简体   繁体   中英

How to send multiple values via checkbox in a dynmaic loop using cakePHP?

first: yes I know these SO questions cakephp-checkbox-multiple-select-just-sends-the-value-of-last-selected-checkbox and multiple-inputs-with-same-name-through-post-in-php . But both threads don't answer the same question I have.

My problem: I'm creating a view for a "route of planets". I now want to create a table where all of the "routeplanets" are listed with a checkbox at the end. Around the table there is a form to (thats my idea) to send an list/array of ids to remove them from the route.

I did several attemps but I don't get the right data in my request.

Base info: The table is build using a foreach -loop

- foreach($routePlanets as $routeplanet)
  - $class = $this->Html->cycle('even', 'odd')

  %tr{:class => "#{$class}"}
    %td.col1
      = [...]
    %td.col2
      = [...]          
    %td.colremove
      = # this is the line where to create the checkbox     

First attempt: Checkbox for every row

%td.remove
  = $this->Form->checkbox('id', array('value' => $routeplanet['RoutePlanet']['id'], 'hiddenField' => false))

As I assumed when writing this, this will always give me the last value. For example this is the generated HTML

// First row
<td class="remove"><input type="checkbox" name="data[Routeplanet][id]"  value="1"/></td>

// Second row
<td class="remove"><input type="checkbox" name="data[Routeplanet][id]"  value="3"/></td>

When I select both rows I get the following request, showing that only the last row is transmitted (or all before the last are overwritten):

var_dump($this->request->data['Routeplanet']);
// shows 
array(1) {
  ["id"]=>
  string(1) "3"
}

When accessing the data i get a "valid" result with the last ID:

$planetIds =  $this->request->data['Routeplanet']['id'];
var_dump($planetIds); 
// shows: string(1) "3"

Second attemp: Then I read in one of the two SO-question (see above) to use name=id[] , so I changed my row to

%td.remove
  = $this->Form->checkbox('id', array('value' => $routeplanet['RoutePlanet']['id'], 'hiddenField' => false))

This results in the following HTML

// First row
<td class="remove"><input type="checkbox" name="data[Routeplanet][id[]]"  value="1"/></td>

// Second row
<td class="remove"><input type="checkbox" name="data[Routeplanet][id[]]"  value="3"/></td>

Selecting both results in

var_dump($this->request->data['Routeplanet']);
// shows 
array(1) {
  ["id["]=>
  string(1) "3"
}

When accessing the data i get a "valid" result with the last ID:

$planetIds =  $this->request->data['Routeplanet']['id[]'];
var_dump($planetIds); 
// shows: NULL

So I tried the second suggestion of the SO-question (see above), using select with multiple => checkbox option:

- $options[] = $routeplanet['RoutePlanet']['id']
= $this->Form->select('id', $options, array('multiple' => 'checkbox', 'hiddenField' => false))

But this results in false HTML

// First row
<td class="remove">
<div class="checkbox"><input type="checkbox" name="data[Routeplanet][id][]" value="0" id="0" /><label for="0">1</label></div>
</td>

// Second row
<td class="remove">
<div class="checkbox"><input type="checkbox" name="data[Routeplanet][id][]" value="0" id="0" /><label for="0">1</label></div>
<div class="checkbox"><input type="checkbox" name="data[Routeplanet][id][]" value="1" id="1" /><label for="1">3</label></div>
</td>

As you can see a) in the second row, the first is also added (because of $options[] ) and b) the values are not the $routeplanet['RoutePlanet']['id'] - they are only used for labels (which I don't want by the way). I could break here as the layout and the HTML is wrong, but let me show you the even false request:

array(1) {
  ["id"]=>
  array(3) {
    [0]=>
    string(1) "0"
    [1]=>
    string(1) "0"
    [2]=>
    string(1) "1"
  }
}

I then thought about doing another loop to fill the options but I already assumed that then all rows will have all options. And I was right:

- foreach($routePlanets as $routeplanet)
  - $options[] = $routeplanet['RoutePlanet']['id']

- foreach($routePlanets as $routeplanet)
  %td.remove
    = $this->Form->select('id', $options, array('multiple' => 'checkbox', 'hiddenField' => false))

results in the following HTML for each row:

<td class="remove">
<div class="checkbox"><input type="checkbox" name="data[Routeplanet][id][]" value="0" id="0" /><label for="0">1</label></div>
<div class="checkbox"><input type="checkbox" name="data[Routeplanet][id][]" value="1" id="1" /><label for="1">3</label></div>
</td>    

So my question now is: How can I build a valid form, that gives me the option to mark a checkbox in each row, resulting that each marked row is in the sent request I acces in my controller?

Thanks in advance

The link provided by ndm was very helpfull - thank you! My mistake was that I only checked "checkbox" and "select" (with multiple-option) in the documentation but totally forget about the "normal" input.

This is how I did it in the end:

Form:

- # MyModel as Helpername for easier access to the array
- $fieldname = 'MyModel.' . $i . '.id'
= $this->Form->input($fieldname, array('value' => $routeplanet['RoutePlanet']['id'], 'type' => 'checkbox', 'label' => false, 'hiddenField' => false))

Controller:

$MyModelArray = $this->request->data['MyModel'];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM