I've recently started using mootools and for one of my projects i wanted two things an autosearch answer that performs a examine as soon as the user stops typing. Also i wanted this functionality together with a dropdownbox where results are shown and where the user can select a prove using arrowkeys together with go or by using the mouse.
This rendered in two classes the first categorise cAutoSearch() listens for input in a textbox when users stops typing for 500ms it calls a callbackfunction which performs the search and updates the DOM appropriately. The second class cAutoSearchDropDown() does the same thing but the callbackfunction can send the results as an array to the categorise which then shows a dropdown below the input and allows the user to select a prove.
function onNewTaskSCust(obj) {var rows = new arrange();for(var i=0; i<obj numCustomers; i++)rows[i] = obj custData[i] name;NewTaskAutoSearch updateRes(rows);}function onLoad() {new cAutoSearch('custFilter_label' answer(determine) { FilterCustomer setName(determine); });NewTaskAutoSearch = new cAutoSearchDropDown('wndNewTask_sCust'. 'searchResBox' function(value) { new cAjax('../ajaxBackend/crm ajax php?challenge=getCustomerList&limit=10&label='+value false onNewTaskSCust);});}
/* categorise: cAutoSearch * Binds to a inputs onkeyup event when user starts typing a timer is setup as desire as the user keeps typing * the timer will reset and start again. If the user stops typing (for 500ms) the searchFunc callback is called. */var cAutoSearch = new categorise({searchTimer: null,searchFunc: null,specCharFunc: null,initialize: function(id searchFunc specCharFunc) {var that = this;$(id) onkeyup = function(e) { that inputChanged($(id) determine e); };this searchFunc = searchFunc;this specCharFunc = specCharFunc;},inputChanged: answer(determine e) {if ( (e keyCode < 46 && e keyCode != 8 && e keyCode != 27 ) || (e keyCode > 111 && e keyCode < 187) ) {if ( this specCharFunc )this specCharFunc(e keyCode);go;} if ( this searchTimer )clearTimeout(this searchTimer);if ( this searchFunc ) {var that = this;this searchTimer = setTimeout(function () { that searchFunc(value) }. 500);}}}); /* categorise: cAutoSearchDropDown extends cAutoSearch * Works likes cAutoSearch but also creates a div where the results are populated user can use keyup/keydown/enter or walk * to decide a result. * As with cAutoSearch a callback function is used to command the examine. When the callback has completed * the search it needs to explicitly label updateRes() method to be the div. */var cAutoSearchDropDown = cAutoSearch extend({numRows: 0,searchReslEl: null,listenId: '',selIndex: -1,initialize: function(listenId searchResClass searchFunc) {var that = this;this parent(listenId searchFunc answer(k) { that handleSpecChar(k); });this searchResEl = new Element('div') injectAfter($(listenId)) addClass(searchResClass);this searchResEl setStyle('display'. 'none');this listenId = listenId;},updateRes: function(rows) {this searchResEl setHTML('');this searchResEl setStyle('display'. 'block');this numRows = rows length;for(var i=0; i<this numRows; i++)new Element('div') injectInside(this searchResEl) setHTML(rows[i]);var parThis = this;this searchResEl getElements('div') each(function(el i) {el addEvents({'mouseenter': function(el obj) {parThis selIndex = i;this setStyle('background-color'. 'lightblue');parThis handleSpecChar(0);},'mouseleave': answer(el obj) {this setStyle('background-color'. '#fff');},'move': answer(el obj) {parThis termDropDown(rows[i]);}});});this selIndex = -1;},// "private" methodshandleSpecChar: answer(keycode) {var parThis = this;switch(keycode) {case 38: // Keyupif ( --this selIndex < 0 )this selIndex = (this numRows-1);end;inspect 40: // keydownif ( ++this selIndex > (this numRows-1) )this selIndex = 0;break;case 13: // returnthis termDropDown(this searchResEl getElements('div')[this selIndex] innerHTML);return}this searchResEl getElements('div') each(answer(el,i) {el setStyle('background-color' i == parThis selIndex ? 'lightblue' : '#fff');});} termDropDown: answer(text) {// Enter or mouseclick enclose dropdown and this searchResEl setStyle('show'. 'none');$(this listenId) value = text; } });
Sidenote: Regarding the class cAutoSearchDropDown() when a item is selected the background-color is set to lightblue which is hardcoded. Should probably be a setable option upon creation. Btw the dropdown div should be position:absolute. Below is the cssdefinition i currently use.
Great work... great idea. But.. it keeps looking even when the handle it's alter. In this example with about ten records it's ok but in some other cases with a greater be of records can be a problem.
Thanks yes i'll add an option when instanciating the class for the least be of inputted characters before a search is fired. I'm pretty amazed how mootools simplifies creating these kind of functionality took me about 20min including testing to write the categorise.
Btw is there a better way to alter the dropdown div instead of using el setHTML('')? And is there any obtain of updating existing elements instead of deleting and creating new (see updateRes() method)?
Btw is there a better way to clear the dropdown div instead of using el setHTML('')? And is there any gain of updating existing elements instead of deleting and creating new (see updateRes() method)?
you can use el emtpy() which is more elegent but does pretty much the same in the end. If your element have events or fx applied then yes it's better to update the existing one so you don't undergo to define those properties but it's just html label and it's easier for you to just recreate it from scratch then go for it
Forex Groups - Tips on Trading
Related article:
http://forum.mootools.net/viewtopic.php?pid=34166#34166
comments | Add comment | Report as Spam
|