ZF-6174: Zend_Form elements: must be able to allow disabling id attribute

Description

Zend_Form elements should be able to allowed to disable the rendering of the id attribute. It seems that, when id is explicitly set to null, the id attribute is automatically assigned the name of the element. Right now I'm working on a CMS that has multiple identical forms which should allow the same (hidden) form elements. Consider the following example:

Page 1
Page 2

Now, if the hidden elements (or the submit elements for that matter) are automatically assigned an id attribute value (left out in this example) equivalent to the name attribute value, this results in non valid W3C (x)html code, because of repetitive equivalent id's.

I strongly believe developers should be able to decide for themselfs whether they want the id attribute automatically rendered if no value is given (or rendered at all for that matter). Perhaps with some method like

Zend_Form [ _Element ]::autoAssignIdAttrib( /* true | false */ ); // be it a static global method or an instance method

I think you should not let developers resort to creating unique id's with a mandatory routine. Especially if the developer feels assigning id's to the elements is unnessecary anyway, when s/he has no use for it, because they are not gonna manipulate the elements with some type of clientside scripting.

Comments

As noted on list, I'm closing this issue as "Won't Fix," for two reasons.

First, the design of the form view helpers since the very beginning has been to always create IDs. This is to make it trivial to get to the discrete elements using JavaScript, as well as to make testing easy (easier to select DOM elements by ID than other methods, though Zend_Dom_Query now makes it less of an issue).

Second, if you're having ID collisions, there is another mechanism you can use that's built into Zend_Form: array notation. Call the setElementsBelongTo() method of your form (or pass the 'elementsBelongTo' configuration key) and provide a unique namespace for your form. All elements within will then be prefixed by "-".

Refactoring to allow optional display of IDs at this point only serves an edge case for something that can be easily avoided with proper configuration.

I would like to ask for this bug to be re-opened, as there is not only a problem with invalid XHTML code (because of duplicated IDs), but also with Explorer bugs:

http://msdn.microsoft.com/en-us/library/ms536438(VS.85).aspx

http://msdn.microsoft.com/en-us/library/…

As you can see, both getElementByID() and getElementByName(), in IE search for both ID and NAME. This could lead to hardly traceable bugs in Javascript.

Moreover, it is not always possible to use Zend_Form, and this problem is related to View Helpers, and not Zend_Form.

As for the duplicated IDs, there could be parts of the page rendered by different actions. I had a problem with two partial views rendering a search form, linking to the same actioncontroller. Think of a "search" box in the header and another search field in the search results. I had to adapt the searchAction to accept both field names.

I think the id generation should be made optional, at least in ZF 2.0 (so to not break compatibility in ZF 1.x)

That bug is only of outdated versions of IE

" Internet Explorer 8 and later. In IE8 mode, getElementById performs a case-sensitive match on the ID attribute only. In IE7 mode and previous modes, this method performs a case-insensitive match on both the ID and NAME attributes, which might produce unexpected results. For more information, see Defining Document Compatibility."

It's like proposing a fix for use with the Mosaic browser....

Mosaic has 0% of the installed share. IE6 + IE7 still has nearly 70% of it. IE8 is stable since a week or so.

That said, it is still wrong to assign the same value for name and id, as they are two separate values. One must be unique, the other not. This should suffice to make a fix.

What should suffice? How do you propose making a different name and id?

Additionally, using modern JS toolkits, this is not an issue -- they have mechanisms for finding the appropriate DOM elements based on ID that work around any such issues as you report (I know, because I use them).

Please also note the reasons why I closed this earlier. Changing this behavior is (1) a major BC break, and (2) a large scale refactoring effort. I do not see how we can do this anytime before 2.0 -- and I'm not entirely convinced it's necessary.

I think the major BC break could be avoided if you implemented a method like I proposed (but for the viewhlepers instead of form or form elements) with a default value of true.

So something like:

protected Zend_View_Helper_FormElement::$_autoAssignIdAttribute = true;

Zend_View_Helper_FormElement::autoAssignIdAttribute( /* true | false */ );

maybe with some proxy method in Zend_Form too.

I still haven't been able to figure out where this auto id assigning takes place BTW, but I would image it to be something like:

if( !isset( $attribs[ 'id' ] ) || empty( $attribs[ 'id' ] ) ) { $id = $name; }

This could then be replaced with something like:

if( Zend_View_Helper_FormElement::autoAssignIdAttribute() && ( !isset( $attribs[ 'id' ] ) || empty( $attribs[ 'id' ] ) ) ) { $id = $name; }

But maybe my ideas about this are a bit to simple since you say it would require large scale refactoring.

Hi, I have got the same problem with multiple forms in same page (multiple forms are from the same class extending Zend_Form).

I read the comments and I think it is a real issue. Not because web browser compatibility, but developers have to be able to render their forms how they want.

Matthew Weier O'Phinney said there is another way (using array notation and "setElementsBelongTo" method). But I think you must give the possibility to use framework components in a easy way to do simple things. Then you add methods to use more complex functionalities.

So, the actual behavior of Zend_View_Helper_FormElement (which adds the "id" attribute) is made to ??make it trivial to get to the discrete elements using JavaScript??. If I don't want to use IDs but DOM tree to use my JavaScript on similar elements ? IDs become unusual and maybe I don't want to see them in my source. That's what I said: developers want a framework which give the possibility to do what they want.

I specially signed up for this comment because I was quite shaken at this issue. I really appreciate Zend for not forcing me to do things in a predefined way. Therefore I totally agree with Damien Flament and would really beg to fix this (in my eyes) design fault in version 2. Until then I will generate my forms manually.

I would also like to be able to disable form ID elements. This has been a long term issue for me also, I have resorted to loading some forms by ajax so not to dupicate IDs.

@Damien Flament, walther, Jonathan Dunn

With more than 180 errors, there are currently enough work for this component. Can you add some patches and tests? This would help!

Thanks and greetings Kaiuwe

Matthew Weier O'Phinney did good points in his first comment.

Except about "Refactoring to allow optional display of IDs at this point only serves an edge case for something that can be easily avoided with proper configuration."

The use case of multiple use of same the form class in a same page is not rare. And setBelongs/setIsArray+setName is not an option at least in some cases. In my case all those instances will be interpreted by the same code in the controller. The array notation does not fit. SO the "proper configuration" does not stand.

I completely agree with Damien Flament. The actual behavior is good as default as it saves time in most cases, but enforcing it is intrusive and limitating.

Despite i think it is normal not making it to 2.0, this is still an opened issue, that deserves to be fixed the sooner the better, it should be reopened.

Until then i have no workaround, except reimplementing every form view helpers :/ and other dirty patchs.