Chaining Form Elements

For this tutorial/community site I’m working on I need a (front-end) form to display (or not display) form controls based on user selections. I believe this is referred to as “chaining”? Correct me if I’m wrong.

Is this sort of logic usually done server-side or with js? I’m not sure if I need to look at the PHP framework I’m using to build the site or somewhere else.

Todd


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Depending on the degree of logic needed, it can be done in either or both (I would tend to say both, unless you only have a few possible combinations, and don’t mind overloading the page with extra elements that won’t appear).

One thing to realize here — if your pickers are replaced on screen, then any handler that is bound to them will fail after the update. Here’s an example:

<select name=“foo” id=“foo” size=“1”>
	<option value=“a”>A</option>
</select>

$('foo').observe('change', function(){
	// do something clever here, maybe call the next picker after that
});

The first time the page loads, the observer will work. But if you update that select using an Ajax callback that replaces the whole element, then unless you re-initialize your observer, it will never work again. That’s because the initial call that created the observer function bound it to that actual picker element, not just any picker with that name.

There’s a way around this, actually two ways I can think of off the top of my head. First is to use a lazy (late-evaluating) observer, like this:

document.on('change', '#foo', function(evt, elm){
	// do your cleverness here
});

Now, no matter what happens to the picker, if it fires a change event and the document catches it, the method will do its thing, because the observer is bound to the document, which doesn’t change.

The other way around this is to instantiate the picker, and bind an observer to it, but then never remove that select element. To replace all the option elements of a select without getting rid of the outer select (and thereby breaking the bond with its observer), you need to follow this pattern (ignore anyone who tells you you can just update the contents of the picker with a new set of options using jQuery or Prototype — that will only work in a frustratingly tiny minority of the browsers out there).

$('foo').options.length = 0; // erase existing options
$H({a: 'A', b: 'B', c: 'C'}).each(function(pair){
	$('foo').options[$('foo').options.length] = new Option( pair.value, pair.key );
}); 

In this example, I’m using a hard-coded hash of variables, but replace that with an Ajax request to your server to get the proper set of values based on the initial value, and you get a very flexible setup that can be administered through the database (you don’t need to edit the HTML or JavaScript to change the possible options). As long as your server can return JSON, then you are all set.

Walter

On Nov 8, 2014, at 12:14 PM, Todd email@hidden wrote:

For this tutorial/community site I’m working on I need a (front-end) form to display (or not display) form controls based on user selections. I believe this is referred to as “chaining”? Correct me if I’m wrong.

Is this sort of logic usually done server-side or with js? I’m not sure if I need to look at the PHP framework I’m using to build the site or somewhere else.

Todd


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Thank you, I’ll go over this. The framework has built-in tools for working with bindings. The js part is another matter.

I don’t want to remove an element if it triggers an event, only add whatever control is bound to it so the user can see the progression of their selections and if necessary go back and change something.

I think the “bind” you’re referring to is something I recently started using to customize the back-end (Manager) of the framework. I’m still getting my head around the concept but what I’ve done with bindings so far is pretty cool. I can see where some extremely slick functionality can be implemented both front and back.

This entire community site project is turning into a real tech safari and it’s leading me deep into the jungle. I’m really enjoying the ride but I may need some water-wings to keep me afloat.

Todd

The other way around this is to instantiate the picker, and bind an observer to it, but then never remove that select element.


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Just to give this some context, the the default form element to which all other options are tied to is a “Name” text field. If the user enters something it will trigger the chain.

Name [text field] (initially visible)

Picker 1 (triggered by Name)

Picker 2 (triggered by Picker 1)

Text Field (triggered by Picker 2)

etc.

Todd


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

That’s not hard to do, but think about the UX you want when typing in the text box, do you want the function to fire after every keystroke, or after they tab out of the field (or otherwise blur)?

Walter

On Nov 8, 2014, at 1:17 PM, Todd email@hidden wrote:

Just to give this some context, the the default form element to which all other options are tied to is a “Name” text field. If the user enters something it will trigger the chain.

Name [text field] (initially visible)

Picker 1 (triggered by Name)

Picker 2 (triggered by Picker 1)

Text Field (triggered by Picker 2)

etc.

Todd
http://xiiro.com


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Tab out.

That’s not hard to do, but think about the UX you want when typing in the text box, do you want the function to fire after every keystroke, or after they tab out of the field (or otherwise blur)?


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

Your example uses vanilla js, yes?

Todd


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

No, that’s all Prototype stuff. You can get close with jQuery and Underscore (to get the each() stuff).

Walter

On Nov 8, 2014, at 1:35 PM, Todd email@hidden wrote:

Your example uses vanilla js, yes?

Todd
http://xiiro.com


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

I’ve been debating the js aspect. Using a framework (Prototype, jQuery) does appeal to me in terms of initial convenience but I’m wondering if going the vanilla route is a better long-term plan, thus avoiding any dependency on a specific framework. js in general is not my strongest area so a blank slate approach will add to my workload and stress level.

Todd

No, that’s all Prototype stuff. You can get close with jQuery and Underscore (to get the each() stuff).


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options

There’s a great article out there titled “Do you need jQuery” – it’s a monster list of jQuery tropes and their “vanilla” equivalents.

Walter

On Nov 8, 2014, at 1:55 PM, Todd email@hidden wrote:

I’ve been debating the js aspect. Using a framework (Prototype, jQuery) does appeal to me in terms of initial convenience but I’m wondering if going the vanilla route is a better long-term plan, thus avoiding any dependency on a specific framework. js in general is not my strongest area so a blank slate approach will add to my workload and stress level.

Todd
http://xiiro.com

No, that’s all Prototype stuff. You can get close with jQuery and Underscore (to get the each() stuff).


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options


dynamo mailing list
email@hidden
Update your subscriptions at:
http://freewaytalk.net/person/options