In short, I am trying to figure out how to add a custom and unique identifier to each submission from the Webform module.

Example: User fills out the Webform and submits. User then receives an email (email is captured from email field in Webform) confirming their submission and providing them with a Unique Identifier (ABC-14-001).

I know Webform asks what number to start the next submission (and I'm assuming this is considered the "SID"). If I am to utilize the SID, I need to be able to append the custom "ABC-14" prefix to each submission's SID.

I'm not very familiar with hooks (sorry for the ignorance), but I understand that hooks might be the only way, or at least most effective way, to accomplish this?

Update Thanks all who responded! I have a working solution right now with this module:

function identifier_webform_submission_presave($node, &$submission) { $component_id = 23; //that's your hidden field $submission->data[$component_id][0] = 'Text to be inserted'; }

  • Do you need that number stored anyway? Or simply putting it in email is enough? I mean, simplistic thing to get what you write would be to write "ABC-14[token-for-sid]" in e-mail template, but somehow I don't feel that it is what you want.
    – Mołot
    Nov 25, 2014 at 19:07
  • "I know Webform asks what number to start the next submission (and I'm assuming this is considered the "SID")". Don't believe you are right on this. The SID is unique, but there is now also a 'serial' column in the db which holds the 'sequence' for that specific node Nov 26, 2014 at 1:12

2 Answers 2


You want to use hook_webform_submission_presave to record your special key. I would create a hidden textfield in the Webform that is optional so the value can be set by your PHP code upon submission.

For a basically full working example see Webform Issue #1964080.

To create your special value such as AB-001-12345 you just make a php function that creates a random string, or a string to your specifications:

function generate_special_submission_key() {
  $length = 10;
  $str = substr(str_shuffle("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"), 0, $length);
  return $str;

Correct. You would have to write a hook_form_alter() on that web form to populate a hidden field with the tracking information you want to add.

Here is an example of a form alter I did on a webform to populate data in a hidden field based on a query string from the URL

 * Implement hook_form_alter().
function ss_customization_module_form_alter(&$form, $form_state, $form_id) {
  if ($form_id == 'webform_client_form_103') {
    $nid = 0;
    if (isset($_GET['cp']) && !empty($_GET['cp'])) {
      $ss_custom_cp_id = check_plain($_GET['cp']);
      $results = db_query('SELECT node.nid AS nid, \'node\' AS field_data_field_email_node_entity_type, \'node\' AS field_data_field_content_certpro_ltext_biog_node_entity_type
      {node} node
      LEFT JOIN {field_data_field_int_sort} field_data_field_int_sort ON node.nid = field_data_field_int_sort.entity_id AND (field_data_field_int_sort.entity_type = \'node\' AND field_data_field_int_sort.deleted = \'0\')
      WHERE (( (node.status = \'1\') AND (node.type IN  (\'certified_professional\')) AND (field_data_field_int_sort.field_int_sort_value = :ssid) ))
      LIMIT 1 OFFSET 0', array(':ssid' => $ss_custom_cp_id));
      while ($row = $results->fetchAll(PDO::FETCH_ASSOC)) {
        $nid = $row[0]['nid'];
      if ($ss_custom_cp_node = node_load($nid)) {
        //kpr($ss_custom_cp_node); //Use this if you need to see what is in the CP node for data
        $email = check_plain($ss_custom_cp_node->field_email[$ss_custom_cp_node->language]['0']['email']);
        $tphone = check_plain($ss_custom_cp_node->field_content_certpro_tphone[$ss_custom_cp_node->language]['0']['safe_value']);
        $full_name = check_plain($ss_custom_cp_node->title);
        $form['submitted']['cp_email_addr']['#default_value'] = $email;
        $form['submitted']['cp_full_name']['#default_value'] = $full_name;
        $form['submitted']['cp_telephone']['#default_value'] = $tphone;

What happens here is I take data from the query string of the URL (?cp=XXX) and pull data out of the database based on that number and add it to hidden fields ('cp_email_addr', 'cp_full_name', 'cp_telephone' are all hidden fields in the form that the user does not see). When submitted all of this data is then available via the Webform tools.

You could also do this based on the path that you are loading for the webform, it does not have to be a query string. You could use the $arg array to compare the path and make your own custom submission ID's based off of that path. You could then flow that data into a hidden field on the form.

Very important. Note how I clean the input from the query string using check_plain. This prevents XSS attacks because I know this data should be just text with no markup contained in it. I also use check_plain again to clean input going into the form.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.