From 7da736f929e88f4730f160d28afc90667c26b966 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 26 Jun 2005 12:03:43 +0000 Subject: Added script.aculo.us Javascripts (controls.js, dragdrop.js, effects.js) (NEEDS MORE DESCRIPTION) #1509 [Thomas Fuchs] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@1522 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../action_view/helpers/javascripts/controls.js | 218 +++++++++++++++++++++ 1 file changed, 218 insertions(+) create mode 100644 actionpack/lib/action_view/helpers/javascripts/controls.js (limited to 'actionpack/lib/action_view/helpers/javascripts/controls.js') diff --git a/actionpack/lib/action_view/helpers/javascripts/controls.js b/actionpack/lib/action_view/helpers/javascripts/controls.js new file mode 100644 index 0000000000..94d438a784 --- /dev/null +++ b/actionpack/lib/action_view/helpers/javascripts/controls.js @@ -0,0 +1,218 @@ +// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us) +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Ajax.Autocompleter = Class.create(); +Ajax.Autocompleter.prototype = (new Ajax.Base()).extend({ + initialize: function(element, update, url, options) { + this.element = $(element); + this.update = $(update); + this.has_focus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entry_count = 0; + this.url = url; + + this.setOptions(options); + this.options.asynchronous = true; + this.options.onComplete = this.onComplete.bind(this) + this.options.frequency = this.options.frequency || 0.4; + this.options.min_chars = this.options.min_chars || 1; + this.options.method = 'post'; + + if(this.options.indicator) + this.indicator = $(this.options.indicator); + + this.observer = null; + + Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); + Event.observe(document, "click", this.onBlur.bindAsEventListener(this)); + }, + + show: function() { + Element.show(this.update); + if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0)) { + new Insertion.Before(this.update, + ''); + this.iefix = $(this.update.id+'_iefix'); + this.iefix.style.position = 'absolute'; + this.iefix.style.zIndex = 1; + this.update.style.zIndex = 2; + } + if(this.iefix) { + Position.clone(this.update, this.iefix); + Element.show(this.iefix); + } + }, + + hide: function() { + if(this.iefix) Element.hide(this.iefix); + Element.hide(this.update); + }, + + startIndicator: function() { + if(this.indicator) Element.show(this.indicator); + }, + + stopIndicator: function() { + if(this.indicator) Element.hide(this.indicator); + }, + + onObserverEvent: function() { + this.changed = false; + if(this.element.value.length>=this.options.min_chars) { + this.startIndicator(); + this.options.parameters = this.options.callback ? + this.options.callback(this.element, Form.Element.getValue(this.element)) : + Form.Element.getValue(this.element); + new Ajax.Request(this.url, this.options); + } else { + this.active = false; + this.hide(); + } + }, + + onComplete: function(request) { + if(!this.changed) { + this.update.innerHTML = request.responseText; + + if(this.update.firstChild && this.update.firstChild.childNodes) { + this.entry_count = + this.update.firstChild.childNodes.length; + for (var i = 0; i < this.entry_count; i++) { + entry = this.get_entry(i); + entry.autocompleteIndex = i; + Event.observe(entry, "mouseover", this.onHover.bindAsEventListener(this)); + Event.observe(entry, "click", this.onClick.bindAsEventListener(this)); + } + } else { + this.entry_count = 0; + } + + this.stopIndicator(); + + this.index = 0; + this.render(); + } + }, + + onKeyPress: function(event) { + if(this.active) + switch(event.keyCode) { + case Event.KEY_TAB: + case Event.KEY_RETURN: + this.select_entry(); + Event.stop(event); + case Event.KEY_ESC: + this.hide(); + this.active = false; + return; + case Event.KEY_LEFT: + case Event.KEY_RIGHT: + return; + case Event.KEY_UP: + this.mark_previous(); + this.render(); + return; + case Event.KEY_DOWN: + this.mark_next(); + this.render(); + return; + } + else + if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) + return; + + this.changed = true; + this.has_focus = true; + + if(this.observer) clearTimeout(this.observer); + this.observer = + setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); + }, + + onHover: function(event) { + element = Event.findElement(event, 'LI'); + if(this.index != element.autocompleteIndex) + { + this.index = element.autocompleteIndex; + this.render(); + } + }, + + onClick: function(event) { + element = Event.findElement(event, 'LI'); + this.index = element.autocompleteIndex; + this.select_entry(); + }, + + onBlur: function(event) { + element = Event.element(event); + if(element==this.update) return; + while(element.parentNode) + { element = element.parentNode; if(element==this.update) return; } + this.hide(); + this.active = false; + }, + + render: function() { + if(this.entry_count > 0) { + for (var i = 0; i < this.entry_count; i++) + this.index==i ? + Element.Class.add(this.get_entry(i),"selected") : + Element.Class.remove(this.get_entry(i),"selected"); + + if(this.has_focus) { + if(this.get_current_entry().scrollIntoView) + this.get_current_entry().scrollIntoView(false); + + this.show(); + this.active = true; + } + } else this.hide(); + }, + + mark_previous: function() { + if(this.index > 0) this.index-- + else this.index = this.entry_count-1; + }, + + mark_next: function() { + if(this.index < this.entry_count-1) this.index++ + else this.index = 0; + }, + + get_entry: function(index) { + return this.update.firstChild.childNodes[index]; + }, + + get_current_entry: function() { + return this.get_entry(this.index); + }, + + select_entry: function() { + this.hide(); + this.active = false; + value = Text.decodeHTML(Element.collectTextNodesIgnoreClass(this.get_current_entry(), 'informal')); + this.element.value = value; + this.element.focus(); + } +}); \ No newline at end of file -- cgit v1.2.3