digestive-functors icon indicating copy to clipboard operation
digestive-functors copied to clipboard

listOf generates invalid HTML (w/ Heist)

Open cimmanon opened this issue 11 years ago • 3 comments

When creating a list of elements via listOf/dfInputList, the generated HTML contains duplicate IDs. This is not valid in HTML, and can cause confusion with JavaScript.

My Heist template:

<fieldset>
    <legend>Product Codes</legend>

    <dfInputList ref="codes"><ul>
    <dfListItem><li itemAttrs><dfLabel ref="name">Name <dfInputText ref="name" itemAttrs /></dfLabel>
        <dfLabel ref="code">UPC <dfInputText ref="code" itemAttrs /></dfLabel>
        <input type="button" name="remove" value="Remove" /></li></dfListItem>
    </ul>

    <input type="button" name="add" value="Add another product" /></dfInputList>
</fieldset>

Generated HTML

<fieldset>
    <legend>Product Codes</legend>

    <div id='form.codes' class='inputList'><input type='hidden' name='form.codes.indices' value='0' /><ul>
    <li id='form.codes.-1' class='form.codes inputListTemplate'><label for='form.codes.-1.name'>Name <input id='form.codes.-1' class='form.codes inputListTemplate' type='text' name='form.codes.-1.name' value /></label>
        <label for='form.codes.-1.code'>UPC <input id='form.codes.-1' class='form.codes inputListTemplate' type='text' name='form.codes.-1.code' value /></label>
        <input type='button' name='remove' value='Remove' /></li><li id='form.codes.0' class='form.codes inputListItem'><label for='form.codes.0.name'>Name <input id='form.codes.0' class='form.codes inputListItem' type='text' name='form.codes.0.name' value='a' /></label>
        <label for='form.codes.0.code'>UPC <input id='form.codes.0' class='form.codes inputListItem' type='text' name='form.codes.0.code' value='1234' /></label>
        <input type='button' name='remove' value='Remove' /></li>
    </ul>

    <input type='button' name='add' value='Add another product' /></div>
</fieldset>

cimmanon avatar Jun 07 '13 14:06 cimmanon

@mightybyte aren't you using this feature as well? Did you ever encounter this issue?

jaspervdj avatar Aug 05 '13 10:08 jaspervdj

Ahhh, I had not noticed this issue. But I agree that it is definitely a problem.

mightybyte avatar Aug 05 '13 15:08 mightybyte

The invalid HTML is partially my own doing, I should have updated this issue.

Here's a jist containing the JavaScript I've written and the modifications I had to make to the dfInputList function to get it working the way I needed: https://gist.github.com/cimmanon/6158752

When you use the required attribute on form input elements, it doesn't matter what type of component it is (text, textarea, select, etc.), it will prevent the form from processing if the field is blank. This sounds reasonable and good until you use dfInputList and it generates a collection of invisible elements hidden via CSS display: none. Because the components are hidden, the this field cannot be blank notification is hidden as well. The only way to prevent this is to disable the invisible elements.

It is worth noting that disabled elements are not submitted with the rest of the form fields (this is HTML standard and has been for quite some time). HTML5 added the disabled flag for fieldsets which effectively disables all input elements within and is honored by IE8+ along with everyone else.

I should have created an extra attribute splice rather than modify the itemAttrs splice, which would have prevented the invalid HTML in the first place. I'm hesitant to suggest that it should be assumed that all form fields be disabled as a listItemTemplate and enabled as a listItem, since the author may have a legitimate reason to want specific fields to be disabled by default when the items are made available to the user. This is why I mention the disabled flag for fieldsets: it may be safer to leverage this feature somehow rather than slap disabled on everything provided it can still generate valid HTML.

cimmanon avatar Aug 05 '13 20:08 cimmanon