Zend setElementsBelongTo() effect on subform elements
Asked Answered
G

1

10

I have a subform($fileUploadSubform) within a subform ($requestSubform). I called setElementsBelongTo("requestRow[$rowNumber]") on the parent subform ($requestSubform).

    $requestSubform= new Zend_Form_Subform();
    $requestSubform->setElementsBelongTo("requestRow[$rowNumber]");

    // add elements to $requestSubform

    // now create the file upload subform
    $fileUploadSubform= new Zend_Form_SubForm();
    $fileUploadSubform->addElement('file', 'fileName')
            ->setLabel('File'); 

    $fileUploadSubform->addElement('text', 'fileDesc')
            ->setLabel('File Description'); 

    $requestSubform->addSubForm($fileUploadSubform, 'fileUpload');

    $this->view->field = $requestSubform->__toString();

    // pass it as json via ajax back to javascript

When the form is rendered, $fileUploadSubform fileDesc element' name and id are as follows

name="requestRow[1][requestRow][1][fileUpload][fileDesc]"
id="requestRow-1-fileUpload-fileDesc"

Why is the value I've set in the setElementsBelongTo() function is repeated twice?

Thank you in advance!

[Update 08/13/2015]

As a temporary workaround, I just called setElementsBelongTo() from the child subform ($fileUploadSubform) instead of the parent subform ($requestSubform)

[Update 08/17/2015]

I have tried the following code I got from http://zend-framework-community.634137.n4.nabble.com/Improved-array-support-for-Zend-Form-td667215.html as it says in that post that subform elementsTobelong to is working properly.

    $form = new Zend_Form();
    $form->setElementsBelongTo('foobar');

    $form->addElement('text', 'firstName')
    ->getElement('firstName')
    ->setLabel('First Name')
    ->setRequired(true);

    $form->addElement('text', 'lastName')
    ->getElement('lastName')
    ->setLabel('Last Name')
    ->setRequired(true);

    $subForm = new Zend_Form_SubForm();
    $subForm->setElementsBelongTo('foobar[baz]');
    $subForm->addElement('text', 'email')
    ->getElement('email')
    ->setLabel('Email Address');

    $subSubForm = new Zend_Form_SubForm();
    $subSubForm->setElementsBelongTo('foobar[baz][bat]');
    $subSubForm->addElement('checkbox', 'home')
    ->getElement('home')
    ->setLabel('Home address?');
    $subForm->addSubForm($subSubForm, 'subSub');

    $form->addSubForm($subForm, 'sub')
    ->addElement('submit', 'save', array('value' => 'submit'));
    print_r($form->__toString());

But here's what I'm getting for the $subForm's and $subFubForm's elements.

<input id="foobar-foobar-baz-email" type="text" value="" name="foobar[foobar][foobar][baz][email]">

<input id="foobar-foobar-baz-foobar-baz-bat-home" type="checkbox" value="1" name="foobar[foobar][foobar][baz][foobar][foobar][baz][foobar][baz][bat][home]">

[Update 08/24/2015]

I finally figured out the problem.

It was this line

$this->view->field = $additionalInfoSubform->__toString();

There were some elements not showing before that's why I added that line. And only now I understand that those elements that were not showing up are those without ViewHelper decorator set. So, when I set the ViewHelper as the decorator and remove the above fields and called setElementsBelongTo() of the subform without having to from the root of the hierarchy just from that subform, then it worked.

Ginkgo answered 12/8, 2015 at 5:46 Comment(8)
So, what is the question? Did you solved or no? What is he desire output?Cretonne
Instead of "requestRow[1][requestRow][1][fileUpload][fileDesc]" as name of the element, it should be "requestRow[1][fileUpload][fileDesc]".Ginkgo
I'm not able to reproduce this. What is the exact version of ZF that you are using? If it's later than 1.12.9, can you provide the full code, including the main (parent) form?Incult
hi @darkangel, I know now the problem for the sample code i posted above. The problem will only occur when this line is added. $this->view->field = $requestSubform->__toString();Ginkgo
I still can't reproduce the issue with ZF 1.12.9. I get requestRow[1][fileUpload][fileDesc]. Also it's probably cleaner to use $requestSubform->render() instead of directly invoking __toString().Incult
thanks darkangel! Didn't know I can use render() to get the html code of the form. Still so much to learn about Zend. I think the reason I got duplicates in element's name in my 1st code is because I was calling __toString() 2x. 1st is with this line $this->view->field = $requestSubform->__toString(); 2nd is when I am passing the html code of the form to javascript using JSON and Ajax.Ginkgo
With regards to the 2nd set of code I copied from zend-framework-community, it's really not working. I am really getting duplicates in the names. But when I followed what @spenibus answer to this post, I am getting the correct names. I don't know why the person who posted it said it's working.Ginkgo
That code works for me as well.Incult
S
4

I'm unfamiliar with the but from the looks of it, the form hierarchy is implicit. By which I mean you don't have to declare the full "path" when using setElementsBelongTo(). Think of it like a folder structure, you would only name the subfolder within the current working directory.

So when you declare:

$form = new Zend_Form();
$form->setElementsBelongTo('foo');

$subForm = new Zend_Form_SubForm();
$subForm->setElementsBelongTo('bar');
$subForm->addElement('text', 'email')

$form->addSubForm($subForm, 'sub');

This is interpreted as putting email into bar and bar into foo, aka:

name="foo[bar][email]"

The documentation says:

setElementsBelongTo (line 1367)
Set name of array elements belong to
access: public
Zend_Form setElementsBelongTo (string $array)
string $array

From http://framework.zend.com/apidoc/1.9/Zend_Form/Zend_Form.html#setElementsBelongTo

Also:

Zend_Form::setElementsBelongTo($array)
Using this method, you can specify the name of an array to which all elements of the form belong. You can determine the name using the getElementsBelongTo() accessor.

From http://framework.zend.com/manual/1.12/en/zend.form.advanced.html

The wording might be a little unclear but it might support my theory. So when using $form->setElementsBelongTo('foo'), anything added to $form will implicitely become an element of foo and therefore foo must be left out of subsequent setElementsBelongTo() calls that deal with sub-elements.

Shool answered 20/8, 2015 at 18:12 Comment(1)
Thank you @spenibus! You are right with your answer. Actually, I have also tried this way of naming the elements but it didn't work because of this $this->view->field = $subform->__toString(); I added it before because there are some elements not showing up without that line. And only now I realize that those elements didn't have their ViewHelper decorator set. So when I added that line, the elements are showing but having problem with their names.Ginkgo

© 2022 - 2024 — McMap. All rights reserved.