ZF2 - Checkboxes in table rows

2.3k views Asked by At

I've got a table of messages/emails and want to have a checkbox to select multiple messages and delete them using the button at the bottom of the table:

Typical table

Dead simple with standard PHP/HTML without the use of a framework you can:

<input type="checkbox" name="ids[]" value="510">
<input type="checkbox" name="ids[]" value="1231">

Then in PHP loop through the array of IDs that have been selected. I'm trying to achieve the same thing with ZF2.

ZF2 provides:

FormCollection - is a collection of Fieldsets, which I think is wrong for storing an array of IDs passed.
MultiCheckbox - with the current set of ViewHelpers cannot be extracted using an interator
Checkbox - involves dynamically adding inputs with the ID of the name, but can't be looped through and validated so easily.

If FormCollection supported inserting elements, I would say that is the best option as you could dynamically add them and loop through them when POSTed. I imagine in the near future FormCollection will allow adding elements, replacing the need for MultiCheckbox and MultiRadio as you could iterate through a FormCollection and extract the individual parts

Has anyone else done something like this, how did you go about it?

As I always say: Frameworks make the hard things easy, and the easy things hard.

2

There are 2 answers

0
Andrew On

You can add new items quite easily:

http://framework.zend.com/manual/2.2/en/modules/zend.form.collections.html#adding-new-elements-dynamically

There's an example using a little simple Javascript to add new rows/items.

0
Curtis Kelsey On

Have you tried generating the form in the controller? For example:

public function emailAction(){
    $emailList = $this->getEmailTable()->getEmails();

    $emailForm = new \Zend\Form\Form();
    $emailForm->setName('email_form');

    foreach($emailList as $email){
        $element = new \Zend\Form\Element\Checkbox($email->id);
        $emailForm->add($element);
    }

    return new ViewModel(array('form'=>$emailForm,'list'=>$emailList));
}

Then in the view iterate over the list to produce the table and encapsulate the table with the form. Don't forget to create a delete selected submit button.

<?php
    $form = $this->form;
    $form->setAttribute('action', $this->url('deleteEmail');
    $form->prepare();

    echo $this->form()->openTag($form);
?>
<table>
    <?php foreach($this->list as $item): ?>
        <tr>
            <td><?php echo $this->formElement($form->get($item->id));?></td>
            <td><?php echo $item->subject;?></td>
            <td><?php echo $item->receipt_date;?></td>
        </tr>
    <?php endforeach; ?>
</table>
<?php
    echo $this->formRow($form->get('submit'));
    echo $this->form()->closeTag();
?>

Now when the form is submitted to the deleteEmail action you may iterate over the form elements, check if they are selected and then delete them.

public function deleteEmailAction(){
    $post = $request->getPost()->toArray();

    foreach($post as $key=>$value){
        if($value){
            $this->getEmailTable()->deleteEmail($key);
        }
    }
}

This is to be considered psudocode and may take some tweaking to get working, but hopefully it gives you an idea on how you can model your problem. May not be the easiest.