Core idea: Your control code needs a quick and reliable way to manipulate the HTML sub-elements or sub-controls a control contains. To this end, QuickUI can automatically generate element reference functions for any element whose ID is specified in the JSON. An element reference function always returns the indicated element, even if another element with the same ID has been added to the DOM. This avoids a large class of name collisions, simplifying the integration of controls from multiple authors.

To have a control access a contained element, one could give that element a unique ID or DOM class name, then use a jQuery selector to find that elements on demand. However, by nature, controls often host other controls whose construction may be unknown and outside your control. Those controls may themselves contain elements whose IDs or class names conflict with the ones you have chosen. Such naming collisions can cause controls to break when combined in new ways, defeating the goal of having controls be context independent.

To address this problem, QuickUI gives you a reliable way to refer to elements within a control. In the JSON which defines your control class’s initial DOM, assign an ID to any HTML element or sub-control by including an “ref:” key in the nested dictionary for that element or sub-control. This will have two effects. First, the element will have “foo” included its list of CSS classes (and can therefore be selected or styled with “.foo” as usual). Second, and more importantly, a function called $foo() will automatically be generated for your control class.

The instant the QuickUI framework creates that #foo element at runtime, it will store a reference to it in the control’s per-instance data. Invoking $foo() on that control will return the control’s copy of the #foo element. This runtime lookup is done by reference, not by searching by class, so it works even when other elements with the same class have been added within the control’s subtree.

The demo code creates a simple user tile class such as might be found on a social networking site. A tile includes a photo – for demo purposes, this will be a random photo – and a span to hold the user’s name. The code then creates three user tile controls, and searches through these for the spans that have class “.name”. It directly manipulates these spans to give each tile a different user name.

This works — for now. But what if the author of FlickrInterestingPhoto decides to give that control a sub-element with class “.name”? The attempt to search for name spans by class would inadvertently pick up unintended elements inside FlickrInterestingPhoto. It’s better to avoid the potential for a naming collision.

Your goal: Rewrite this code to use an element reference function to reliably manipulate the name span.

  1. Remove the class='name' attribute from the “html:” line and replace it with a ref: "name" declaration on the line that follows the “html:” line. This will generate a function called $name() that always returns the indicated element.
  2. Replace the find("#name") calls with calls to the new $name() function.