Losing Values When Cloning Forms

The Web is ever changing, and this article is relatively ancient having been published 9 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

I’ve finally started development of a book recommendation widget for the musings and reviews on books I read section of my site. The general functionality is pretty simple: visitors have a few fields to complete with info about the book; upon submission, their recommendation is saved to a database; the new recommendation is shown to all and sundry in a “last recommendation” section; rinse & repeat. The whole no-JS needed, server-side scripting processing involved is simple, straight-forward and was quickly completed. Being a front-end developer, however, I want to make sure this can all be done in a smooth JS-enhanced way as well (for some nifty UX). That’s where I encountered yet another annoying JavaScript problem.

Each browser interprets “clone” differently

Due to differences in how each browser implemented cloneNode() in their JavaScript engines, there is an issue with values for form elements not persisting to the copy of an element. Inconsistencies like this are many of the reasons why I’m a fan of using a JavaScript library for most projects. In this case, because the library has usually worked out the issues and can handle copying without losing important data. Unfortunately, jQuery still has some issues to work out; it loses select and textarea values on clone(). Other inputs types don’t seem to have any issues, including hidden fields.

How this affected my widget

In order to display the submitted form data in the “last recommendation” section, I decided the best approach would be to copy the form, then replace each form element with an inline element containing the value based on type of element. It might not be the most elegant solution, but it seemed better than specifying each individual element by name and manipulating it that way.

So, step one: use clone() to copy the form (no need for cloning events and the like). Step two: do the replacement. Step three: realize that regardless of selection, the last recommendation always displays the first option in a select box. And an empty string for any text area.

Solutions

Honestly, my current solution is just a dirty hack. I only have two affected fields, so I explicitly copy the original values to where they need to go. I’m more concerned about getting this up and running, knowing that there won’t be much in the way of extension in the future. I am about 99% positive I won’t be adding any additional fields, at least.

For other projects though, this could be a major issue for scalability and ongoing maintenance, especially if there are multiple affected elements. A quick search around the Internet shows a lot of inelegant solutions. One that approaches a decent solution for jQuery is this solution at mddev.co.uk, although it only attacks the select issue (and later inputs as well with a bit overkill [see the comments], but no textarea). That approach could work with some modifications.

Have you seen this before? How’d you solve it/work around it?

Semantic, Accessible (Good) Forms: the Label Element

One of the most common issues I see with forms is the improper (or lack of) use of label elements. Admittedly, I too am guilty of misuse, but even after becoming aware of them, I was very confused about how to do radio and checkbox elements. Why? I learned incorrectly that the for attribute of the label referred to the name attribute of the input. Wipe that from your memory this instant. The label’s for attribute is a reference to the input’s id.

Wait, back up. What is the label element?

The label element in HTML provides a way to give semantic meaning to the text describing or labeling form control elements. Using the element not only gives you an element to style around your labels, but also provides accessibility and functional advantages.

By using a properly constructed label element along with your input, textarea, or select element, you give

  • screen readers information on which form control the label belongs to,
  • manually maladroit visitors an increased click area (clicking on the label focuses on the element), and
  • yourself a semantic element to target with CSS and Javascript to use in design and enhancement.

Add this element and its use to your list of best practices for forms.

How do I use the label element?

The label element is simple to use and shouldn’t cause any additional headaches while setting up forms. Its usage is simple:

<label for="visitor-email">E-mail address</label>
      <input type="text" name="email" id="visitor-email" size="32" />

It can go either before or after your element. In a real form, you would most likely have the entire line wrapped in a list item or paragraph element, but I left those off for purposes of demonstration.

For checkboxes and radio buttons, the usage is very similar. You provide a label for each individual element, keyed to that element’s id attribute:

<label for="contact-by-email">e-mail</label>
      <input type="radio" name="contact-how" id="contact-by-email"  checked="checked" />
<label for="contact-by-phone">phone</label>
      <input type="radio" name="contact-how" id="contact-by-phone"  />

Incorrect use, a demonstration

The following are improper uses of the label element:

<label>E-mail address</label> <input type="text" name="email" id="visitor-email" size="32" />
In this example, the label does not have a for attribute declared, so its semantic value and aid in accessibility is lost.
<label for="contact-how">Contact by</label>
       phone <input type="radio" name="contact-how" id="contact-by-phone"  checked="checked" />
       e-mail <input type="radio" name="contact-how" id="contact-by-email"  />
Here, the for attribute is referring to the name attribute of the inputs. This is incorrect. The for attribute is a reference to the id attribute of the input.
<label>Phone <input type="radio" name="contact-how" id="contact-by-phone" checked="checked" /></label>
While technically correct according to W3C recommendations, this method should not be used. The reason being, certain browsers, particularly mobile browsers, handle this code incorrectly and will often cause the element to be un-clickable. You are better off using the method of labeling checkboxes/radio buttons I described above.

For detailed information on the label element and other form information, check out the W3C Recommendations on Forms.

IE Bug on Enter Key Form Submission

The Web is ever changing, and this article is relatively ancient having been published 10 years ago. It is likely out of date or even blatantly incorrect in relation to modern better practices, so proceed at your own risk.

Due to a punishment handed down by the gods, I’m forced on a weekly — if not daily — basis to serve and protect the ridiculous number of Web users who haven’t escaped the dark ages. Yeah, that’s right — I have to bug hunt in IE6 — a browser with many documented bugs that is quickly approaching its eighth birthday. And sometimes those funky bugs exist even in IE7. This is one of those stories.

The Problem

One of my recent projects was setting up an extremely simple app for a local company. They gave out fliers with a URL and a short alpha-numeric key to students at local schools. The purpose was to have the students go online to the URL and enter the key to access some school-specific information.

Extremely simple and quickly completed, until I was testing and found out that IE didn’t pass along the submit input value if the user submitted the form by pressing enter. Forms 101: enter submits the form, including the submit input.

So why was IE failing remedial form submission? Why, another IE bug of course. And not a very well documented one.

View a Demonstration

When Does it Happen?

Example of problematic form

Think this is a quick, simple, easy form? Not quite …

This bug rears its ugly head under the following conditions:

  1. Your form contains one, and only one, text input. (It can still have other types)
  2. Your visitor hits enter to submit the form while not focusing on a checkbox, radio, or the submit input (in other words, most likely only if they’re focusing on that single text input or some esoteric input element).

The Solution

This issue throws us into a bit of a grey area in terms of a solution, because frankly, there’s no magic fix. But, there are a few different workarounds that you can use. There are various ways you can do it with Javascript, of course. But that means the form can’t be submitted with the bug fixed without JS enabled, thus I’m not going to explain those methods.

Probably the best solution is the one Jim Meyes posits:

The solution is to hide an additional disabled input for IE to find, using IE conditional Comments and hiding it from view with some CSS.

<!--[if IE]><input type="text" style="display: none;" disabled="disabled" »
	 size="1" /><![endif]-->

Editor’s note: Line breaks marked by ».

Why this is a good solution

This is extremely unobtrusive (and thus a quality solution) for a few reasons.

  1. Only IE will “see” the extra input, so we’re not fixing anything that’s not broken in other browsers.
  2. Because the field is disabled, the value isn’t getting passed through to the processing scripts when the form is submitted, so it’s not going to get in the way in the backend.
  3. This might be the only case in which I advocate for inline styles, but they’re solid here, because even if there is a user-specific stylesheet enabeld, it’s unlikely that a style will take precedence unless !important is employed (and IE <= 6 ignores that declaration anyhow …)

The only case I can think of where the user will notice this is when CSS is disabled (and far more unlikely: if for some reason a screen reader or such doesn’t ignore display:none;). My only suggested improvement: add a value to the field that succinctly describes why the field exists and is disabled. Thus, I would use this code:

<!--[if IE]><input type="text" style="display: none;" disabled="disabled"  »
	 size="20" value="Ignore field. IE bug fix" /><![endif]-->

Editor’s note: Line breaks marked by ».

N.B. I also bumped up the size of the field so that the visitor could see the entire value. This shouldn’t be a problem; if they’re actually seeing the field, your layout is already mangled.

Can you think of a better workaround?

Closing Arguments

Basically, if you are doing any server-side processing that relies on checking to see if the submit button was pressed, you must have multiple text fields or implement a workaround.

Best of luck in your own IE bug hunting. And please, wear bright colors and don’t shoot other hunters.

Update: I haven’t tested it personally, but I’ve received a few comments and e-mails that it also happens in IE8. So, maybe it’s not a bug, but it is an annoying decision on Microsoft’s part. This hack works, at least.