Issues

ZF-10791: $form->setName('nameAttr'); has no effect

Description

This ticket is related to http://framework.zend.com/issues/browse/ZF-4342 but I did not find a way to reopen. The ticket was closed with the hint that name is not a valid form-element attribute.

I could not find any evidence for this statement.

W3C says for HTML401 and also 5 that name IS a valid attribute for the form-element: HTML 401: http://w3.org/TR/html401/… HTML 5 : http://w3.org/TR/2010/…

Comments

??I could not find any evidence for this statement.??

www.w3.org/TR/xhtml1/#h-4.10" rel="nofollow">XHTML 1.0 - 4.10. The elements with 'id' and 'name' attributes

I think the priority "major" is greatly exaggerated!

Thank you for the link, couldn't find this by myself :( I copied the priority from the source-ticket, so you are right.

I thought HTML5 will be the future, not XHTML, any opinions?

I strongly advise that HTML5 takes priority over XHTML. The simple reason: W3C declared XHTML as dead (http://www.w3.org/2009/06/xhtml-faq.html). So the name atribute should be rendered by the ViewHelper of the form.

It is possible to detect the DTD in use via the doctype view helper. The view helpers are already doing this (i.e. deciding whether to include a closing / in tags), so look there for an example. This should be fixable in a way that maintains compatibility with both HTML4, XHTML and HTML5

100 points for Marc! :-)

Example (not tested!):


/**
 * Render HTML form
 *
 * @param  string $name Form name
 * @param  null|array $attribs HTML form attributes
 * @param  false|string $content Form content
 * @return string
 */
public function form($name, $attribs = null, $content = false)
{
    $info = $this->_getInfo($name, $content, $attribs);
    extract($info);

    // Set the id attribute if it exists
    if (!empty($id)) {
        $id = ' id="' . $this->view->escape($id) . '"';
    } else {
        $id = '';
    }

    // Remove id from attributes
    if (array_key_exists('id', $attribs) && empty($attribs['id'])) {
        unset($attribs['id']);
    }
    
    // Set the name attribute if it exists and the doctype is not XHTML
    if (false === $this->_isXhtml() && !empty($name)) {
        $name = ' name="' . $this->view->escape($name) . '"';
    } else {
        $name = '';
    }
    
    // Remove name from attributes
    if (array_key_exists('name', $attribs) && empty($attribs['name'])) {
        unset($attribs['name']);
    }

    $html = '_htmlAttribs($attribs)
          . '>';

    if (false !== $content) {
        $html .= $content
              .  '';
    }

    return $html;
}

I do not see the point why the attribute "name" should be removed when a xhtml doctype is set.

The W3C states in the XHTML 1.0 Recommendation taht the name attribute is formally deprecated and will be removes. As we all know there will be no future xhtml version and in the current 1.0 version it is allowed. Why then restrict the developer (especially under the fact that the older IE versions do not work properly and need the identical value for the "name"and "id" attribute)?

I agree with Ulf on this one. XHTML 1.0 and 1.1 deprecated the name attribute on form tags but never formally removed it, and it is valid syntax in HTML5, so there is no reason to deny it's use here.

I thought that you could do the following regardless of whether the name attribute is added by the view helper:


// When creating a new form instance
$zf = new Zend_Form(array(
    'attribs' => array(
        'name' => 'NameOfForm'
    )
));

// ...or inside the init() method of your Zend_Form subclass:
$this->setAttrib('name', 'NameOfForm');

However, when I tried it against 1.11.1 it did not have the desired effect. A change to Zend_View_Helper_Form like the one Kai suggested should fix that, though. The other option would be to find out where in the call stack the name attribute is overridden (my money is on Zend_View_Helper_FormElement::_getInfo(..), but I haven't been able to prove that yet).

I've attached a patch which I think sorts out this issue: - single line change to Zend_View_Helper_FormElement::_getInfo(...) (Allows overriding of name attribute on all Form elements) - Added two tests to Zend_View_Helper_FormTest ala the existing tests for the ID attribute

Comments?

Made a few slight changes - Fixed: Providing NULL name attribute should not produce

<

form name=""> - Added: Test to enforce above - Fixed: Nomenclature on tests was clumsy. Changed to follow ID tests more closely.

Reformatted patch to Zend Framework coding guidelines (ie: replaced tabs with spaces)

Excellent point! I failed to read the DTDs close enough, and took the W3C documents at their word that the element was deprecated and not removed. Apologies for that. I will modify my patch annd repost later this morning.

A proposal (not tested!):


// Set the name attribute if it exists and the doctype is not XHTML Strict or XHTML 1.1
$isStrictXhtml = false;
if ($this->_isXhtml() && stristr($this->view->doctype(), 'strict')
    || stristr($this->view->doctype(), 'XHTML 1.1')) {
    $isStrictXhtml = true;
}

if (false === $isStrictXhtml && !empty($name)) {
    $name = ' name="' . $this->view->escape($name) . '"';
} else {
    $name = '';
}

I've updated my patch with the suggested modifications: {quote} - Narrowed scope of fix to only affect the form tag - Will not render name attribute when using XHTML 1.0 strict or XHTML 1.1 - Extended test suite: [x] Passing name as attribute should override form name [x] Not specifying form name should not render name attrib [x] Specifying form name should render name attrib [x] Passing empty name attribute to unnamed form should not render name attrib [x] Passing empty name attribute to named form should not override name attrib [x] Name attribute should be omitted when using xhtml 1 strict [x] Name attribute should be omitted when using xhtml 11 - Removed incorrect test: testPassingIdAsAttributeShouldRenderIdAttribAndNotName() (name and id attributes can coexist in some doctypes) {quote}

Comments?

@Adam Thanks!

Two more ideas for Zend_View_Helper_Doctype:


public function isStrict()
{
    switch ($this->getDoctype()) {
        case self::XHTML11:
        case self::XHTML1_STRICT:
        case self::HTML4_STRICT:
            // ...
    }
}

public function getHtmlVersionNumber()
{
    // ...
}

@Ulf ??W3C declared XHTML as dead?? XHTML is not dead: XHTML5 ;-)

@Kai: Thanks for the suggestion. That does streamline the logic nicely :) I've attached a patch to reflect the changes.

Regarding Ulf's statement, I think he was referring to the fact that HTML5 is the defacto successor to XHTML 1, and the future of the web (that is, if you believe the hype from Apple, et. al :P)

Thanks for your work on this Adam. One small item of note regarding your latest patch - the test annotations should be "@group ZF-10791" and not "@see ZF-10791". This allows running the tests in isolation via "runtests.sh ZF-10791"

@Marc Thanks for pointing that out. I have changed @see to @group for all of the bug-related tests in Zend_View_Helper_FormTest.

Fixed in trunk r23945

Test added in trunk r23947

Test suite updated in r24058 * Removed incorrect test: testPassingIdAsAttributeShouldRenderIdAttribAndNotName() (name and id attributes can coexist in some doctypes)

Commits reviewed and merged to 1.11 release branch.