digestive-functors
digestive-functors copied to clipboard
listOf generates invalid HTML (w/ Heist)
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>
@mightybyte aren't you using this feature as well? Did you ever encounter this issue?
Ahhh, I had not noticed this issue. But I agree that it is definitely a problem.
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.