So the old JavaScript aficionado and the young jQuery wizard in me are having a little disagreement. Sorry for the long setup, but the heart of the issue is whether to embed onClick
code directly in my HTML or to go jQuery-style and and use bind()
or click()
. I find myself & myself disagreeing on this topic quite often, so I thought I would try generate some discussion on the issue. To explain the issue, the pattern below seems to bring this to the forefront most often.
Typical Example
I'm writing a search for a member directory. On my interface I have various filter criteria like "gender", "member since", and "has profile photo". A criteria looks like this ...
- A user can select an option by clicking on the text (e.g. "Female") or choosing the radio button.
- When a selection is made the appropriate radio button is selected the text is bold-ed
My html ends up looking something like ...
<div id="FilterContainer_GenderDIV">
<span id="FilterLabel_Gender">Gender:</span>
<span id="FilterSelection_Gender">Any</span>
<span id="FilterChicklet_Gender" class="sprite_MediumArrowDown inline" ></span>
<div id="FilterOptions_GenderDIV">
<input type="radio" id="GenderID" name="GenderID" value="1"/> <a href="" id="FilterOptionLink_CoupleGender_1" >Male</a><br />
<input type="radio" id="GenderID" name="GenderID" value="2"/> <a href="" id="FilterOptionLink_CoupleGender_2" >Female</a><br />
<input type="radio" id="GenderID" name="GenderID" value="0" checked="checked"/> <a href="" id="FilterOptionLink_CoupleGender_0" class="SearchSelectedChoice" >Any</a><br />
</div>
The issue really arises when a user clicks on the text link. At that point I need to know which radio set to change,which link text to bold, and take the newly selected text and change my header label. I see a few options for making this type of scenario work.
Options for making it work
jQuery Injection with Clever element names
I can use jQuery to bind to my elements in a generic fashion. $('#FinderBodyDIV input:radio').click(SearchOption_Click);
Then sort out the appropriate ID & text with clever dom inspection. For example, name my hyperlink could be named GenderID_Link_1
where 1
is the ID I should select and GenderID
tells me which radio set to change. I could use a combination of '.parents().find()
and
.siblings()` to find the radio next door and set it with the ID.
- This is good because my binding code is simple and my jQuery is separated from my HTML
- It's bad because my code functioning now really depends on a brittle HTML structure & naming.
Bind elements individually with eventData
An alternate option is to gather up my set of elements and for each individual element do a 'bind()' passing eventData.
var elements = $('#FinderBodyDIV input:radio');
elements.each ( FunctionWithLogicToBindPassingEventData );
- This is satisfying because I've separate the logic for binding event data from a brittle HTML structure.
- It's bad because I've simply moved the brittle piece to a new function
- It's also bad because I've introduced slowed down (relatively) the binding (more DOM traversal).
Embed onClick code in the HTML
This is where my old JavaScript inclinations keep taking me. Instead of using jQuery to inject bindings, I change my link/radio button HTML to include click handlers. Something like ...
<input type="radio" id="GenderID" name="GenderID" value="1" onClick="SetGender(1,'Male')"/> <a href="" id="FilterOptionLink_Gender" onClick="SetGender(1,'Male')">Male</a><br />
- This is satisfying because i know the values when I'm generating the HTML, so I've simplified my life.
- I've removed a lot of dependency on my HTML structure (although not all).
- On the down side, I've co-mingled my JS and HTML.
- It feels dirty.
So what's a boy to do?
This seems like a fairly common scenario. I find it pops up in quite a few situations besides the one I've described above. I've searched tubes on the interweb, blogumentation, and technical articles on twitter. Yet, I don't see anyone talking about this issue. Maybe I just don't know how to phrase the issue. Whatever the reason, I don't feel good about any of the solutions I've come up with.
It really comes down to how do I associate a clicked element with it's related data--JSON, embedded in HTML names, or otherwise. So what's your take?
The pat answer is that embedding the onClick call in the input element goes against the unobtrusive javascript concept. However, I'm the kind of developer that'll go ahead and use it anyway if it gets the jorb done and the audience is not likely to have javascript disabled.
If I'm understanding the problem correctly, you need a way to do things jQuery-style without relying on html structure and such. Give your radio buttons a class name, for example, the "Male" radio button can have class="Male", and you can select it via jQuery easier.
Bonus: There are some instances where you may need to assign some element more than one class, for example, you are filtering by language and by country. So you can assign some element multiple classes like this:
And select it using either class later.