Drupal.behaviors + jQuery: multiple buttons with the same name

published on August 23, 2008

While working for Mollom, I faced the problem of needing multiple buttons with the same name. In my case, this was an absolute necessity on an advanced multi-step form. Sounds super … easy, right? But HTML doesn’t support this!

Thankfully, the combination of Drupal.behaviors and jQuery makes it easy to create a work-around! jQuery makes it easy to write the necessary code, Drupal.behaviors makes it trivial to ensure it keeps working even when new content has been added to the page (i.e. after an AHAH callback).

You would have a piece of Forms API code like this:

$form['step1']['edit'] = array(
  '#type'       => 'submit',
  '#value'      => t('Edit step 1'),
  '#submit'     => array('subscriptions_create_edit_step1'),
  '#attributes' => array('class' => 'edit-step-button'),
);

// … more form definition code

$form['step4']['edit'] = array(
  '#type'       => 'submit',
  '#value'      => t('Edit step 4'),
  '#submit'     => array('subscriptions_create_edit_step4'),
  '#attributes' => array('class' => 'edit-step-button'),
);

As you can see, nothing remarkable about this, except for one thing: we’ve set the class attribute. This is used in our Drupal.behaviors method to detect which buttons this behavior should be applied to.

Next, add this piece of JavaScript code to your module’s .js file:

Drupal.behaviors.subscriptionsCreateFormEditStepButton = function() {
  $('.edit-step-button:not(.edit-step-button-processed)')
  .addClass('edit-step-button-processed').each(function () {
    var actualButtonName = $(this).val();
    $(this).val(Drupal.t('Edit'));
    $(this).click(function() {
      $(this).val(actualButtonName);
    });
  });
};

This is a trivial piece of code: it overwrites the value attribute but restores it as soon as the button is pressed. But I think — or hope at least — that this will save 5 minutes of some people’s time :)