Ajax.implement({ responseIsSuccess: function(status){ try { if(this.transport.readyState != 4 || this.transport.status == "undefined" || (this.transport.status < 200 || this.transport.status >= 300)) return false; return true; } catch(e) { return false; } }, responseIsFailure: function(){ return !this.responseIsSuccess(); }, onStateChange: function(){ if (this.transport.readyState == 4 && this.responseIsSuccess()){ if (this.options.update) $(this.options.update).setHTML(this.transport.responseText); this.options.onComplete.pass([this.transport.responseText, this.transport.responseXML], this).delay(20); if (this.options.evalScripts) this.evalScripts.delay(30, this); this.transport.onreadystatechange = Class.empty; this.callChain(); } else if(this.transport.readyState == 4 && this.responseIsFailure()) { if($type(this.options.onFailure)=='function') this.options.onFailure.pass(this.transport, this).delay(20); } } }); Element.extend({ hide: function() { this.style.display = 'none'; return this; }, show: function() { this.style.display = ''; return this; } }); var AjaxAutoCompleter = new Class({ initialize: function(element, choices, url, options) { this.options = Object.extend({ minChars: 1, delay: 400, indicator: null }, options || {}); if (this.options.indicator != null) { this.indicator = $(this.options.indicator); } this.element = $(element); this.choices = $(choices); this.url = url; this.choices.hide(); this.currentValue = ''; this.element.setAttribute("autocomplete", "off"); this.element.addEvent('keyup', this.onTextChange.bindAsEventListener(this)); this.element.addEvent('blur', this.onTextBlur.bindAsEventListener(this));this.element.onkeydown = this.onKeyDown.bind(this); this.element.onkeypress = this.onKeyPress.bind(this); }, onKeyPress: function(e) { if (window.event) { var keyCode = window.event.keyCode; } else { var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; } if (keyCode == 13) { if (this.choices.style.display == '') { var currentSel = $E('div.selected', this.choices); if (currentSel) { this.choiceSelect(currentSel); } } return false; } return true; }, onKeyDown: function(e) { if (window.event) { var keyCode = window.event.keyCode; } else { var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode; } if (keyCode == 40 || keyCode == 38) { if (this.choices.style.display == '') {var currentSel = $E('div.selected', this.choices); if (keyCode == 38) {if (currentSel && currentSel.getPrevious()) { currentSel.removeClassName('selected'); currentSel.getPrevious().addClassName('selected'); } else if (!currentSel) { var tempSel = $ES('div', this.choices); if (tempSel && tempSel.length > 0) { tempSel[tempSel.length-1].addClassName('selected'); } } } else if (keyCode == 40) {if (currentSel && currentSel.getNext()) { currentSel.removeClassName('selected'); currentSel.getNext().addClassName('selected'); } else if (!currentSel) { var tempSel = $E('div', this.choices); if (tempSel) { tempSel.addClassName('selected'); } } } } return false; } return true; }, onTextChange: function() { if (this.fetchDelay) { this.fetchDelay = $clear(this.fetchDelay); } this.fetchDelay = this.fetch.delay(this.options.delay, this); }, fetch: function() { if (this.element.value.length <= this.options.minChars) { this.choices.hide(); } else { if (this.element.value != this.currentValue) { this.currentValue = this.element.value; this.clearSelected(); this.choices.show(); if (this.indicator) { this.indicator.show(); } new Ajax(this.url + this.element.value, {onFailure:this.onFailure, onComplete:this.onSuccess.bindAsEventListener(this)}).request(); } } }, onFailure: function(response) { if (this.indicator) { this.indicator.hide(); } alert('There was a problem! ' + response); }, onSuccess: function(response) { if (this.indicator) { this.indicator.hide(); } if (response.trim() == '') { this.choices.hide(); } else { this.choices.setHTML(response); $ES('div', this.choices).each(function (el) { el.addEvent('mouseover', function() {this.choiceOver(el);}.bind(this)); el.addEvent('mousedown', function() {this.choiceSelect(el);}.bind(this)); }.bind(this)); } }, onTextBlur: function() { this.choices.hide(); }, choiceOver: function(element) { this.clearSelected(); element.addClassName('selected'); }, choiceSelect: function(element) { eval(element.id); this.currentValue = this.element.value; this.choices.hide(); }, clearSelected: function() { $ES('div.selected', this.choices).each(function (el) { el.removeClassName('selected'); }); } });
