7

This may be a duplicate of the following: Multiple form submit, but I am unable to figure out how the answer applies to my situation. So here is my go at asking this (I admit) quite similar question:

I have a table with a row of data, each row has a submit button. It may look something like this:

$form['f'] = array();
foreach ($rows as $row) {
  $form['f'][$row['nid']] = array();
  $form['f'][$row['nid']]['nid'] = array(
    '#markup' => $row['nid'],
  );
  $form['f'][$row['nid']]['submit'] = array(
    '#type' => 'submit',
    '#value' => t('sumbit'),
    '#submit' =>  array('f_submit'),
  );
}

I.e. the form consists of a sequence of rows, extracted from the database, I want to create a submit callback that picks up the value of the corresponding nid field and prints out its value. I guess I am asking what to put where the comment below is.

function f_submit($form, &$form_state) {
  // Here I want to print the value of the relevant nid field
}
6

Data about clicked button is stored in $form_state['triggering_element']. You can get the node ID by looking at $form_state['triggering_element']['#parents']. In your case the node ID would be the second item in the parents array. Please note that the name attribute of the field definition needs to be defined and unique. Otherwise the triggering element will point to the last submit button on the form. I would alter your code as follows:

$form['f'] = array();
foreach ($rows as $row) {
  $form['f'][$row['nid']] = array();
  $form['f'][$row['nid']]['nid'] = array(
    '#markup' => $row['nid'],
  );
  $form['f'][$row['nid']]['submit'] = array(
    '#type' => 'submit',
    '#value' => t('sumbit'),
    '#name' => 'submit-' . $row['nid'],
    '#submit' =>  array('f_submit'),
  );
}

Good way to view $form_state is to install the Devel module (for krumo()) and then putting krumo($form_state);drupal_exit(); to top of the submit handler. This will print out a nice structured tree of data.

  • 1
    Good call on using Devel, but $form_state['clicked_button'] always contains the last nid as the 2nd parent element, not the one related to the clicked button (I've just tried it). Same thing with $form_state['triggering_element'], which I think is preferred in Drupal 7 (but can't find a reference to back that up right now) – Clive Apr 6 '13 at 16:46
  • 2
    Forgot to say that #name needs to be defined and unique on the submit button. Otherwise it will behave like you describe. You're right about using triggering_element, clicked_button is deprecated. Info about that at api.drupal.org/api/drupal/includes%21form.inc/function/…. I updated the answer. – Lauri Apr 6 '13 at 16:58
1

Set the #name property of each submit element to a unique value like your $row['nid']. This unique value can be accessed from the submit function through $form_state['clicked_button']['#name'].

0

I was struggling with this for a while and came up with this workaround. I wanted to have two separate submit buttons with slightly different behavior. I also wanted to add and remove them with jQuery.

So, I did this.

Create two buttons with unique names.

    $form['edit-submit'] = array(
        '#type' => 'submit',
        '#value' => t('Reclassify Selected'),
        '#name' => 'default-submit'
    );

    $form['classify-submit'] = array(
        '#type' => 'submit',
        '#value' => t('Re-classify'),
        '#name' => 'classify-submit'
    );

Hide the button that I want to use dynamically.

    $(document).ready(function() {
        // Hide the classify button
        $('#edit-classify-submit').css('display', 'none');
    });

Clone that button as needed into other places in the form and page.

    $('#edit-classify-submit').clone().appendTo('.my-form').css('display', 'inline-block')

It seems that if you don't add the button definition in through the drupal form declaration it won't be in $form['triggering_element'].

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.