Posts Tagged ‘crossselect’

Optimize how?

Thursday, July 2nd, 2009

Yesterday and today I’ve been rewriting my jQuery crossSelect plugin (probably over half of the code has changed) to; a) Fix the serious bugs brought about by trying to bring my plugin closer in line with how it’s supposed to be done, without fully understanding the implications in advance; b) make the code more efficient, in part applying the ideas in this excellent article; and c) prepare the code for bringing in more functionality in later releases.

With regard to c), the main thing I needed to do was rewrite all my selection and removal functions so that moving many items into the selected column at once could just be the move one item function iterated a number of times. I’ve now ( I think) found a pretty efficient solution (each move many function is only 3 lines long), but along the way I came across an interesting dilemma.

My selectOne() function essentially moved a list item and then checks how many items are in each list before adjusting the buttons appropriately. Now, to do a selectAll() or a selectMany() the obvious thing to do is just to iterate that selectOne() function over all list items – just a handful of lines of code – … but this unfortunately leads to a less efficient (and probably slower) function. Writing a selectAll()/selectMany() function from scratch would enable me to only adjust the buttons once and, in the selectAll() case, not have to care about tracking which list item I’m dealing with as they all get moved over in the end… but this way would not only be less elegant, I feel, but also lead to more lines of code.

I’d always assumed that optimising code meant two things – faster and smaller – and I’d always thought that one more or less implies the other. Turns out I was wrong.

In the end, the escape from this trade off involved removing the button adjustment from selectOne() and putting it in selectNow(), a new function triggered by a click. But this required a feature of jQuery which I’ll talk about in some other post.

It’s all about context

Saturday, May 30th, 2009

One big selling point of jQuery – so everyone says – is the ability to nest/chain selectors, so that using oen string you can, in theory, pick out any element in the DOM. But this has eluded me somewhat until today; until I realised the usefulness of setting a context for jQuery selectors.

I noticed a few days ago that my new crossSelect plugin was a bit inefficient, in that it queried the DOM far too often. It used to have something like the following code:

$(this).parent().parent().find('.target1').children('li')...
$(this).parent().parent().find('.target2').children('li')...

But the next iteration was going to have something like this instead – far sleeker.

var context = $(this).parent().parent()
$(context).find('.target1').children('li')...
$(context).find('.target2').children('li')...

But it bugged me that I couldn’t pick out the <li>’s with a string selector. This is because context is an object, not a string, and therefore can’t be a part of a selector string. But then I discovered setting the context on selectors (easy to miss as it’s not linked to from the selectors bit of the documentation site). So that led to the following:

$(context).find('.target2').children('li');

is equivalent to

$('.target2', context).children('li');

which can be rewritten

$('.target2 > li', context);

Far more elegant, I think you’ll agree. So it’s jQuery context setting all the way for me. From now on I will only use find when I need to find a child element on the same line that I’ve already done something to the parent; it really has no place at the begining of a line of jQuery code.

crossSelect jQuery plugin

Wednesday, May 27th, 2009

I thought I should write a short post to say I have written another jQuery plugin, for making multiple select form elements more intuitive to use. It’s called crossSelect, and here is a demo.

One of these days I will make a proper portfolio site/subsite which collects all the stuff I make together.

I will, I will, I will!