Nested forms give unexpected results

I have a database table that I baked the standard CRUD skeleton. The index view creates an html table with paginated listing of the records where the last column are View/Edit/Delete actions using postLinks.

I want add a checkbox to each html table row so that I can select multiple rows and submit for processing similar to this pseudo code:

$this->Form->create($items,['url' => ['action' => 'process']])
  foreach $items as $item
        <td> $this->Form->checkbox('itemid[]', ['hiddenField' => false, 'value' => $item->item_id ],);</td>
       <td> multiple item fields displayed</td>
       <td class="actions">
               $this->Html->link(__('Edit'), ['action' => 'edit', $item->id]) ?><br>
                $this->Form->postLink(__('Delete'), ['action' => 'delete', $item->id], ['confirm' => __('Delete {0}?', $item->item_id)]) 
      end foreach;

When I use this approach, the postLinks behave unpredictably. When I click “Delete” postLink for the first item in the table, nothing happens and the item doesn’t get deleted from the list. The javascript console has this error:

items:78 Uncaught TypeError: Cannot read properties of undefined (reading ‘submit’)
at HTMLAnchorElement.onclick (items:78:731)
onclick @ items:78

I gather that nesting forms is the issue, but I’ve seen sites that have this feature the UI so I’m asking for best practice for this feature.


If the code you posted is what you’re using it looks like you have php code in the html document, it should have the php directives around it <?php & ?>

But how that could possibly lead to javascript errors is anyone’s guess!

Edit: my attempt at putting the tags in - syntax not tested / could be wrong!

<?= $this->Form->create($items,['url' => ['action' => 'process']]) ?>
  <?php foreach ($items as $item) : ?>
       <td> <?= $this->Form->checkbox('itemid[]', ['hiddenField' => false, 'value' => $item->item_id ],) ?></td>
       <td> multiple item fields displayed</td>
       <td class="actions">
           <?= $this->Html->link(__('Edit'), ['action' => 'edit', $item->id]) ?><br>
           <?= $this->Form->postLink(__('Delete'), ['action' => 'delete', $item->id], ['confirm' => __('Delete {0}?', $item->item_id)]) ?>
   <?php endforeach; ?>
 <?= $this->Form->end() ?>

Note that was a stack of editing, fixing reserved words, putting in language punctuation like brackets, etc!
The code itself may need cleaning, like why the hiddenfield property? I didn’t examine it further, this is just the starting place.

Thanks for the reply, Jawfin.

I was listing pseudo code for brevity. My production code is properly formatted html and in-line php statements with appropriate delimiters.

I don’t have any php warning or errors. Only javascript console errors in the browser (tested on chrome, firefox and safari).

Ah makes sense!

CakePHP doesn’t generate any JavaScript (AFAIK) so any scripting errors have come from somewhere else. Unless you’re just referring to the developer’s console only. That Submit would most likely tie back to a POST command, maybe it needs a Submit button? Or is that form feeding into JS like an AJAX?

It seems though I’m not understanding the issue, so we’ll just wait for an expert to answer here!

Forms cannot be nested, that’s simply invalid in HTML, and will result in unpredictable rendering (most browsers drop the nested form and render its contents outside of the parent).

Assign the POST link forms to a block instead, and render it outside of the main form.

<?= $this->Form->postLink(
    ['action' => 'delete', $item->id],
        'confirm' => __('Delete {0}?', $item->item_id),
        'block' => 'postLinkForms',  // <<  there
)  ?>
<?= $this->Form->end() ?>
// ...
<?= $this->fetch('postLinkForms') ?>

See also the note in the Cookbook: Form - 4.x

This works as desired. Thanks ndm!