CakePHP 2.0 Determine which submit button has been clicked

16,182

Solution 1

Generally it is a bad practise to use the same name for both submit buttons. There should be a "submit" key in the $_POST and $this->request->data

I tested this in CakePHP 2.1.1 as shown below:

The view code:

<?php echo $this->Form->create('Message', array('action'=>'test')); 
//  Extra test input field
echo $this->Form->input('test');
?>

<div class='submit'>
<?php 
echo $this->Form->submit('Yes', array('div'=>false, 'name'=>'submit')); 
echo $this->Form->submit('No', array('div'=>false, 'name'=>'submit')); 
?>
</div>
<?php echo $this->Form->end()?>

The in the controller in $this->request->data:

array(
    'submit' => 'Yes',
    'Message' => array(
        'test' => 'TestFieldTest'
    )
)

And in $_POST:

array(
    '_method' => 'POST',
    'data' => array(
        'Message' => array(
            'test' => 'TestFieldTest'
        )
    ),
    'submit' => 'Yes'
)

You can also give the two submits different names:

echo $this->Form->submit('Yes', array('div'=>false, 'name'=>'submitY')); 
echo $this->Form->submit('No', array('div'=>false, 'name'=>'submitN')); 

This way you can differ them in the $_POST or $this->request->data, because the keys will be the submits' names:

array(
    'submitY' => 'Yes',
    'Message' => array(
        'test' => 'foo'
    )
)

array(
    '_method' => 'POST',
    'data' => array(
        'Message' => array(
            'test' => 'Bar'
        )
    ),
    'submitY' => 'Yes'
)

Then to determine which button is pressed you can use a simple isset($_POST['']) or over $this->request->data ?

Solution 2

Don't use the same name for both submit buttons. Consider this example:

<?php echo $this->Form->create(false); ?>
<?php echo $this->Form->text('input'); ?>
<?php echo $this->Form->submit('Yes', array('name' => 'submit1')); ?>
<?php echo $this->Form->submit('No', array('name' => 'submit2')); ?>
<?php echo $this->Form->end(); ?>

debug($this->request->data) will produce the following when the "Yes" button is clicked:

array(
    'submit1' => 'Yes',
    'input' => 'test'
)

And here it is when the "No" button is clicked:

array(
    'submit2' => 'No',
    'input' => 'test'
)

To check which button was clicked:

if (isset($this->request->data['submit1'])) {
    // yes button was clicked
} else if (isset($this->request->data['submit2'])) {
    // no button was clicked
}

Solution 3

in 2.0 there is no $this->params['form'] anymore all form helper posted fields end up in $this->data (which makes more sense anyway)

so

if (!empty($this->data['submit']) && $this->data['submit'] == "Submit 1") {}

note that !empty() is better here as well.

PS: you can use my enhanced upgrade shell to replace it in your code: https://github.com/dereuromark/upgrade

its the command

cake Upgrade.Upgrade request

(https://github.com/dereuromark/upgrade/blob/master/Console/Command/UpgradeShell.php#L833)

Share:
16,182
RichardAtHome
Author by

RichardAtHome

A seasoned developer working mainly in PHP, CakePHP, MySQL, HTML, CSS, jQuery and occasionally forced into the murky depths of ASP.Net

Updated on June 21, 2022

Comments

  • RichardAtHome
    RichardAtHome almost 2 years

    In CakePHP 1.3 you can create a form with multiple submit buttons:

    echo $this->Form->submit('Submit 1', array('name'=>'submit');
    echo $this->Form->submit('Submit 2', array('name'=>'submit');
    

    and detect which submit button was pressed in the controller with:

    if (isset($this->params['form']['submit']) && $this->params['form']['submit'] == "Submit 1") {
      // first button clicked
    }
    

    In CakePHP, $this->params['form'] isn't set and the clicked button value doesn't appear anywhere in $this->request, $this->request->data, $this->params, $this->data or $_POST.

    How do I determine which button has been clicked in CakePHP 2.0?

    Thanks in advance.

    Edit:

    As requested, here's the code for the form:

    <?php echo $this->Form->create('History', array('action'=>'add')); ?>
    <div class='submit'>
    <?php 
    echo $this->Form->submit('Yes', array('div'=>false, 'name'=>'submit')); 
    echo $this->Form->submit('No', array('div'=>false, 'name'=>'submit')); 
    ?>
    </div>
    <?php echo $this->Form->end()?>
    

    And the output of the form:

    <form action="/projects/kings_recruit/trunk/www/histories/add" id="HistoryAddForm" method="post" accept-charset="utf-8">
      <div style="display:none;">
        <input name="_method" value="POST" type="hidden">
      </div>
      <div class="submit">
        <input name="submit" value="Yes" type="submit">
        <input name="submit" value="No" type="submit">
      </div>
    </form>
    
  • RichardAtHome
    RichardAtHome about 12 years
    I don't see "Submit 1" in $this->data either :-( Also, I'm not upgrading a 1.3 project, this is a brand new 2.0 project.
  • RichardAtHome
    RichardAtHome about 12 years
    Also not seeing it in $_POST either. Have updated my question to reflect this
  • RichardAtHome
    RichardAtHome about 12 years
    As I mentioned in a previous answer (and updated the question to reflect this), I don't see 'submit' in $this->data
  • thecodeparadox
    thecodeparadox about 12 years
    @RichardAtHome Not $this->data, it is $this->request->data. please recheck you code with $this->request->data
  • RichardAtHome
    RichardAtHome about 12 years
    Also don't see it in $this->request->data (sorry I thought that was implied with my point about not seeing it $this->request)
  • RichardAtHome
    RichardAtHome almost 12 years
    Not seeing this in my form post array - even with a brand new project :-S I'll explore a bit more later and get back to you...
  • Borislav Sabev
    Borislav Sabev almost 12 years
    Are you using any custom filtering over the POST - like Codeigniter XSS or? This is very strange. A trivial question would be: Are you in the right action? Is the form pointing to the right action? Try it with different names for the submits. Could you also provide the contents of the POST?