Zend_Form array notation with no indices
Asked Answered
S

3

6

I would like to create a form that allows the user to input any number of values, each in a separate text field using an array notation. The example expected HTML output is:

<dd id="dupa-element">
    <input type="text" name="dupa[]" value="">
    <input type="text" name="dupa[]" value="">
</dd>

However, I can't seem to find a way to introduce multiple input elements within a single element, using array notation without indices.

Currently, I do this:

$elt1 = new Zend_Form_Element_Text('1');
$elt1->setOptions(array('belongsTo' => 'dupa'));

$elt2 = new Zend_Form_Element_Textarea('2');
$elt2->setOptions(array('belongsTo' => 'dupa'));

While this works, Zend_Form treats these as independent elements (which can have different sets of validators and filters - that's sort of cool) and the resulting HTML is something along these lines:

<dd id="dupa-1-element">
    <input type="text" name="dupa[1]" id="dupa-1" value="">
</dd>
<dd id="dupa-2-element">
    <input type="text" name="dupa[2]" id="dupa-2" value="">
</dd>

Is there a (preferably simple) way to achieve the indexless array notation I'm after?

Sterling answered 18/5, 2011 at 8:57 Comment(4)
See #5632796Byline
@David, how does this relate to my question?Sterling
I guess I interpreted your phrasing "allows the user to input any number of values" to mean that the number of such elements would be unknown when the form is delivered. The post to which I linked outlines a way to allow the user to dynamically add these form elements on the client side and the server-side Zend_Form instance can be "magically" modified reflect the client-side reality. If your situation doesn't have that kind of indeterminacy, then I'll just delete my comment. Sorry for the misread.Byline
Oh, no, that's fine, you don't have to delete it. I guess I could've phrased that more explicitly. I have a tiny jQuery script that adds or removes the elements on the client side, and the server side has no validation on them, so any input is OK as long as all of it is sent as an array. The problem is that when I extract the array from the database, I really should populate the form server-side, not client side - and Zend appears to have trouble handling those natively :).Sterling
O
3

I would follow MWOP's tutorial on creating composite elements. More work, but it's less Trial&Error then akond's solution. Basic idea for me would be extending the Zend_Form_Element_Multi (what you want is how Zend_Form_Element_Multiselect/MultiCheckbox works).

Omaomaha answered 18/5, 2011 at 11:9 Comment(5)
Ah, sorry :) I accidentaly overwrote it.Colbert
Not exactly what I was looking for, but given that there's probably no solution that does exactly what I'd like to achieve, your suggestion comes close enough :). Thanks.Sterling
are you fine with the outpu of Zend_Form_Element_MultiCheckbox? If you are mimic the way it's created. I believe it creates elements that have names element-name[]...Colbert
I toyed with the idea to create a custom text element instead of the multicheckbox. My final pick was more mundane though: setIsArray() on a regulat text element + jQuery to add more :D.Sterling
@Tomáš: OK, I ended up changing my approach due to problems with validation & form repopulation (too much dependency on Javascript was an issue as well) and revisited the link you suggested. Based on it, I created a custom element that does exactly what I need :). Thanks, mate :)Sterling
G
2

I managed to do this by having a "container subform", and then adding subforms to that "container" e.g.:

$container = new Zend_Form_SubForm();
$subform1 = new Zend_Form_SubForm();
$container->addSubForm($subform1, '1');

$subform2 = new Zend_Form_SubForm();
$subform2->addSubForm($subform1, '2');

$mainForm = new Zend_Form();
$mainForm->addSubform($container,'mysubforms');

Hope that helps.

Geezer answered 17/11, 2011 at 18:42 Comment(0)
M
1

You need a custom view helper for that.

class Zend_View_Helper_FormMySelect extends Zend_View_Helper_Abstract
{
    function formMySelect ($name, $value = null, $attribs = null, $options = null, $listsep = "<br />\n")
    {
        $result = array ();
        foreach ($options as $option)
        {
            $result [] = sprintf ('<input type="text" name="%s[]" value="">', $name);
        }

        return join ($listsep, $result);
    }
}

Than have in your form something like that:

    $form = new Zend_Form();
    $form->addElement ('select', 'test', array (
    'label'     => 'Test',
    'multioptions' => array (
        'test 1',
        'test 2',
        'test 3',
    ),
    ));

    $form->test->helper = 'formMySelect';
Monogram answered 18/5, 2011 at 9:50 Comment(6)
Interesting. I'll experiment with this.Sterling
Will validating and populating of select element with such view helper work?Unfasten
Not sure. I've just given an idea.Monogram
@Marcin: it doesn't seem to, unfortunately :(. While I don't really need any validation in my particular case, it would be desireable not to forfeit it.Sterling
@mingos. that's what I suspected. Normally you cannot do such array elements in ZF. I think you would have to create your own element like this. I also think that @Tomáš Fejfar idea is a way to go.Unfasten
@Marcin: Too bad. This is what I expected, to be honest, especially since the setBelongsTo() and setIsArray() functions don't seem to do what I would like to achieve, but still I was hoping I'd somehow be wrong :D.Sterling

© 2022 - 2024 — McMap. All rights reserved.