SteveSanderson/knockout — Issue #360: New "uniqueId" binding handler
Author: ducka
Created: 2012-03-05 11:03:03+00:00
State: open

Hey all,

After working with ASP.Net MVC & Knockout JS for some time now, I've come to realise that automatic, unique, and **deterministic** html element ID generation seems to be a real problem for client side web applications. It's quite possible to explicitly set the IDs of your html elements in a simple flat form; however, as soon as you throw a foreach template into the mix, your explicitly set IDs are no longer unique. So far, this has caused me problems in the following areas:

* Where html elements need to reference other elements by their Id. The most obvious example of this is the `` element; however, I'm also experiencing this issue with a UI messaging framework I wrote which associates "Field Message Controls" with input elements in the dom via their IDs.
* I haven't had personal experience with this yet, but I've heard some Automated Web UI testing suites use the ID's of html elements to reference when testing the UI. I suspect if this is true, and your IDs are not unique and deterministic, your UI tests will break as soon as you change the webpage.

In an attempt to at solve the unique Id problem, I wrote a "UniqueId" binding. When applied to an element with a server side generated Id it would generate a new client side unique Id for that element, and would then update the Id reference of all other elements in the page (like `` elements). Unfortunately this binding was far from perfect; It didn't provide me with deterministic Ids, and the search and replace operation that updated the Id references killed the page's performance whenever the view model was updated with ko.mapping.fromJS(). Having said that, the process of writing the Unique Id binding gave me a better idea of what I think the solution to this problem should be.

I think Knockout JS should have some sort of ID generation binding handler that assigns a deterministic Id to each HTML element it's applied to. While it would be nice to have magical automatic generation of deterministic unique Ids across all of your html elements, I've discovered that I'm mainly interested in deterministic and unique Ids for input, select, and textarea elements. The main value binding of these elements are the "value" and "selectedOptions" bindings. I think it could be possible to determine the Id of these elements based off the view model property path that binds to the elements via these bindings.

For example, the Knockout binding markup would look like something like this:

````

Person Name

Street

Suburb

````

And here is the markup (minus the residual knockout attributes and elements) that would result from the above code:

````

Person Name

Street

Suburb

Street

Suburb

````

A binding like this would achieve automatically generated, deterministic, and *relatively unique*^ Id's for all of your input, select, and text area controls. I believe this sort of Id generation is similar to what ASP.Net MVC uses in it's HtmlHelper extension methods.

(^ I say relatively unique because it is possible to bind 2 inputs to the same property on the view model. If you really require unique Id's for these controls, you could create two properties with different names, with one depending on the value of the other..)

I suspect a binding like this could be written quite easily if I was able to figure out the view model property path (relative to the root of the view model) from the "value" or "selectedOptions" binding. From what I've seen so far, figuring out this information from within a binding handler is quite difficult, even with the new "binding context" object.

Anyways, I think this sort of feature would be quite useful in Knockout Js.