Categories
Development

Too many options!

Ran into a peach of an issue on friday – client complains of a report being ‘glitchy’. They have a learning management system which contains a report with a filter that lists all student ID’s in an HTML select element. No problems you’d think… until you realise there are 13,000 plus students, all listed out as options within the select element… and the page has performance issues trying to load all the options.

What can we do?

So my first instinct was to throw some javascript at it, and convert the problem from being a select element to being a div with some javascript to handle displaying a much smaller subset of options depending on what is being typed – Select2 is my go-to javascript select replacement library, so we threw that at it.

Did it work? No. Same performance issues, but they were less as you filtered down the result set by entering digits… So its a bit of a better look, but it still ain’t right. What a pickle! Where to now?

After a period of trawling Google search results for a solution, I’ve stumbled upon the datalist html element. There is talk of it being a more efficient option as a select alternative… so here is what I’ve done:


jQuery('#id_filter_fuserfield_idnumber').after('<input type="text" list="filt_students" id="id_filter_fuserfield_idnumber_entry"/><datalist id="filt_students"></datalist>');
var opts = "";
jQuery('#id_filter_fuserfield_idnumber option').each(function(k,v){ 
    opts += "<option "+jQuery(v).attr("selected")+">"+jQuery(v).text()+"</option>"; 
	if(jQuery(v).attr("selected")){
		jQuery('#id_filter_fuserfield_idnumber_entry').val(jQuery(v).text()); 
	});
}
jQuery('#filt_students').append(opts);
jQuery('#id_filter_fuserfield_idnumber').hide();
jQuery('#id_filter_fuserfield_idnumber_entry').on('change',function(){
	jQuery('#id_filter_fuserfield_idnumber').val(jQuery('#id_filter_fuserfield_idnumber option:contains("'+jQuery('#id_filter_fuserfield_idnumber_entry').val()+'")').attr('value'))
});

So to explain this:
– add text input and link empty datalist after the select element (note no name on the text input so data not submitted with form).
– populate the datalist with items from the select element. If an item from the select options is marked as selected, update the text box to reflect that.
– hide the original select element.
– listen to changes on the text input so that when a value is chosen, the select has its value updated to match the chosen value.

Testing this, it is really fast. Like – really fast. No performance issues with 13,000 options to chose from, and all behaves as expected very similar to a select inpout, but you have the advantage of being able to use the text input to start typing and filter the list of elements to chose from accordingly. Vary cool!

In summary – don’t always reach for Select2 to solve select problems – the datalist element is your friend, and offers similar basic functionality (yeah I know – select2 can do a bunch more esp when it comes to ajax loading etc, so horses for courses, but if you don’t need the extra functinality…). I know I’ll be looking at using datalists more going forward.