├── Demo ├── GrowingInput.js ├── autocomplete.php ├── autocomplete2.php ├── images │ ├── abrahamlincoln.jpg │ ├── adolfhitler.jpg │ ├── agentsmith.jpg │ ├── agnus.png │ ├── aiai.jpg │ ├── akirashoji.jpg │ ├── akuma.jpg │ ├── alex.jpg │ ├── ang.jpg │ ├── antoinettamarie.jpg │ ├── baal.jpg │ ├── babyluigi.jpg │ ├── backpack.jpg │ ├── bandero.jpg │ ├── baralai.jpg │ ├── bardock.jpg │ ├── baronmordo.png │ ├── barthello.jpg │ ├── blanka.jpg │ ├── bloodybrad.jpg │ ├── cagnazo.jpg │ ├── calonord.png │ ├── calypso.jpg │ ├── caocao.jpg │ ├── captainamerica.jpg │ ├── chang.jpg │ ├── cheato.jpg │ ├── cheshirecat.jpg │ ├── daegon.png │ ├── dampe.png │ ├── danielcarrington.jpg │ ├── daniellang.png │ ├── dansevern.jpg │ ├── darkman.jpg │ ├── darthvader.jpg │ ├── dingodile.png │ ├── dmitripetrovic.png │ ├── ebonroc.png │ ├── eccothedolphin.png │ ├── echidna.jpg │ ├── edeakramer.jpg │ ├── edwardvanhelgen.png │ ├── elena.jpg │ ├── eulogyjones.jpg │ ├── excellagionne.jpg │ ├── ezekialfreeman.jpg │ ├── fakeman.jpg │ ├── fasha.jpg │ ├── fawful.jpg │ ├── fergie.jpg │ ├── firebrand.jpg │ ├── freshprince.jpg │ ├── frylock.jpg │ ├── fyrus.jpg │ ├── lamarr.jpg │ ├── lazarus.jpg │ ├── lebronjames.jpg │ ├── leehong.jpg │ ├── lemmykoopa.jpg │ ├── leonbelmont.jpg │ ├── lewton.jpg │ ├── lexluthor.jpg │ ├── lighter.jpg │ ├── lulu.jpg │ └── spinner.gif ├── index.html ├── mootools-1.2.1-core-yc.js └── submit.php ├── README.md ├── Source ├── TextboxList.Autocomplete.Binary.js ├── TextboxList.Autocomplete.css ├── TextboxList.Autocomplete.js ├── TextboxList.css ├── TextboxList.js └── close.gif └── package.yml /Demo/GrowingInput.js: -------------------------------------------------------------------------------- 1 | /* 2 | Script: GrowingInput.js 3 | Alters the size of an input depending on its content 4 | 5 | License: 6 | MIT-style license. 7 | 8 | Authors: 9 | Guillermo Rauch 10 | */ 11 | 12 | (function(){ 13 | 14 | GrowingInput = new Class({ 15 | 16 | Implements: [Options, Events], 17 | 18 | options: { 19 | min: 0, 20 | max: null, 21 | startWidth: 2, 22 | correction: 15 23 | }, 24 | 25 | initialize: function(element, options){ 26 | this.setOptions(options); 27 | this.element = $(element).store('growing', this).set('autocomplete', 'off'); 28 | this.calc = new Element('span', { 29 | 'styles': { 30 | 'float': 'left', 31 | 'display': 'inline-block', 32 | 'position': 'absolute', 33 | 'left': -1000 34 | } 35 | }).inject(this.element, 'after'); 36 | ['font-size', 'font-family', 'padding-left', 'padding-top', 'padding-bottom', 37 | 'padding-right', 'border-left', 'border-right', 'border-top', 'border-bottom', 38 | 'word-spacing', 'letter-spacing', 'text-indent', 'text-transform'].each(function(p){ 39 | this.calc.setStyle(p, this.element.getStyle(p)); 40 | }, this); 41 | this.resize(); 42 | var resize = this.resize.bind(this); 43 | this.element.addEvents({blur: resize, keyup: resize, keydown: resize, keypress: resize}); 44 | }, 45 | 46 | calculate: function(chars){ 47 | this.calc.set('html', chars); 48 | var width = this.calc.getStyle('width').toInt(); 49 | return (width ? width : this.options.startWidth) + this.options.correction; 50 | }, 51 | 52 | resize: function(){ 53 | this.lastvalue = this.value; 54 | this.value = this.element.value; 55 | var value = this.value; 56 | if($chk(this.options.min) && this.value.length < this.options.min){ 57 | if($chk(this.lastvalue) && (this.lastvalue.length <= this.options.min)) return; 58 | value = str_pad(this.value, this.options.min, '-'); 59 | } else if($chk(this.options.max) && this.value.length > this.options.max){ 60 | if($chk(this.lastvalue) && (this.lastvalue.length >= this.options.max)) return; 61 | value = this.value.substr(0, this.options.max); 62 | } 63 | this.element.setStyle('width', this.calculate(value)); 64 | return this; 65 | } 66 | 67 | }); 68 | 69 | var str_repeat = function(str, times){ return new Array(times + 1).join(str); }; 70 | var str_pad = function(self, length, str, dir){ 71 | if (self.length >= length) return this; 72 | str = str || ' '; 73 | var pad = str_repeat(str, length - self.length).substr(0, length - self.length); 74 | if (!dir || dir == 'right') return self + pad; 75 | if (dir == 'left') return pad + self; 76 | return pad.substr(0, (pad.length / 2).floor()) + self + pad.substr(0, (pad.length / 2).ceil()); 77 | }; 78 | 79 | })(); -------------------------------------------------------------------------------- /Demo/autocomplete.php: -------------------------------------------------------------------------------- 1 | $name) 16 | { 17 | $filename = str_replace(' ', '', strtolower($name)); 18 | $response[] = array($i, $name, null, ' ' . $name); 19 | } 20 | 21 | header('Content-type: application/json'); 22 | echo json_encode($response); -------------------------------------------------------------------------------- /Demo/autocomplete2.php: -------------------------------------------------------------------------------- 1 | $name) 18 | { 19 | if (!preg_match("/^$search/i", $name)) continue; 20 | $filename = str_replace(' ', '', strtolower($name)); 21 | $response[] = array($i, $name, null, ' ' . $name); 22 | } 23 | 24 | header('Content-type: application/json'); 25 | echo json_encode($response); -------------------------------------------------------------------------------- /Demo/images/abrahamlincoln.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/abrahamlincoln.jpg -------------------------------------------------------------------------------- /Demo/images/adolfhitler.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/adolfhitler.jpg -------------------------------------------------------------------------------- /Demo/images/agentsmith.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/agentsmith.jpg -------------------------------------------------------------------------------- /Demo/images/agnus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/agnus.png -------------------------------------------------------------------------------- /Demo/images/aiai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/aiai.jpg -------------------------------------------------------------------------------- /Demo/images/akirashoji.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/akirashoji.jpg -------------------------------------------------------------------------------- /Demo/images/akuma.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/akuma.jpg -------------------------------------------------------------------------------- /Demo/images/alex.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/alex.jpg -------------------------------------------------------------------------------- /Demo/images/ang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/ang.jpg -------------------------------------------------------------------------------- /Demo/images/antoinettamarie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/antoinettamarie.jpg -------------------------------------------------------------------------------- /Demo/images/baal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/baal.jpg -------------------------------------------------------------------------------- /Demo/images/babyluigi.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/babyluigi.jpg -------------------------------------------------------------------------------- /Demo/images/backpack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/backpack.jpg -------------------------------------------------------------------------------- /Demo/images/bandero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/bandero.jpg -------------------------------------------------------------------------------- /Demo/images/baralai.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/baralai.jpg -------------------------------------------------------------------------------- /Demo/images/bardock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/bardock.jpg -------------------------------------------------------------------------------- /Demo/images/baronmordo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/baronmordo.png -------------------------------------------------------------------------------- /Demo/images/barthello.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/barthello.jpg -------------------------------------------------------------------------------- /Demo/images/blanka.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/blanka.jpg -------------------------------------------------------------------------------- /Demo/images/bloodybrad.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/bloodybrad.jpg -------------------------------------------------------------------------------- /Demo/images/cagnazo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/cagnazo.jpg -------------------------------------------------------------------------------- /Demo/images/calonord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/calonord.png -------------------------------------------------------------------------------- /Demo/images/calypso.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/calypso.jpg -------------------------------------------------------------------------------- /Demo/images/caocao.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/caocao.jpg -------------------------------------------------------------------------------- /Demo/images/captainamerica.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/captainamerica.jpg -------------------------------------------------------------------------------- /Demo/images/chang.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/chang.jpg -------------------------------------------------------------------------------- /Demo/images/cheato.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/cheato.jpg -------------------------------------------------------------------------------- /Demo/images/cheshirecat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/cheshirecat.jpg -------------------------------------------------------------------------------- /Demo/images/daegon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/daegon.png -------------------------------------------------------------------------------- /Demo/images/dampe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/dampe.png -------------------------------------------------------------------------------- /Demo/images/danielcarrington.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/danielcarrington.jpg -------------------------------------------------------------------------------- /Demo/images/daniellang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/daniellang.png -------------------------------------------------------------------------------- /Demo/images/dansevern.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/dansevern.jpg -------------------------------------------------------------------------------- /Demo/images/darkman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/darkman.jpg -------------------------------------------------------------------------------- /Demo/images/darthvader.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/darthvader.jpg -------------------------------------------------------------------------------- /Demo/images/dingodile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/dingodile.png -------------------------------------------------------------------------------- /Demo/images/dmitripetrovic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/dmitripetrovic.png -------------------------------------------------------------------------------- /Demo/images/ebonroc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/ebonroc.png -------------------------------------------------------------------------------- /Demo/images/eccothedolphin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/eccothedolphin.png -------------------------------------------------------------------------------- /Demo/images/echidna.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/echidna.jpg -------------------------------------------------------------------------------- /Demo/images/edeakramer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/edeakramer.jpg -------------------------------------------------------------------------------- /Demo/images/edwardvanhelgen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/edwardvanhelgen.png -------------------------------------------------------------------------------- /Demo/images/elena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/elena.jpg -------------------------------------------------------------------------------- /Demo/images/eulogyjones.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/eulogyjones.jpg -------------------------------------------------------------------------------- /Demo/images/excellagionne.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/excellagionne.jpg -------------------------------------------------------------------------------- /Demo/images/ezekialfreeman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/ezekialfreeman.jpg -------------------------------------------------------------------------------- /Demo/images/fakeman.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/fakeman.jpg -------------------------------------------------------------------------------- /Demo/images/fasha.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/fasha.jpg -------------------------------------------------------------------------------- /Demo/images/fawful.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/fawful.jpg -------------------------------------------------------------------------------- /Demo/images/fergie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/fergie.jpg -------------------------------------------------------------------------------- /Demo/images/firebrand.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/firebrand.jpg -------------------------------------------------------------------------------- /Demo/images/freshprince.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/freshprince.jpg -------------------------------------------------------------------------------- /Demo/images/frylock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/frylock.jpg -------------------------------------------------------------------------------- /Demo/images/fyrus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/fyrus.jpg -------------------------------------------------------------------------------- /Demo/images/lamarr.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lamarr.jpg -------------------------------------------------------------------------------- /Demo/images/lazarus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lazarus.jpg -------------------------------------------------------------------------------- /Demo/images/lebronjames.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lebronjames.jpg -------------------------------------------------------------------------------- /Demo/images/leehong.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/leehong.jpg -------------------------------------------------------------------------------- /Demo/images/lemmykoopa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lemmykoopa.jpg -------------------------------------------------------------------------------- /Demo/images/leonbelmont.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/leonbelmont.jpg -------------------------------------------------------------------------------- /Demo/images/lewton.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lewton.jpg -------------------------------------------------------------------------------- /Demo/images/lexluthor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lexluthor.jpg -------------------------------------------------------------------------------- /Demo/images/lighter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lighter.jpg -------------------------------------------------------------------------------- /Demo/images/lulu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/lulu.jpg -------------------------------------------------------------------------------- /Demo/images/spinner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Demo/images/spinner.gif -------------------------------------------------------------------------------- /Demo/index.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | MooTools TextboxList Demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 62 | 63 | 64 | 80 | 81 | 82 |

TextboxList demo

83 |

Devthought project page (downloads, documentation)

84 | 85 |
86 |

TextboxList (standard)

87 |

Enter tags

88 |
89 |

Type the tag (one or more words) and press enter. Use left/right arrows, backspace, delete to navigate

90 | 91 |

Enter tags (with commas)

92 |
93 |

Type the tag (one or more words) and press comma (,). Use left/right arrows, backspace, delete to navigate

94 | 95 |

TextboxList.Autocomplete (values seeded all at once)

96 |

Select friends to email

97 |
98 | 99 |
100 |

Type the tag (one or more words) and press enter. Use left/right arrows, backspace, delete to navigate/remove boxes, and up/down/enter to navigate/add suggestions.

101 | 102 |

TextboxList.Autocomplete (values seeded on demand)

103 |

Select friends to email

104 |
105 | 106 |
107 |

Type the tag (one or more words) and press enter. Use left/right arrows, backspace, delete to navigate/remove boxes, and up/down/enter to navigate/add suggestions.

108 | 109 |

Test submit

110 |

111 | 112 |

Samples code

113 |

To view the implementation for these examples just use the View Source option in your browser

114 |

They're already documented, and resemble the most common implementations that you might need for your websites.

115 | 116 |

Read more

117 |

Please head to the article page for a complete explanation.

118 |
119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /Demo/mootools-1.2.1-core-yc.js: -------------------------------------------------------------------------------- 1 | //MooTools, , My Object Oriented (JavaScript) Tools. Copyright (c) 2006-2008 Valerio Proietti, , MIT Style License. 2 | 3 | var MooTools={version:"1.2.1",build:"0d4845aab3d9a4fdee2f0d4a6dd59210e4b697cf"};var Native=function(K){K=K||{};var A=K.name;var I=K.legacy;var B=K.protect; 4 | var C=K.implement;var H=K.generics;var F=K.initialize;var G=K.afterImplement||function(){};var D=F||I;H=H!==false;D.constructor=Native;D.$family={name:"native"}; 5 | if(I&&F){D.prototype=I.prototype;}D.prototype.constructor=D;if(A){var E=A.toLowerCase();D.prototype.$family={name:E};Native.typize(D,E);}var J=function(N,L,O,M){if(!B||M||!N.prototype[L]){N.prototype[L]=O; 6 | }if(H){Native.genericize(N,L,B);}G.call(N,L,O);return N;};D.alias=function(N,L,O){if(typeof N=="string"){if((N=this.prototype[N])){return J(this,L,N,O); 7 | }}for(var M in N){this.alias(M,N[M],L);}return this;};D.implement=function(M,L,O){if(typeof M=="string"){return J(this,M,L,O);}for(var N in M){J(this,N,M[N],L); 8 | }return this;};if(C){D.implement(C);}return D;};Native.genericize=function(B,C,A){if((!A||!B[C])&&typeof B.prototype[C]=="function"){B[C]=function(){var D=Array.prototype.slice.call(arguments); 9 | return B.prototype[C].apply(D.shift(),D);};}};Native.implement=function(D,C){for(var B=0,A=D.length;B-1:this.indexOf(A)>-1;},trim:function(){return this.replace(/^\s+|\s+$/g,"");},clean:function(){return this.replace(/\s+/g," ").trim(); 65 | },camelCase:function(){return this.replace(/-\D/g,function(A){return A.charAt(1).toUpperCase();});},hyphenate:function(){return this.replace(/[A-Z]/g,function(A){return("-"+A.charAt(0).toLowerCase()); 66 | });},capitalize:function(){return this.replace(/\b[a-z]/g,function(A){return A.toUpperCase();});},escapeRegExp:function(){return this.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1"); 67 | },toInt:function(A){return parseInt(this,A||10);},toFloat:function(){return parseFloat(this);},hexToRgb:function(B){var A=this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); 68 | return(A)?A.slice(1).hexToRgb(B):null;},rgbToHex:function(B){var A=this.match(/\d{1,3}/g);return(A)?A.rgbToHex(B):null;},stripScripts:function(B){var A=""; 69 | var C=this.replace(/]*>([\s\S]*?)<\/script>/gi,function(){A+=arguments[1]+"\n";return"";});if(B===true){$exec(A);}else{if($type(B)=="function"){B(A,C); 70 | }}return C;},substitute:function(A,B){return this.replace(B||(/\\?\{([^{}]+)\}/g),function(D,C){if(D.charAt(0)=="\\"){return D.slice(1);}return(A[C]!=undefined)?A[C]:""; 71 | });}});Hash.implement({has:Object.prototype.hasOwnProperty,keyOf:function(B){for(var A in this){if(this.hasOwnProperty(A)&&this[A]===B){return A;}}return null; 72 | },hasValue:function(A){return(Hash.keyOf(this,A)!==null);},extend:function(A){Hash.each(A,function(C,B){Hash.set(this,B,C);},this);return this;},combine:function(A){Hash.each(A,function(C,B){Hash.include(this,B,C); 73 | },this);return this;},erase:function(A){if(this.hasOwnProperty(A)){delete this[A];}return this;},get:function(A){return(this.hasOwnProperty(A))?this[A]:null; 74 | },set:function(A,B){if(!this[A]||this.hasOwnProperty(A)){this[A]=B;}return this;},empty:function(){Hash.each(this,function(B,A){delete this[A];},this); 75 | return this;},include:function(B,C){var A=this[B];if(A==undefined){this[B]=C;}return this;},map:function(B,C){var A=new Hash;Hash.each(this,function(E,D){A.set(D,B.call(C,E,D,this)); 76 | },this);return A;},filter:function(B,C){var A=new Hash;Hash.each(this,function(E,D){if(B.call(C,E,D,this)){A.set(D,E);}},this);return A;},every:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&!B.call(C,this[A],A)){return false; 77 | }}return true;},some:function(B,C){for(var A in this){if(this.hasOwnProperty(A)&&B.call(C,this[A],A)){return true;}}return false;},getKeys:function(){var A=[]; 78 | Hash.each(this,function(C,B){A.push(B);});return A;},getValues:function(){var A=[];Hash.each(this,function(B){A.push(B);});return A;},toQueryString:function(A){var B=[]; 79 | Hash.each(this,function(F,E){if(A){E=A+"["+E+"]";}var D;switch($type(F)){case"object":D=Hash.toQueryString(F,E);break;case"array":var C={};F.each(function(H,G){C[G]=H; 80 | });D=Hash.toQueryString(C,E);break;default:D=E+"="+encodeURIComponent(F);}if(F!=undefined){B.push(D);}});return B.join("&");}});Hash.alias({keyOf:"indexOf",hasValue:"contains"}); 81 | var Event=new Native({name:"Event",initialize:function(A,F){F=F||window;var K=F.document;A=A||F.event;if(A.$extended){return A;}this.$extended=true;var J=A.type; 82 | var G=A.target||A.srcElement;while(G&&G.nodeType==3){G=G.parentNode;}if(J.test(/key/)){var B=A.which||A.keyCode;var M=Event.Keys.keyOf(B);if(J=="keydown"){var D=B-111; 83 | if(D>0&&D<13){M="f"+D;}}M=M||String.fromCharCode(B).toLowerCase();}else{if(J.match(/(click|mouse|menu)/i)){K=(!K.compatMode||K.compatMode=="CSS1Compat")?K.html:K.body; 84 | var I={x:A.pageX||A.clientX+K.scrollLeft,y:A.pageY||A.clientY+K.scrollTop};var C={x:(A.pageX)?A.pageX-F.pageXOffset:A.clientX,y:(A.pageY)?A.pageY-F.pageYOffset:A.clientY}; 85 | if(J.match(/DOMMouseScroll|mousewheel/)){var H=(A.wheelDelta)?A.wheelDelta/120:-(A.detail||0)/3;}var E=(A.which==3)||(A.button==2);var L=null;if(J.match(/over|out/)){switch(J){case"mouseover":L=A.relatedTarget||A.fromElement; 86 | break;case"mouseout":L=A.relatedTarget||A.toElement;}if(!(function(){while(L&&L.nodeType==3){L=L.parentNode;}return true;}).create({attempt:Browser.Engine.gecko})()){L=false; 87 | }}}}return $extend(this,{event:A,type:J,page:I,client:C,rightClick:E,wheel:H,relatedTarget:L,target:G,code:B,key:M,shift:A.shiftKey,control:A.ctrlKey,alt:A.altKey,meta:A.metaKey}); 88 | }});Event.Keys=new Hash({enter:13,up:38,down:40,left:37,right:39,esc:27,space:32,backspace:8,tab:9,"delete":46});Event.implement({stop:function(){return this.stopPropagation().preventDefault(); 89 | },stopPropagation:function(){if(this.event.stopPropagation){this.event.stopPropagation();}else{this.event.cancelBubble=true;}return this;},preventDefault:function(){if(this.event.preventDefault){this.event.preventDefault(); 90 | }else{this.event.returnValue=false;}return this;}});var Class=new Native({name:"Class",initialize:function(B){B=B||{};var A=function(){for(var E in this){if($type(this[E])!="function"){this[E]=$unlink(this[E]); 91 | }}this.constructor=A;if(Class.prototyping){return this;}var D=(this.initialize)?this.initialize.apply(this,arguments):this;if(this.options&&this.options.initialize){this.options.initialize.call(this); 92 | }return D;};for(var C in Class.Mutators){if(!B[C]){continue;}B=Class.Mutators[C](B,B[C]);delete B[C];}$extend(A,this);A.constructor=Class;A.prototype=B; 93 | return A;}});Class.Mutators={Extends:function(C,A){Class.prototyping=A.prototype;var B=new A;delete B.parent;B=Class.inherit(B,C);delete Class.prototyping; 94 | return B;},Implements:function(A,B){$splat(B).each(function(C){Class.prototying=C;$extend(A,($type(C)=="class")?new C:C);delete Class.prototyping;});return A; 95 | }};Class.extend({inherit:function(B,E){var A=arguments.callee.caller;for(var D in E){var C=E[D];var G=B[D];var F=$type(C);if(G&&F=="function"){if(C!=G){if(A){C.__parent=G; 96 | B[D]=C;}else{Class.override(B,D,C);}}}else{if(F=="object"){B[D]=$merge(G,C);}else{B[D]=C;}}}if(A){B.parent=function(){return arguments.callee.caller.__parent.apply(this,arguments); 97 | };}return B;},override:function(B,A,E){var D=Class.prototyping;if(D&&B[A]!=D[A]){D=null;}var C=function(){var F=this.parent;this.parent=D?D[A]:B[A];var G=E.apply(this,arguments); 98 | this.parent=F;return G;};B[A]=C;}});Class.implement({implement:function(){var A=this.prototype;$each(arguments,function(B){Class.inherit(A,B);});return this; 99 | }});var Chain=new Class({$chain:[],chain:function(){this.$chain.extend(Array.flatten(arguments));return this;},callChain:function(){return(this.$chain.length)?this.$chain.shift().apply(this,arguments):false; 100 | },clearChain:function(){this.$chain.empty();return this;}});var Events=new Class({$events:{},addEvent:function(C,B,A){C=Events.removeOn(C);if(B!=$empty){this.$events[C]=this.$events[C]||[]; 101 | this.$events[C].include(B);if(A){B.internal=true;}}return this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this;},fireEvent:function(C,B,A){C=Events.removeOn(C); 102 | if(!this.$events||!this.$events[C]){return this;}this.$events[C].each(function(D){D.create({bind:this,delay:A,"arguments":B})();},this);return this;},removeEvent:function(B,A){B=Events.removeOn(B); 103 | if(!this.$events[B]){return this;}if(!A.internal){this.$events[B].erase(A);}return this;},removeEvents:function(C){if($type(C)=="object"){for(var D in C){this.removeEvent(D,C[D]); 104 | }return this;}if(C){C=Events.removeOn(C);}for(var D in this.$events){if(C&&C!=D){continue;}var B=this.$events[D];for(var A=B.length;A--;A){this.removeEvent(D,B[A]); 105 | }}return this;}});Events.removeOn=function(A){return A.replace(/^on([A-Z])/,function(B,C){return C.toLowerCase();});};var Options=new Class({setOptions:function(){this.options=$merge.run([this.options].extend(arguments)); 106 | if(!this.addEvent){return this;}for(var A in this.options){if($type(this.options[A])!="function"||!(/^on[A-Z]/).test(A)){continue;}this.addEvent(A,this.options[A]); 107 | delete this.options[A];}return this;}});var Element=new Native({name:"Element",legacy:window.Element,initialize:function(A,B){var C=Element.Constructors.get(A); 108 | if(C){return C(B);}if(typeof A=="string"){return document.newElement(A,B);}return $(A).set(B);},afterImplement:function(A,B){Element.Prototype[A]=B;if(Array[A]){return ; 109 | }Elements.implement(A,function(){var C=[],G=true;for(var E=0,D=this.length;E";}return $.element(this.createElement(A)).set(B);},newTextNode:function(A){return this.createTextNode(A); 118 | },getDocument:function(){return this;},getWindow:function(){return this.window;}});Window.implement({$:function(B,C){if(B&&B.$family&&B.uid){return B;}var A=$type(B); 119 | return($[A])?$[A](B,C,this.document):null;},$$:function(A){if(arguments.length==1&&typeof A=="string"){return this.document.getElements(A);}var F=[];var C=Array.flatten(arguments); 120 | for(var D=0,B=C.length;D1);A.each(function(E){var F=this.getElementsByTagName(E.trim());(B)?C.extend(F):C=F;},this);return new Elements(C,{ddup:B,cash:!D}); 126 | }});(function(){var H={},F={};var I={input:"checked",option:"selected",textarea:(Browser.Engine.webkit&&Browser.Engine.version<420)?"innerHTML":"value"}; 127 | var C=function(L){return(F[L]||(F[L]={}));};var G=function(N,L){if(!N){return ;}var M=N.uid;if(Browser.Engine.trident){if(N.clearAttributes){var P=L&&N.cloneNode(false); 128 | N.clearAttributes();if(P){N.mergeAttributes(P);}}else{if(N.removeEvents){N.removeEvents();}}if((/object/i).test(N.tagName)){for(var O in N){if(typeof N[O]=="function"){N[O]=$empty; 129 | }}Element.dispose(N);}}if(!M){return ;}H[M]=F[M]=null;};var D=function(){Hash.each(H,G);if(Browser.Engine.trident){$A(document.getElementsByTagName("object")).each(G); 130 | }if(window.CollectGarbage){CollectGarbage();}H=F=null;};var J=function(N,L,S,M,P,R){var O=N[S||L];var Q=[];while(O){if(O.nodeType==1&&(!M||Element.match(O,M))){if(!P){return $(O,R); 131 | }Q.push(O);}O=O[L];}return(P)?new Elements(Q,{ddup:false,cash:!R}):null;};var E={html:"innerHTML","class":"className","for":"htmlFor",text:(Browser.Engine.trident||(Browser.Engine.webkit&&Browser.Engine.version<420))?"innerText":"textContent"}; 132 | var B=["compact","nowrap","ismap","declare","noshade","checked","disabled","readonly","multiple","selected","noresize","defer"];var K=["value","accessKey","cellPadding","cellSpacing","colSpan","frameBorder","maxLength","readOnly","rowSpan","tabIndex","useMap"]; 133 | Hash.extend(E,B.associate(B));Hash.extend(E,K.associate(K.map(String.toLowerCase)));var A={before:function(M,L){if(L.parentNode){L.parentNode.insertBefore(M,L); 134 | }},after:function(M,L){if(!L.parentNode){return ;}var N=L.nextSibling;(N)?L.parentNode.insertBefore(M,N):L.parentNode.appendChild(M);},bottom:function(M,L){L.appendChild(M); 135 | },top:function(M,L){var N=L.firstChild;(N)?L.insertBefore(M,N):L.appendChild(M);}};A.inside=A.bottom;Hash.each(A,function(L,M){M=M.capitalize();Element.implement("inject"+M,function(N){L(this,$(N,true)); 136 | return this;});Element.implement("grab"+M,function(N){L($(N,true),this);return this;});});Element.implement({set:function(O,M){switch($type(O)){case"object":for(var N in O){this.set(N,O[N]); 137 | }break;case"string":var L=Element.Properties.get(O);(L&&L.set)?L.set.apply(this,Array.slice(arguments,1)):this.setProperty(O,M);}return this;},get:function(M){var L=Element.Properties.get(M); 138 | return(L&&L.get)?L.get.apply(this,Array.slice(arguments,1)):this.getProperty(M);},erase:function(M){var L=Element.Properties.get(M);(L&&L.erase)?L.erase.apply(this):this.removeProperty(M); 139 | return this;},setProperty:function(M,N){var L=E[M];if(N==undefined){return this.removeProperty(M);}if(L&&B[M]){N=!!N;}(L)?this[L]=N:this.setAttribute(M,""+N); 140 | return this;},setProperties:function(L){for(var M in L){this.setProperty(M,L[M]);}return this;},getProperty:function(M){var L=E[M];var N=(L)?this[L]:this.getAttribute(M,2); 141 | return(B[M])?!!N:(L)?N:N||null;},getProperties:function(){var L=$A(arguments);return L.map(this.getProperty,this).associate(L);},removeProperty:function(M){var L=E[M]; 142 | (L)?this[L]=(L&&B[M])?false:"":this.removeAttribute(M);return this;},removeProperties:function(){Array.each(arguments,this.removeProperty,this);return this; 143 | },hasClass:function(L){return this.className.contains(L," ");},addClass:function(L){if(!this.hasClass(L)){this.className=(this.className+" "+L).clean(); 144 | }return this;},removeClass:function(L){this.className=this.className.replace(new RegExp("(^|\\s)"+L+"(?:\\s|$)"),"$1");return this;},toggleClass:function(L){return this.hasClass(L)?this.removeClass(L):this.addClass(L); 145 | },adopt:function(){Array.flatten(arguments).each(function(L){L=$(L,true);if(L){this.appendChild(L);}},this);return this;},appendText:function(M,L){return this.grab(this.getDocument().newTextNode(M),L); 146 | },grab:function(M,L){A[L||"bottom"]($(M,true),this);return this;},inject:function(M,L){A[L||"bottom"](this,$(M,true));return this;},replaces:function(L){L=$(L,true); 147 | L.parentNode.replaceChild(this,L);return this;},wraps:function(M,L){M=$(M,true);return this.replaces(M).grab(M,L);},getPrevious:function(L,M){return J(this,"previousSibling",null,L,false,M); 148 | },getAllPrevious:function(L,M){return J(this,"previousSibling",null,L,true,M);},getNext:function(L,M){return J(this,"nextSibling",null,L,false,M);},getAllNext:function(L,M){return J(this,"nextSibling",null,L,true,M); 149 | },getFirst:function(L,M){return J(this,"nextSibling","firstChild",L,false,M);},getLast:function(L,M){return J(this,"previousSibling","lastChild",L,false,M); 150 | },getParent:function(L,M){return J(this,"parentNode",null,L,false,M);},getParents:function(L,M){return J(this,"parentNode",null,L,true,M);},getChildren:function(L,M){return J(this,"nextSibling","firstChild",L,true,M); 151 | },getWindow:function(){return this.ownerDocument.window;},getDocument:function(){return this.ownerDocument;},getElementById:function(O,N){var M=this.ownerDocument.getElementById(O); 152 | if(!M){return null;}for(var L=M.parentNode;L!=this;L=L.parentNode){if(!L){return null;}}return $.element(M,N);},getSelected:function(){return new Elements($A(this.options).filter(function(L){return L.selected; 153 | }));},getComputedStyle:function(M){if(this.currentStyle){return this.currentStyle[M.camelCase()];}var L=this.getDocument().defaultView.getComputedStyle(this,null); 154 | return(L)?L.getPropertyValue([M.hyphenate()]):null;},toQueryString:function(){var L=[];this.getElements("input, select, textarea",true).each(function(M){if(!M.name||M.disabled){return ; 155 | }var N=(M.tagName.toLowerCase()=="select")?Element.getSelected(M).map(function(O){return O.value;}):((M.type=="radio"||M.type=="checkbox")&&!M.checked)?null:M.value; 156 | $splat(N).each(function(O){if(typeof O!="undefined"){L.push(M.name+"="+encodeURIComponent(O));}});});return L.join("&");},clone:function(O,L){O=O!==false; 157 | var R=this.cloneNode(O);var N=function(V,U){if(!L){V.removeAttribute("id");}if(Browser.Engine.trident){V.clearAttributes();V.mergeAttributes(U);V.removeAttribute("uid"); 158 | if(V.options){var W=V.options,S=U.options;for(var T=W.length;T--;){W[T].selected=S[T].selected;}}}var X=I[U.tagName.toLowerCase()];if(X&&U[X]){V[X]=U[X]; 159 | }};if(O){var P=R.getElementsByTagName("*"),Q=this.getElementsByTagName("*");for(var M=P.length;M--;){N(P[M],Q[M]);}}N(R,this);return $(R);},destroy:function(){Element.empty(this); 160 | Element.dispose(this);G(this,true);return null;},empty:function(){$A(this.childNodes).each(function(L){Element.destroy(L);});return this;},dispose:function(){return(this.parentNode)?this.parentNode.removeChild(this):this; 161 | },hasChild:function(L){L=$(L,true);if(!L){return false;}if(Browser.Engine.webkit&&Browser.Engine.version<420){return $A(this.getElementsByTagName(L.tagName)).contains(L); 162 | }return(this.contains)?(this!=L&&this.contains(L)):!!(this.compareDocumentPosition(L)&16);},match:function(L){return(!L||(L==this)||(Element.get(this,"tag")==L)); 163 | }});Native.implement([Element,Window,Document],{addListener:function(O,N){if(O=="unload"){var L=N,M=this;N=function(){M.removeListener("unload",N);L(); 164 | };}else{H[this.uid]=this;}if(this.addEventListener){this.addEventListener(O,N,false);}else{this.attachEvent("on"+O,N);}return this;},removeListener:function(M,L){if(this.removeEventListener){this.removeEventListener(M,L,false); 165 | }else{this.detachEvent("on"+M,L);}return this;},retrieve:function(M,L){var O=C(this.uid),N=O[M];if(L!=undefined&&N==undefined){N=O[M]=L;}return $pick(N); 166 | },store:function(M,L){var N=C(this.uid);N[M]=L;return this;},eliminate:function(L){var M=C(this.uid);delete M[L];return this;}});window.addListener("unload",D); 167 | })();Element.Properties=new Hash;Element.Properties.style={set:function(A){this.style.cssText=A;},get:function(){return this.style.cssText;},erase:function(){this.style.cssText=""; 168 | }};Element.Properties.tag={get:function(){return this.tagName.toLowerCase();}};Element.Properties.html=(function(){var C=document.createElement("div"); 169 | var A={table:[1,"","
"],select:[1,""],tbody:[2,"","
"],tr:[3,"","
"]}; 170 | A.thead=A.tfoot=A.tbody;var B={set:function(){var E=Array.flatten(arguments).join("");var F=Browser.Engine.trident&&A[this.get("tag")];if(F){var G=C;G.innerHTML=F[1]+E+F[2]; 171 | for(var D=F[0];D--;){G=G.firstChild;}this.empty().adopt(G.childNodes);}else{this.innerHTML=E;}}};B.erase=B.set;return B;})();if(Browser.Engine.webkit&&Browser.Engine.version<420){Element.Properties.text={get:function(){if(this.innerText){return this.innerText; 172 | }var A=this.ownerDocument.newElement("div",{html:this.innerHTML}).inject(this.ownerDocument.body);var B=A.innerText;A.destroy();return B;}};}Element.Properties.events={set:function(A){this.addEvents(A); 173 | }};Native.implement([Element,Window,Document],{addEvent:function(E,G){var H=this.retrieve("events",{});H[E]=H[E]||{keys:[],values:[]};if(H[E].keys.contains(G)){return this; 174 | }H[E].keys.push(G);var F=E,A=Element.Events.get(E),C=G,I=this;if(A){if(A.onAdd){A.onAdd.call(this,G);}if(A.condition){C=function(J){if(A.condition.call(this,J)){return G.call(this,J); 175 | }return true;};}F=A.base||F;}var D=function(){return G.call(I);};var B=Element.NativeEvents[F];if(B){if(B==2){D=function(J){J=new Event(J,I.getWindow()); 176 | if(C.call(I,J)===false){J.stop();}};}this.addListener(F,D);}H[E].values.push(D);return this;},removeEvent:function(C,B){var A=this.retrieve("events");if(!A||!A[C]){return this; 177 | }var F=A[C].keys.indexOf(B);if(F==-1){return this;}A[C].keys.splice(F,1);var E=A[C].values.splice(F,1)[0];var D=Element.Events.get(C);if(D){if(D.onRemove){D.onRemove.call(this,B); 178 | }C=D.base||C;}return(Element.NativeEvents[C])?this.removeListener(C,E):this;},addEvents:function(A){for(var B in A){this.addEvent(B,A[B]);}return this; 179 | },removeEvents:function(A){if($type(A)=="object"){for(var C in A){this.removeEvent(C,A[C]);}return this;}var B=this.retrieve("events");if(!B){return this; 180 | }if(!A){for(var C in B){this.removeEvents(C);}this.eliminate("events");}else{if(B[A]){while(B[A].keys[0]){this.removeEvent(A,B[A].keys[0]);}B[A]=null;}}return this; 181 | },fireEvent:function(D,B,A){var C=this.retrieve("events");if(!C||!C[D]){return this;}C[D].keys.each(function(E){E.create({bind:this,delay:A,"arguments":B})(); 182 | },this);return this;},cloneEvents:function(D,A){D=$(D);var C=D.retrieve("events");if(!C){return this;}if(!A){for(var B in C){this.cloneEvents(D,B);}}else{if(C[A]){C[A].keys.each(function(E){this.addEvent(A,E); 183 | },this);}}return this;}});Element.NativeEvents={click:2,dblclick:2,mouseup:2,mousedown:2,contextmenu:2,mousewheel:2,DOMMouseScroll:2,mouseover:2,mouseout:2,mousemove:2,selectstart:2,selectend:2,keydown:2,keypress:2,keyup:2,focus:2,blur:2,change:2,reset:2,select:2,submit:2,load:1,unload:1,beforeunload:2,resize:1,move:1,DOMContentLoaded:1,readystatechange:1,error:1,abort:1,scroll:1}; 184 | (function(){var A=function(B){var C=B.relatedTarget;if(C==undefined){return true;}if(C===false){return false;}return($type(this)!="document"&&C!=this&&C.prefix!="xul"&&!this.hasChild(C)); 185 | };Element.Events=new Hash({mouseenter:{base:"mouseover",condition:A},mouseleave:{base:"mouseout",condition:A},mousewheel:{base:(Browser.Engine.gecko)?"DOMMouseScroll":"mousewheel"}}); 186 | })();Element.Properties.styles={set:function(A){this.setStyles(A);}};Element.Properties.opacity={set:function(A,B){if(!B){if(A==0){if(this.style.visibility!="hidden"){this.style.visibility="hidden"; 187 | }}else{if(this.style.visibility!="visible"){this.style.visibility="visible";}}}if(!this.currentStyle||!this.currentStyle.hasLayout){this.style.zoom=1;}if(Browser.Engine.trident){this.style.filter=(A==1)?"":"alpha(opacity="+A*100+")"; 188 | }this.style.opacity=A;this.store("opacity",A);},get:function(){return this.retrieve("opacity",1);}};Element.implement({setOpacity:function(A){return this.set("opacity",A,true); 189 | },getOpacity:function(){return this.get("opacity");},setStyle:function(B,A){switch(B){case"opacity":return this.set("opacity",parseFloat(A));case"float":B=(Browser.Engine.trident)?"styleFloat":"cssFloat"; 190 | }B=B.camelCase();if($type(A)!="string"){var C=(Element.Styles.get(B)||"@").split(" ");A=$splat(A).map(function(E,D){if(!C[D]){return"";}return($type(E)=="number")?C[D].replace("@",Math.round(E)):E; 191 | }).join(" ");}else{if(A==String(Number(A))){A=Math.round(A);}}this.style[B]=A;return this;},getStyle:function(G){switch(G){case"opacity":return this.get("opacity"); 192 | case"float":G=(Browser.Engine.trident)?"styleFloat":"cssFloat";}G=G.camelCase();var A=this.style[G];if(!$chk(A)){A=[];for(var F in Element.ShortStyles){if(G!=F){continue; 193 | }for(var E in Element.ShortStyles[F]){A.push(this.getStyle(E));}return A.join(" ");}A=this.getComputedStyle(G);}if(A){A=String(A);var C=A.match(/rgba?\([\d\s,]+\)/); 194 | if(C){A=A.replace(C[0],C[0].rgbToHex());}}if(Browser.Engine.presto||(Browser.Engine.trident&&!$chk(parseInt(A)))){if(G.test(/^(height|width)$/)){var B=(G=="width")?["left","right"]:["top","bottom"],D=0; 195 | B.each(function(H){D+=this.getStyle("border-"+H+"-width").toInt()+this.getStyle("padding-"+H).toInt();},this);return this["offset"+G.capitalize()]-D+"px"; 196 | }if((Browser.Engine.presto)&&String(A).test("px")){return A;}if(G.test(/(border(.+)Width|margin|padding)/)){return"0px";}}return A;},setStyles:function(B){for(var A in B){this.setStyle(A,B[A]); 197 | }return this;},getStyles:function(){var A={};Array.each(arguments,function(B){A[B]=this.getStyle(B);},this);return A;}});Element.Styles=new Hash({left:"@px",top:"@px",bottom:"@px",right:"@px",width:"@px",height:"@px",maxWidth:"@px",maxHeight:"@px",minWidth:"@px",minHeight:"@px",backgroundColor:"rgb(@, @, @)",backgroundPosition:"@px @px",color:"rgb(@, @, @)",fontSize:"@px",letterSpacing:"@px",lineHeight:"@px",clip:"rect(@px @px @px @px)",margin:"@px @px @px @px",padding:"@px @px @px @px",border:"@px @ rgb(@, @, @) @px @ rgb(@, @, @) @px @ rgb(@, @, @)",borderWidth:"@px @px @px @px",borderStyle:"@ @ @ @",borderColor:"rgb(@, @, @) rgb(@, @, @) rgb(@, @, @) rgb(@, @, @)",zIndex:"@",zoom:"@",fontWeight:"@",textIndent:"@px",opacity:"@"}); 198 | Element.ShortStyles={margin:{},padding:{},border:{},borderWidth:{},borderStyle:{},borderColor:{}};["Top","Right","Bottom","Left"].each(function(G){var F=Element.ShortStyles; 199 | var B=Element.Styles;["margin","padding"].each(function(H){var I=H+G;F[H][I]=B[I]="@px";});var E="border"+G;F.border[E]=B[E]="@px @ rgb(@, @, @)";var D=E+"Width",A=E+"Style",C=E+"Color"; 200 | F[E]={};F.borderWidth[D]=F[E][D]=B[D]="@px";F.borderStyle[A]=F[E][A]=B[A]="@";F.borderColor[C]=F[E][C]=B[C]="rgb(@, @, @)";});(function(){Element.implement({scrollTo:function(H,I){if(B(this)){this.getWindow().scrollTo(H,I); 201 | }else{this.scrollLeft=H;this.scrollTop=I;}return this;},getSize:function(){if(B(this)){return this.getWindow().getSize();}return{x:this.offsetWidth,y:this.offsetHeight}; 202 | },getScrollSize:function(){if(B(this)){return this.getWindow().getScrollSize();}return{x:this.scrollWidth,y:this.scrollHeight};},getScroll:function(){if(B(this)){return this.getWindow().getScroll(); 203 | }return{x:this.scrollLeft,y:this.scrollTop};},getScrolls:function(){var I=this,H={x:0,y:0};while(I&&!B(I)){H.x+=I.scrollLeft;H.y+=I.scrollTop;I=I.parentNode; 204 | }return H;},getOffsetParent:function(){var H=this;if(B(H)){return null;}if(!Browser.Engine.trident){return H.offsetParent;}while((H=H.parentNode)&&!B(H)){if(D(H,"position")!="static"){return H; 205 | }}return null;},getOffsets:function(){if(Browser.Engine.trident){var L=this.getBoundingClientRect(),J=this.getDocument().documentElement;return{x:L.left+J.scrollLeft-J.clientLeft,y:L.top+J.scrollTop-J.clientTop}; 206 | }var I=this,H={x:0,y:0};if(B(this)){return H;}while(I&&!B(I)){H.x+=I.offsetLeft;H.y+=I.offsetTop;if(Browser.Engine.gecko){if(!F(I)){H.x+=C(I);H.y+=G(I); 207 | }var K=I.parentNode;if(K&&D(K,"overflow")!="visible"){H.x+=C(K);H.y+=G(K);}}else{if(I!=this&&Browser.Engine.webkit){H.x+=C(I);H.y+=G(I);}}I=I.offsetParent; 208 | }if(Browser.Engine.gecko&&!F(this)){H.x-=C(this);H.y-=G(this);}return H;},getPosition:function(K){if(B(this)){return{x:0,y:0};}var L=this.getOffsets(),I=this.getScrolls(); 209 | var H={x:L.x-I.x,y:L.y-I.y};var J=(K&&(K=$(K)))?K.getPosition():{x:0,y:0};return{x:H.x-J.x,y:H.y-J.y};},getCoordinates:function(J){if(B(this)){return this.getWindow().getCoordinates(); 210 | }var H=this.getPosition(J),I=this.getSize();var K={left:H.x,top:H.y,width:I.x,height:I.y};K.right=K.left+K.width;K.bottom=K.top+K.height;return K;},computePosition:function(H){return{left:H.x-E(this,"margin-left"),top:H.y-E(this,"margin-top")}; 211 | },position:function(H){return this.setStyles(this.computePosition(H));}});Native.implement([Document,Window],{getSize:function(){var I=this.getWindow(); 212 | if(Browser.Engine.presto||Browser.Engine.webkit){return{x:I.innerWidth,y:I.innerHeight};}var H=A(this);return{x:H.clientWidth,y:H.clientHeight};},getScroll:function(){var I=this.getWindow(); 213 | var H=A(this);return{x:I.pageXOffset||H.scrollLeft,y:I.pageYOffset||H.scrollTop};},getScrollSize:function(){var I=A(this);var H=this.getSize();return{x:Math.max(I.scrollWidth,H.x),y:Math.max(I.scrollHeight,H.y)}; 214 | },getPosition:function(){return{x:0,y:0};},getCoordinates:function(){var H=this.getSize();return{top:0,left:0,bottom:H.y,right:H.x,height:H.y,width:H.x}; 215 | }});var D=Element.getComputedStyle;function E(H,I){return D(H,I).toInt()||0;}function F(H){return D(H,"-moz-box-sizing")=="border-box";}function G(H){return E(H,"border-top-width"); 216 | }function C(H){return E(H,"border-left-width");}function B(H){return(/^(?:body|html)$/i).test(H.tagName);}function A(H){var I=H.getDocument();return(!I.compatMode||I.compatMode=="CSS1Compat")?I.html:I.body; 217 | }})();Native.implement([Window,Document,Element],{getHeight:function(){return this.getSize().y;},getWidth:function(){return this.getSize().x;},getScrollTop:function(){return this.getScroll().y; 218 | },getScrollLeft:function(){return this.getScroll().x;},getScrollHeight:function(){return this.getScrollSize().y;},getScrollWidth:function(){return this.getScrollSize().x; 219 | },getTop:function(){return this.getPosition().y;},getLeft:function(){return this.getPosition().x;}});Native.implement([Document,Element],{getElements:function(H,G){H=H.split(","); 220 | var C,E={};for(var D=0,B=H.length;D1),cash:!G});}});Element.implement({match:function(B){if(!B||(B==this)){return true;}var D=Selectors.Utils.parseTagAndID(B); 222 | var A=D[0],E=D[1];if(!Selectors.Filters.byID(this,E)||!Selectors.Filters.byTag(this,A)){return false;}var C=Selectors.Utils.parseSelector(B);return(C)?Selectors.Utils.filter(this,C,{}):true; 223 | }});var Selectors={Cache:{nth:{},parsed:{}}};Selectors.RegExps={id:(/#([\w-]+)/),tag:(/^(\w+|\*)/),quick:(/^(\w+|\*)$/),splitter:(/\s*([+>~\s])\s*([a-zA-Z#.*:\[])/g),combined:(/\.([\w-]+)|\[(\w+)(?:([!*^$~|]?=)(["']?)([^\4]*?)\4)?\]|:([\w-]+)(?:\(["']?(.*?)?["']?\)|$)/g)}; 224 | Selectors.Utils={chk:function(B,C){if(!C){return true;}var A=$uid(B);if(!C[A]){return C[A]=true;}return false;},parseNthArgument:function(F){if(Selectors.Cache.nth[F]){return Selectors.Cache.nth[F]; 225 | }var C=F.match(/^([+-]?\d*)?([a-z]+)?([+-]?\d*)?$/);if(!C){return false;}var E=parseInt(C[1]);var B=(E||E===0)?E:1;var D=C[2]||false;var A=parseInt(C[3])||0; 226 | if(B!=0){A--;while(A<1){A+=B;}while(A>=B){A-=B;}}else{B=A;D="index";}switch(D){case"n":C={a:B,b:A,special:"n"};break;case"odd":C={a:2,b:0,special:"n"}; 227 | break;case"even":C={a:2,b:1,special:"n"};break;case"first":C={a:0,special:"index"};break;case"last":C={special:"last-child"};break;case"only":C={special:"only-child"}; 228 | break;default:C={a:(B-1),special:"index"};}return Selectors.Cache.nth[F]=C;},parseSelector:function(E){if(Selectors.Cache.parsed[E]){return Selectors.Cache.parsed[E]; 229 | }var D,H={classes:[],pseudos:[],attributes:[]};while((D=Selectors.RegExps.combined.exec(E))){var I=D[1],G=D[2],F=D[3],B=D[5],C=D[6],J=D[7];if(I){H.classes.push(I); 230 | }else{if(C){var A=Selectors.Pseudo.get(C);if(A){H.pseudos.push({parser:A,argument:J});}else{H.attributes.push({name:C,operator:"=",value:J});}}else{if(G){H.attributes.push({name:G,operator:F,value:B}); 231 | }}}}if(!H.classes.length){delete H.classes;}if(!H.attributes.length){delete H.attributes;}if(!H.pseudos.length){delete H.pseudos;}if(!H.classes&&!H.attributes&&!H.pseudos){H=null; 232 | }return Selectors.Cache.parsed[E]=H;},parseTagAndID:function(B){var A=B.match(Selectors.RegExps.tag);var C=B.match(Selectors.RegExps.id);return[(A)?A[1]:"*",(C)?C[1]:false]; 233 | },filter:function(F,C,E){var D;if(C.classes){for(D=C.classes.length;D--;D){var G=C.classes[D];if(!Selectors.Filters.byClass(F,G)){return false;}}}if(C.attributes){for(D=C.attributes.length; 234 | D--;D){var B=C.attributes[D];if(!Selectors.Filters.byAttribute(F,B.name,B.operator,B.value)){return false;}}}if(C.pseudos){for(D=C.pseudos.length;D--;D){var A=C.pseudos[D]; 235 | if(!Selectors.Filters.byPseudo(F,A.parser,A.argument,E)){return false;}}}return true;},getByTagAndID:function(B,A,D){if(D){var C=(B.getElementById)?B.getElementById(D,true):Element.getElementById(B,D,true); 236 | return(C&&Selectors.Filters.byTag(C,A))?[C]:[];}else{return B.getElementsByTagName(A);}},search:function(I,H,N){var B=[];var C=H.trim().replace(Selectors.RegExps.splitter,function(Y,X,W){B.push(X); 237 | return":)"+W;}).split(":)");var J,E,U;for(var T=0,P=C.length;T":function(H,G,I,A,F){var C=Selectors.Utils.getByTagAndID(G,I,A);for(var E=0,D=C.length;EA){return false;}}return(C==A);},even:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n+1",A); 255 | },odd:function(B,A){return Selectors.Pseudo["nth-child"].call(this,"2n",A);}});Element.Events.domready={onAdd:function(A){if(Browser.loaded){A.call(this); 256 | }}};(function(){var B=function(){if(Browser.loaded){return ;}Browser.loaded=true;window.fireEvent("domready");document.fireEvent("domready");};if(Browser.Engine.trident){var A=document.createElement("div"); 257 | (function(){($try(function(){A.doScroll("left");return $(A).inject(document.body).set("html","temp").dispose();}))?B():arguments.callee.delay(50);})(); 258 | }else{if(Browser.Engine.webkit&&Browser.Engine.version<525){(function(){(["loaded","complete"].contains(document.readyState))?B():arguments.callee.delay(50); 259 | })();}else{window.addEvent("load",B);document.addEvent("DOMContentLoaded",B);}}})();var JSON=new Hash({$specialChars:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},$replaceChars:function(A){return JSON.$specialChars[A]||"\\u00"+Math.floor(A.charCodeAt()/16).toString(16)+(A.charCodeAt()%16).toString(16); 260 | },encode:function(B){switch($type(B)){case"string":return'"'+B.replace(/[\x00-\x1f\\"]/g,JSON.$replaceChars)+'"';case"array":return"["+String(B.map(JSON.encode).filter($defined))+"]"; 261 | case"object":case"hash":var A=[];Hash.each(B,function(E,D){var C=JSON.encode(E);if(C){A.push(JSON.encode(D)+":"+C);}});return"{"+A+"}";case"number":case"boolean":return String(B); 262 | case false:return"null";}return null;},decode:function(string,secure){if($type(string)!="string"||!string.length){return null;}if(secure&&!(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(string.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,""))){return null; 263 | }return eval("("+string+")");}});Native.implement([Hash,Array,String,Number],{toJSON:function(){return JSON.encode(this);}});var Cookie=new Class({Implements:Options,options:{path:false,domain:false,duration:false,secure:false,document:document},initialize:function(B,A){this.key=B; 264 | this.setOptions(A);},write:function(B){B=encodeURIComponent(B);if(this.options.domain){B+="; domain="+this.options.domain;}if(this.options.path){B+="; path="+this.options.path; 265 | }if(this.options.duration){var A=new Date();A.setTime(A.getTime()+this.options.duration*24*60*60*1000);B+="; expires="+A.toGMTString();}if(this.options.secure){B+="; secure"; 266 | }this.options.document.cookie=this.key+"="+B;return this;},read:function(){var A=this.options.document.cookie.match("(?:^|;)\\s*"+this.key.escapeRegExp()+"=([^;]*)"); 267 | return(A)?decodeURIComponent(A[1]):null;},dispose:function(){new Cookie(this.key,$merge(this.options,{duration:-1})).write("");return this;}});Cookie.write=function(B,C,A){return new Cookie(B,A).write(C); 268 | };Cookie.read=function(A){return new Cookie(A).read();};Cookie.dispose=function(B,A){return new Cookie(B,A).dispose();};var Swiff=new Class({Implements:[Options],options:{id:null,height:1,width:1,container:null,properties:{},params:{quality:"high",allowScriptAccess:"always",wMode:"transparent",swLiveConnect:true},callBacks:{},vars:{}},toElement:function(){return this.object; 269 | },initialize:function(L,M){this.instance="Swiff_"+$time();this.setOptions(M);M=this.options;var B=this.id=M.id||this.instance;var A=$(M.container);Swiff.CallBacks[this.instance]={}; 270 | var E=M.params,G=M.vars,F=M.callBacks;var H=$extend({height:M.height,width:M.width},M.properties);var K=this;for(var D in F){Swiff.CallBacks[this.instance][D]=(function(N){return function(){return N.apply(K.object,arguments); 271 | };})(F[D]);G[D]="Swiff.CallBacks."+this.instance+"."+D;}E.flashVars=Hash.toQueryString(G);if(Browser.Engine.trident){H.classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"; 272 | E.movie=L;}else{H.type="application/x-shockwave-flash";H.data=L;}var J=''; 273 | }}J+="";this.object=((A)?A.empty():new Element("div")).set("html",J).firstChild;},replaces:function(A){A=$(A,true);A.parentNode.replaceChild(this.toElement(),A); 274 | return this;},inject:function(A){$(A,true).appendChild(this.toElement());return this;},remote:function(){return Swiff.remote.apply(Swiff,[this.toElement()].extend(arguments)); 275 | }});Swiff.CallBacks={};Swiff.remote=function(obj,fn){var rs=obj.CallFunction(''+__flash__argumentsToXML(arguments,2)+""); 276 | return eval(rs);};var Fx=new Class({Implements:[Chain,Events,Options],options:{fps:50,unit:false,duration:500,link:"ignore"},initialize:function(A){this.subject=this.subject||this; 277 | this.setOptions(A);this.options.duration=Fx.Durations[this.options.duration]||this.options.duration.toInt();var B=this.options.wait;if(B===false){this.options.link="cancel"; 278 | }},getTransition:function(){return function(A){return -(Math.cos(Math.PI*A)-1)/2;};},step:function(){var A=$time();if(A=(7-4*B)/11){C=A*A-Math.pow((11-6*B-11*D)/4,2); 318 | break;}}return C;},Elastic:function(B,A){return Math.pow(2,10*--B)*Math.cos(20*B*Math.PI*(A[0]||1)/3);}});["Quad","Cubic","Quart","Quint"].each(function(B,A){Fx.Transitions[B]=new Fx.Transition(function(C){return Math.pow(C,[A+2]); 319 | });});var Request=new Class({Implements:[Chain,Events,Options],options:{url:"",data:"",headers:{"X-Requested-With":"XMLHttpRequest",Accept:"text/javascript, text/html, application/xml, text/xml, */*"},async:true,format:false,method:"post",link:"ignore",isSuccess:null,emulation:true,urlEncoded:true,encoding:"utf-8",evalScripts:false,evalResponse:false},initialize:function(A){this.xhr=new Browser.Request(); 320 | this.setOptions(A);this.options.isSuccess=this.options.isSuccess||this.isSuccess;this.headers=new Hash(this.options.headers);},onStateChange:function(){if(this.xhr.readyState!=4||!this.running){return ; 321 | }this.running=false;this.status=0;$try(function(){this.status=this.xhr.status;}.bind(this));if(this.options.isSuccess.call(this,this.status)){this.response={text:this.xhr.responseText,xml:this.xhr.responseXML}; 322 | this.success(this.response.text,this.response.xml);}else{this.response={text:null,xml:null};this.failure();}this.xhr.onreadystatechange=$empty;},isSuccess:function(){return((this.status>=200)&&(this.status<300)); 323 | },processScripts:function(A){if(this.options.evalResponse||(/(ecma|java)script/).test(this.getHeader("Content-type"))){return $exec(A);}return A.stripScripts(this.options.evalScripts); 324 | },success:function(B,A){this.onSuccess(this.processScripts(B),A);},onSuccess:function(){this.fireEvent("complete",arguments).fireEvent("success",arguments).callChain(); 325 | },failure:function(){this.onFailure();},onFailure:function(){this.fireEvent("complete").fireEvent("failure",this.xhr);},setHeader:function(A,B){this.headers.set(A,B); 326 | return this;},getHeader:function(A){return $try(function(){return this.xhr.getResponseHeader(A);}.bind(this));},check:function(A){if(!this.running){return true; 327 | }switch(this.options.link){case"cancel":this.cancel();return true;case"chain":this.chain(A.bind(this,Array.slice(arguments,1)));return false;}return false; 328 | },send:function(I){if(!this.check(arguments.callee,I)){return this;}this.running=true;var G=$type(I);if(G=="string"||G=="element"){I={data:I};}var D=this.options; 329 | I=$extend({data:D.data,url:D.url,method:D.method},I);var E=I.data,B=I.url,A=I.method;switch($type(E)){case"element":E=$(E).toQueryString();break;case"object":case"hash":E=Hash.toQueryString(E); 330 | }if(this.options.format){var H="format="+this.options.format;E=(E)?H+"&"+E:H;}if(this.options.emulation&&["put","delete"].contains(A)){var F="_method="+A; 331 | E=(E)?F+"&"+E:F;A="post";}if(this.options.urlEncoded&&A=="post"){var C=(this.options.encoding)?"; charset="+this.options.encoding:"";this.headers.set("Content-type","application/x-www-form-urlencoded"+C); 332 | }if(E&&A=="get"){B=B+(B.contains("?")?"&":"?")+E;E=null;}this.xhr.open(A.toUpperCase(),B,this.options.async);this.xhr.onreadystatechange=this.onStateChange.bind(this); 333 | this.headers.each(function(K,J){try{this.xhr.setRequestHeader(J,K);}catch(L){this.fireEvent("exception",[J,K]);}},this);this.fireEvent("request");this.xhr.send(E); 334 | if(!this.options.async){this.onStateChange();}return this;},cancel:function(){if(!this.running){return this;}this.running=false;this.xhr.abort();this.xhr.onreadystatechange=$empty; 335 | this.xhr=new Browser.Request();this.fireEvent("cancel");return this;}});(function(){var A={};["get","post","put","delete","GET","POST","PUT","DELETE"].each(function(B){A[B]=function(){var C=Array.link(arguments,{url:String.type,data:$defined}); 336 | return this.send($extend(C,{method:B.toLowerCase()}));};});Request.implement(A);})();Element.Properties.send={set:function(A){var B=this.retrieve("send"); 337 | if(B){B.cancel();}return this.eliminate("send").store("send:options",$extend({data:this,link:"cancel",method:this.get("method")||"post",url:this.get("action")},A)); 338 | },get:function(A){if(A||!this.retrieve("send")){if(A||!this.retrieve("send:options")){this.set("send",A);}this.store("send",new Request(this.retrieve("send:options"))); 339 | }return this.retrieve("send");}};Element.implement({send:function(A){var B=this.get("send");B.send({data:this,url:A||B.options.url});return this;}});Request.HTML=new Class({Extends:Request,options:{update:false,evalScripts:true,filter:false},processHTML:function(C){var B=C.match(/]*>([\s\S]*?)<\/body>/i); 340 | C=(B)?B[1]:C;var A=new Element("div");return $try(function(){var D=""+C+"",G;if(Browser.Engine.trident){G=new ActiveXObject("Microsoft.XMLDOM"); 341 | G.async=false;G.loadXML(D);}else{G=new DOMParser().parseFromString(D,"text/xml");}D=G.getElementsByTagName("root")[0];for(var F=0,E=D.childNodes.length; 342 | F -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | TextboxList 2 | =========== 3 | 4 | TextboxList is great! 5 | 6 | ![Screenshot](http://devthought.com/wp-content/uploads/2009/04/picture-1.png) 7 | 8 | How to Use 9 | ---------- 10 | 11 | TextboxList is essentially very easy to use, but is extremely configurable and extensible. Let’s review some sample usage scenarios: 12 | 13 | #JS 14 | new TextboxList('form_tags_input'); 15 | 16 | This turns the `` into a TextboxList widget. By default, as shown in the demo, the user can add new boxes by pressing enter, write between boxes, delete them with backspace and delete keys. Additionally, a delete button is shown in each of the added items. All these behaviors can be configured, as shown in the sections below. 17 | 18 | #JS 19 | var t = new TextboxList('form_tags_input'); 20 | t.add('Tag 1').add('Tag 2').add('Tag 3'); 21 | 22 | In this example we call the public `add()` method of the TextboxList instance to add items from JavaScript. 23 | 24 | The anatomy of TextboxList 25 | -------------------------- 26 | 27 | This section will be useful for those interested in customizing the default behavior of TextboxList, extending the main classes or writing their own plugins. 28 | 29 | The parts that constitute a TextboxList widget are called bits. These parts have common characteristics: they can be focused, blurred, deleted, hidden, they are a fragment of the overall value, etc. TextboxList has two essential bits: the editable and the box bit. 30 | 31 | Some options involved in the behavior and appearance of the widget are specific to the editable bits, and some are specific to the box bits, which are separate classes from TextboxList. To easily pass them from the main class, you use the `bitsOptions` property. For example, to disable the delete button in boxes bits, and use the shift key for adding items instead of the enter key: 32 | 33 | #JS 34 | new TextboxList('form_tags_input', {bitsOptions: { 35 | box: {deleteButton: false}, 36 | editable: {addKeys: Event.Keys.shift} 37 | }}); 38 | 39 | Knowing this gives you more customization power. If you want to target the blur event of any bit, attach a onBitBlur listener. If you want to target boxes, you can use `onBitBoxBlur`. You can see a complete list of options and events at the bottom of this page. 40 | 41 | Screenshots 42 | ----------- 43 | 44 | ![Screenshot](http://www.quicksnapper.com/files/4413/9492781094A285A249645E_m.png) 45 | ![Screenshot](http://www.quicksnapper.com/files/4413/11103271584A285A321A884_m.png) 46 | ![Screenshot](http://www.quicksnapper.com/files/4413/2498436964A285A6A438CD_m.png) -------------------------------------------------------------------------------- /Source/TextboxList.Autocomplete.Binary.js: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | description: TextboxList 4 | 5 | authors: 6 | - Guillermo Rauch 7 | 8 | requires: 9 | core/1.2.1: '*' 10 | 11 | provides: 12 | - textboxlist.autocomplete.binary 13 | ... 14 | */ 15 | 16 | TextboxList.Autocomplete.Methods.binary = { 17 | filter: function(values, search, insensitive, max){ 18 | var method = insensitive ? 'toLowerCase' : 'toString', low = 0, high = values.length - 1, lastTry; 19 | search = search[method](); 20 | while (high >= low){ 21 | var mid = parseInt((low + high) / 2); 22 | var curr = values[mid][1].substr(0, search.length)[method](); 23 | var result = ((search == curr) ? 0 : ((search > curr) ? 1 : -1)); 24 | if (result < 0) { high = mid - 1; continue; } 25 | if (result > 0) { low = mid + 1; continue; } 26 | if (result === 0) break; 27 | } 28 | if (high < low) return []; 29 | var newvalues = [values[mid]], checkNext = true, checkPrev = true, v1, v2; 30 | for (var i = 1; i <= values.length - mid; i++){ 31 | if (newvalues.length === max) break; 32 | if (checkNext) v1 = values[mid + i] ? values[mid + i][1].substr(0, search.length)[method]() : false; 33 | if (checkPrev) v2 = values[mid - i] ? values[mid - i][1].substr(0, search.length)[method]() : false; 34 | checkNext = checkPrev = false; 35 | if (v1 === search) { newvalues.push(values[mid + i]); checkNext = true; } 36 | if (v2 === search) { newvalues.unshift(values[mid - i]); checkPrev = true; } 37 | if (! (checkNext || checkPrev)) break; 38 | } 39 | return newvalues; 40 | }, 41 | 42 | highlight: function(element, search, insensitive, klass){ 43 | var regex = new RegExp('(<[^>]*>)|(\\b'+ search.escapeRegExp() +')', insensitive ? 'ig' : 'g'); 44 | return element.set('html', element.get('html').replace(regex, function(a, b, c, d){ 45 | return (a.charAt(0) == '<') ? a : '' + c + ''; 46 | })); 47 | } 48 | }; -------------------------------------------------------------------------------- /Source/TextboxList.Autocomplete.css: -------------------------------------------------------------------------------- 1 | /* 2 | This stylesheet belongs to TextboxList - Copyright Guillermo Rauch 2009 3 | TextboxList is not priceless for commercial use. See 4 | Purchase to remove copyright 5 | */ 6 | 7 | .textboxlist-autocomplete { position: absolute; } 8 | .textboxlist-autocomplete-placeholder, .textboxlist-autocomplete-results { opacity: 0.9; filter: alpha(opacity=90); background: #eee; -webkit-box-shadow: 0 3px 3px #ccc; -moz-box-shadow: 0 3px 3px #ccc; box-shadow: 0 3px 3px #ccc; border: 1px solid #999; border-top: none; display: none; } 9 | .textboxlist-autocomplete-placeholder { padding: 5px 7px; } 10 | .textboxlist-autocomplete-results { margin: 0; padding: 0; } 11 | .textboxlist-autocomplete-result { margin: 0; padding: 5px; list-style-type: none; background: #eee; } 12 | .textboxlist-autocomplete-result-focus { background: #C6D9E4; } 13 | .textboxlist-autocomplete-highlight { background: #EEF0C4; font-weight: bold; } 14 | 15 | /* TextboxList.Autocomplete Style guidelines 16 | Try to keep .textboxlist-autocomplete {} as it is now 17 | If you apply custom styles to placeholder, also apply them to results, like it is now. 18 | .textboxlist-autocomplete-result {} needs a background for IE. 19 | */ -------------------------------------------------------------------------------- /Source/TextboxList.Autocomplete.js: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | description: TextboxList 4 | 5 | authors: 6 | - Guillermo Rauch 7 | 8 | requires: 9 | core/1.2.1: '*' 10 | 11 | provides: 12 | - textboxlist.autocomplete 13 | ... 14 | */ 15 | 16 | (function(){ 17 | 18 | TextboxList.Autocomplete = new Class({ 19 | 20 | Implements: Options, 21 | 22 | options: { 23 | minLength: 1, 24 | maxResults: 10, 25 | insensitive: true, 26 | highlight: true, 27 | highlightSelector: null, 28 | mouseInteraction: true, 29 | onlyFromValues: false, 30 | queryRemote: false, 31 | remote: { 32 | url: '', 33 | param: 'search', 34 | extraParams: {}, 35 | loadPlaceholder: 'Please wait...' 36 | }, 37 | method: 'standard', 38 | placeholder: 'Type to receive suggestions' 39 | }, 40 | 41 | initialize: function(textboxlist, options){ 42 | this.setOptions(options); 43 | this.textboxlist = textboxlist; 44 | this.textboxlist.addEvent('bitEditableAdd', this.setupBit.bind(this), true) 45 | .addEvent('bitEditableFocus', this.search.bind(this), true) 46 | .addEvent('bitEditableBlur', this.hide.bind(this), true) 47 | .setOptions({bitsOptions: {editable: {addKeys:[], stopEnter: false}}}); 48 | if (Browser.Engine.trident) this.textboxlist.setOptions({bitsOptions: {editable: {addOnBlur: false}}}); 49 | if (this.textboxlist.options.unique){ 50 | this.index = []; 51 | this.textboxlist.addEvent('bitBoxRemove', function(bit){ 52 | if (bit.autoValue) this.index.erase(bit.autoValue); 53 | }.bind(this), true); 54 | } 55 | this.prefix = this.textboxlist.options.prefix + '-autocomplete'; 56 | this.method = TextboxList.Autocomplete.Methods[this.options.method]; 57 | this.container = new Element('div', {'class': this.prefix}).setStyle('width', this.textboxlist.container.getStyle('width')).inject(this.textboxlist.container); 58 | if ($chk(this.options.placeholder) || this.options.queryServer) 59 | this.placeholder = new Element('div', {'class': this.prefix+'-placeholder'}).inject(this.container); 60 | this.list = new Element('ul', {'class': this.prefix + '-results'}).inject(this.container); 61 | this.list.addEvent('click', function(ev){ ev.stop(); }); 62 | this.values = this.results = this.searchValues = []; 63 | this.navigate = this.navigate.bind(this); 64 | }, 65 | 66 | setValues: function(values){ 67 | this.values = values; 68 | }, 69 | 70 | setupBit: function(bit){ 71 | bit.element.addEvent('keydown', this.navigate, true).addEvent('keyup', function(){ this.search(); }.bind(this), true); 72 | }, 73 | 74 | search: function(bit){ 75 | if (bit) this.currentInput = bit; 76 | if (!this.options.queryRemote && !this.values.length) return; 77 | var search = this.currentInput.getValue()[1]; 78 | if (search.length < this.options.minLength) this.showPlaceholder(this.options.placeholder); 79 | if (search == this.currentSearch) return; 80 | this.currentSearch = search; 81 | this.list.setStyle('display', 'none'); 82 | if (search.length < this.options.minLength) return; 83 | if (this.options.queryRemote){ 84 | if (this.searchValues[search]){ 85 | this.values = this.searchValues[search]; 86 | } else { 87 | var data = this.options.remote.extraParams, that = this; 88 | if ($type(data) == 'function') data = data.run([], this); 89 | data[this.options.remote.param] = search; 90 | if (this.currentRequest) this.currentRequest.cancel(); 91 | this.currentRequest = new Request.JSON({url: this.options.remote.url, data: data, onRequest: function(){ 92 | that.showPlaceholder(that.options.remote.loadPlaceholder); 93 | }, onSuccess: function(data){ 94 | that.searchValues[search] = data; 95 | that.values = data; 96 | that.showResults(search); 97 | }}).send(); 98 | } 99 | } 100 | if (this.values.length) this.showResults(search); 101 | }, 102 | 103 | showResults: function(search){ 104 | var results = this.method.filter(this.values, search, this.options.insensitive, this.options.maxResults); 105 | if (this.index) results = results.filter(function(v){ return !this.index.contains(v); }, this); 106 | this.hidePlaceholder(); 107 | if (!results.length) return; 108 | this.blur(); 109 | this.list.empty().setStyle('display', 'block'); 110 | results.each(function(r){ this.addResult(r, search); }, this); 111 | if (this.options.onlyFromValues) this.focusFirst(); 112 | this.results = results; 113 | }, 114 | 115 | addResult: function(r, search){ 116 | var element = new Element('li', {'class': this.prefix + '-result', 'html': $pick(r[3], r[1])}).store('textboxlist:auto:value', r); 117 | this.list.adopt(element); 118 | if (this.options.highlight) $$(this.options.highlightSelector ? element.getElements(this.options.highlightSelector) : element).each(function(el){ 119 | if (el.get('html')) this.method.highlight(el, search, this.options.insensitive, this.prefix + '-highlight'); 120 | }, this); 121 | if (this.options.mouseInteraction){ 122 | element.setStyle('cursor', 'pointer').addEvents({ 123 | mouseenter: function(){ this.focus(element); }.bind(this), 124 | mousedown: function(ev){ 125 | ev.stop(); 126 | $clear(this.hidetimer); 127 | this.doAdd = true; 128 | }.bind(this), 129 | mouseup: function(){ 130 | if (this.doAdd){ 131 | this.addCurrent(); 132 | this.currentInput.focus(); 133 | this.search(); 134 | this.doAdd = false; 135 | } 136 | }.bind(this) 137 | }); 138 | if (!this.options.onlyFromValues) element.addEvent('mouseleave', function(){ if (this.current == element) this.blur(); }.bind(this)); 139 | } 140 | }, 141 | 142 | hide: function(ev){ 143 | this.hidetimer = (function(){ 144 | this.hidePlaceholder(); 145 | this.list.setStyle('display', 'none'); 146 | this.currentSearch = null; 147 | }).delay(Browser.Engine.trident ? 150 : 0, this); 148 | }, 149 | 150 | showPlaceholder: function(customHTML){ 151 | if (this.placeholder){ 152 | this.placeholder.setStyle('display', 'block'); 153 | if (customHTML) this.placeholder.set('html', customHTML); 154 | } 155 | }, 156 | 157 | hidePlaceholder: function(){ 158 | if (this.placeholder) this.placeholder.setStyle('display', 'none'); 159 | }, 160 | 161 | focus: function(element){ 162 | if (!element) return this; 163 | this.blur(); 164 | this.current = element.addClass(this.prefix + '-result-focus'); 165 | }, 166 | 167 | blur: function(){ 168 | if (this.current){ 169 | this.current.removeClass(this.prefix + '-result-focus'); 170 | this.current = null; 171 | } 172 | }, 173 | 174 | focusFirst: function(){ 175 | return this.focus(this.list.getFirst()); 176 | }, 177 | 178 | focusRelative: function(dir){ 179 | if (!this.current) return this; 180 | return this.focus(this.current['get' + dir.capitalize()]()); 181 | }, 182 | 183 | addCurrent: function(){ 184 | var value = this.current.retrieve('textboxlist:auto:value'); 185 | var b = this.textboxlist.create('box', value.slice(0, 3)); 186 | if (b){ 187 | b.autoValue = value; 188 | if (this.index != null) this.index.push(value); 189 | this.currentInput.setValue([null, '', null]); 190 | b.inject($(this.currentInput), 'before'); 191 | } 192 | this.blur(); 193 | return this; 194 | }, 195 | 196 | navigate: function(ev){ 197 | switch (ev.code){ 198 | case Event.Keys.up: 199 | ev.stop(); 200 | (!this.options.onlyFromValues && this.current && this.current == this.list.getFirst()) ? this.blur() : this.focusRelative('previous'); 201 | break; 202 | case Event.Keys.down: 203 | ev.stop(); 204 | this.current ? this.focusRelative('next') : this.focusFirst(); 205 | break; 206 | case Event.Keys.enter: 207 | ev.stop(); 208 | if (this.current) this.addCurrent(); 209 | else if (!this.options.onlyFromValues){ 210 | var value = this.currentInput.getValue(); 211 | var b = this.textboxlist.create('box', value); 212 | if (b){ 213 | b.inject($(this.currentInput), 'before'); 214 | this.currentInput.setValue([null, '', null]); 215 | } 216 | } 217 | } 218 | } 219 | 220 | }); 221 | 222 | TextboxList.Autocomplete.Methods = { 223 | 224 | standard: { 225 | filter: function(values, search, insensitive, max){ 226 | var newvals = [], regexp = new RegExp('\\b' + search.escapeRegExp(), insensitive ? 'i' : ''); 227 | for (var i = 0; i < values.length; i++){ 228 | if (newvals.length === max) break; 229 | if (values[i][1].test(regexp)) newvals.push(values[i]); 230 | } 231 | return newvals; 232 | }, 233 | 234 | highlight: function(element, search, insensitive, klass){ 235 | var regex = new RegExp('(<[^>]*>)|(\\b'+ search.escapeRegExp() +')', insensitive ? 'ig' : 'g'); 236 | return element.set('html', element.get('html').replace(regex, function(a, b, c){ 237 | return (a.charAt(0) == '<') ? a : '' + c + ''; 238 | })); 239 | } 240 | } 241 | 242 | }; 243 | 244 | })(); -------------------------------------------------------------------------------- /Source/TextboxList.css: -------------------------------------------------------------------------------- 1 | /* 2 | This stylesheet belongs to TextboxList - Copyright Guillermo Rauch 2009 3 | TextboxList is not priceless for commercial use. See 4 | Purchase to remove copyright 5 | */ 6 | 7 | .textboxlist { font: 11px "Lucida Grande", Verdana; cursor: text; } 8 | .textboxlist-bits { zoom: 1; overflow: hidden; margin: 0; padding: 3px 4px 0; border: 1px solid #999; *padding-bottom: 3px; } 9 | .textboxlist-bit { list-style-type: none; float: left; display: block; padding: 0; margin: 0 5px 3px 0; cursor: default; } 10 | .textboxlist-bit-editable { border: 1px solid #fff; } 11 | .textboxlist-bit-editable-input { border: 0; padding: 2px 0; *padding-bottom: 0; height: 14px; font: 11px "Lucida Grande", Verdana; } 12 | .textboxlist-bit-editable-input:focus { outline: 0; } 13 | .textboxlist-bit-box { position: relative; line-height: 18px; padding: 0 5px; -moz-border-radius: 9px; -webkit-border-radius: 9px; border-radius: 9px; border: 1px solid #CAD8F3; background: #DEE7F8; cursor: default; } 14 | .textboxlist-bit-box-deletable { padding-right: 15px; } 15 | .textboxlist-bit-box-deletebutton { position: absolute; right: 4px; top: 6px; display: block; width: 7px; height: 7px; font-size: 1px; background: url('close.gif'); } 16 | .textboxlist-bit-box-deletebutton:hover { border: none; background-position: 7px; text-decoration: none; } 17 | .textboxlist-bit-box-hover { background: #BBCEF1; border: 1px solid #6D95E0; } 18 | .textboxlist-bit-box-focus { border-color: #598BEC; background: #598BEC; color: #fff; } 19 | .textboxlist-bit-box-focus .textboxlist-bit-box-deletebutton { background-position: bottom; } 20 | 21 | /* TextboxList Style guidelines 22 | This style doesn't necessarily have to be in a separate file. 23 | It's advisable not to set widths and margins from here, but instead apply it to a particular object or class (#id .textboxlist { width: xxx } or .class .textboxlist { width: xxx }) 24 | The padding-top + padding-left + height of ".textboxlist-bit-editable-input {}" has to match the line-height of ".textboxlist-bit-box {}" for UI consistency. 25 | The font configuration has to be present in .textboxlist and .textboxlist-bit-editable-input (for IE reasons) 26 | The *padding-bottom (notice the *) property of .textboxlist-bits {} has to be equal to the margin-bottom of .textboxlist-bit {} for IE reasons. 27 | The padding-top of .textboxlist ul {} has to match the margin-bottom of .textboxlist-bit, and the padding-bottom has to be null. 28 | Make sure the border-width of the .textboxlist-bit-editable {} is equal to the border-width of the box (a border that matches the background is advisable for the input) 29 | Feel free to edit the borders, fonts, backgrounds and radius. 30 | */ -------------------------------------------------------------------------------- /Source/TextboxList.js: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | description: TextboxList 4 | 5 | authors: 6 | - Guillermo Rauch 7 | 8 | requires: 9 | core/1.2.1: '*' 10 | 11 | provides: 12 | - textboxlist 13 | ... 14 | */ 15 | 16 | var TextboxList = new Class({ 17 | 18 | Implements: [Options, Events], 19 | 20 | plugins: [], 21 | 22 | options: {/* 23 | onFocus: $empty, 24 | onBlur: $empty, 25 | onBitFocus: $empty, 26 | onBitBlur: $empty, 27 | onBitAdd: $empty, 28 | onBitRemove: $empty, 29 | onBitBoxFocus: $empty, 30 | onBitBoxBlur: $empty, 31 | onBitBoxAdd: $empty, 32 | onBitBoxRemove: $empty, 33 | onBitEditableFocus: $empty, 34 | onBitEditableBlue: $empty, 35 | onBitEditableAdd: $empty, 36 | onBitEditableRemove: $empty,*/ 37 | prefix: 'textboxlist', 38 | max: null, 39 | unique: false, 40 | uniqueInsensitive: true, 41 | endEditableBit: true, 42 | startEditableBit: true, 43 | hideEditableBits: true, 44 | inBetweenEditableBits: true, 45 | keys: {previous: Event.Keys.left, next: Event.Keys.right}, 46 | bitsOptions: {editable: {}, box: {}}, 47 | plugins: {}, 48 | check: function(s){ return s.clean().replace(/,/g, '') != ''; }, 49 | encode: function(o){ 50 | return o.map(function(v){ 51 | v = ($chk(v[0]) ? v[0] : v[1]); 52 | return $chk(v) ? v : null; 53 | }).clean().join(','); 54 | }, 55 | decode: function(o){ return o.split(','); } 56 | }, 57 | 58 | initialize: function(element, options){ 59 | this.setOptions(options); 60 | this.original = $(element).setStyle('display', 'none').set('autocomplete', 'off').addEvent('focus', this.focusLast.bind(this)); 61 | this.container = new Element('div', {'class': this.options.prefix}).inject(element, 'after'); 62 | this.container.addEvent('click', function(e){ 63 | if ((e.target == this.list || e.target == this.container) && (!this.focused || $(this.current) != this.list.getLast())) this.focusLast(); 64 | }.bind(this)); 65 | this.list = new Element('ul', {'class': this.options.prefix + '-bits'}).inject(this.container); 66 | for (var name in this.options.plugins) this.enablePlugin(name, this.options.plugins[name]); 67 | ['check', 'encode', 'decode'].each(function(i){ this.options[i] = this.options[i].bind(this); }, this); 68 | this.afterInit(); 69 | }, 70 | 71 | enablePlugin: function(name, options){ 72 | this.plugins[name] = new TextboxList[name.camelCase().capitalize()](this, options); 73 | }, 74 | 75 | afterInit: function(){ 76 | if (this.options.unique) this.index = []; 77 | if (this.options.endEditableBit) this.create('editable', null, {tabIndex: this.original.tabIndex}).inject(this.list); 78 | var update = this.update.bind(this); 79 | this.addEvent('bitAdd', update, true).addEvent('bitRemove', update, true); 80 | document.addEvents({ 81 | click: function(e){ 82 | if (!this.focused) return; 83 | if (e.target.className.contains(this.options.prefix)){ 84 | if (e.target == this.container) return; 85 | var parent = e.target.getParent('.' + this.options.prefix); 86 | if (parent == this.container) return; 87 | } 88 | this.blur(); 89 | }.bind(this), 90 | keydown: function(ev){ 91 | if (!this.focused || !this.current) return; 92 | var caret = this.current.is('editable') ? this.current.getCaret() : null; 93 | var value = this.current.getValue()[1]; 94 | var special = ['shift', 'alt', 'meta', 'ctrl'].some(function(e){ return ev[e]; }); 95 | var custom = special || (this.current.is('editable') && this.current.isSelected()); 96 | switch (ev.code){ 97 | case Event.Keys.backspace: 98 | if (this.current.is('box')){ 99 | ev.stop(); 100 | return this.current.remove(); 101 | } 102 | case this.options.keys.previous: 103 | if (this.current.is('box') || ((caret == 0 || !value.length) && !custom)){ 104 | ev.stop(); 105 | this.focusRelative('previous'); 106 | } 107 | break; 108 | case Event.Keys['delete']: 109 | if (this.current.is('box')){ 110 | ev.stop(); 111 | return this.current.remove(); 112 | } 113 | case this.options.keys.next: 114 | if (this.current.is('box') || (caret == value.length && !custom)){ 115 | ev.stop(); 116 | this.focusRelative('next'); 117 | } 118 | } 119 | }.bind(this) 120 | }); 121 | this.setValues(this.options.decode(this.original.get('value'))); 122 | }, 123 | 124 | create: function(klass, value, options){ 125 | if (klass == 'box'){ 126 | if ((!value[0] && !value[1]) || ($chk(value[1]) && !this.options.check(value[1]))) return false; 127 | if ($chk(this.options.max) && this.list.getChildren('.' + this.options.prefix + '-bit-box').length + 1 > this.options.max) return false; 128 | if (this.options.unique && this.index.contains(this.uniqueValue(value))) return false; 129 | } 130 | return new TextboxListBit[klass.capitalize()](value, this, $merge(this.options.bitsOptions[klass], options)); 131 | }, 132 | 133 | uniqueValue: function(value){ 134 | return $chk(value[0]) ? value[0] : (this.options.uniqueInsensitive ? value[1].toLowerCase() : value[1]); 135 | }, 136 | 137 | onFocus: function(bit){ 138 | if (this.current) this.current.blur(); 139 | $clear(this.blurtimer); 140 | this.current = bit; 141 | this.container.addClass(this.options.prefix + '-focus'); 142 | if (!this.focused){ 143 | this.focused = true; 144 | this.fireEvent('focus', bit); 145 | } 146 | }, 147 | 148 | onBlur: function(bit, all){ 149 | this.current = null; 150 | this.container.removeClass(this.options.prefix + '-focus'); 151 | this.blurtimer = this.blur.delay(all ? 0 : 200, this); 152 | }, 153 | 154 | onAdd: function(bit){ 155 | if (this.options.unique && bit.is('box')) this.index.push(this.uniqueValue(bit.value)); 156 | if (bit.is('box')){ 157 | var prior = this.getBit($(bit).getPrevious()); 158 | if ((prior && prior.is('box') && this.options.inBetweenEditableBits) || (!prior && this.options.startEditableBit)){ 159 | var b = this.create('editable').inject(prior || this.list, prior ? 'after' : 'top'); 160 | if (this.options.hideEditableBits) b.hide(); 161 | } 162 | } 163 | }, 164 | 165 | onRemove: function(bit){ 166 | if (!this.focused) return; 167 | if (this.options.unique && bit.is('box')) this.index.erase(this.uniqueValue(bit.value)); 168 | var prior = this.getBit($(bit).getPrevious()); 169 | if (prior && prior.is('editable')) prior.remove(); 170 | this.focusRelative('next', bit); 171 | }, 172 | 173 | focusRelative: function(dir, to){ 174 | var b = this.getBit($($pick(to, this.current))['get' + dir.capitalize()]()); 175 | if (b) b.focus(); 176 | return this; 177 | }, 178 | 179 | focusLast: function(){ 180 | var lastElement = this.list.getLast(); 181 | if (lastElement) this.getBit(lastElement).focus(); 182 | return this; 183 | }, 184 | 185 | blur: function(){ 186 | if (! this.focused) return this; 187 | if (this.current) this.current.blur(); 188 | this.focused = false; 189 | return this.fireEvent('blur'); 190 | }, 191 | 192 | add: function(plain, id, html, afterEl){ 193 | var b = this.create('box', [id, plain, html]); 194 | if (b){ 195 | if (!afterEl) afterEl = this.list.getLast('.' + this.options.prefix + '-bit-box'); 196 | b.inject(afterEl || this.list, afterEl ? 'after' : 'top'); 197 | } 198 | return this; 199 | }, 200 | 201 | getBit: function(obj){ 202 | return ($type(obj) == 'element') ? obj.retrieve('textboxlist:bit') : obj; 203 | }, 204 | 205 | getValues: function(){ 206 | return this.list.getChildren().map(function(el){ 207 | var bit = this.getBit(el); 208 | if (bit.is('editable')) return null; 209 | return bit.getValue(); 210 | }, this).clean(); 211 | }, 212 | 213 | setValues: function(values){ 214 | if (!values) return; 215 | values.each(function(v){ 216 | if (v) this.add.apply(this, $type(v) == 'array' ? [v[1], v[0], v[2]] : [v]); 217 | }, this); 218 | }, 219 | 220 | update: function(){ 221 | this.original.set('value', this.options.encode(this.getValues())); 222 | } 223 | 224 | }); 225 | 226 | var TextboxListBit = new Class({ 227 | 228 | Implements: Options, 229 | 230 | initialize: function(value, textboxlist, options){ 231 | this.name = this.type.capitalize(); 232 | this.value = value; 233 | this.textboxlist = textboxlist; 234 | this.setOptions(options); 235 | this.prefix = this.textboxlist.options.prefix + '-bit'; 236 | this.typeprefix = this.prefix + '-' + this.type; 237 | this.bit = new Element('li').addClass(this.prefix).addClass(this.typeprefix).store('textboxlist:bit', this); 238 | this.bit.addEvents({ 239 | mouseenter: function(){ 240 | this.bit.addClass(this.prefix + '-hover').addClass(this.typeprefix + '-hover'); 241 | }.bind(this), 242 | mouseleave: function(){ 243 | this.bit.removeClass(this.prefix + '-hover').removeClass(this.typeprefix + '-hover'); 244 | }.bind(this) 245 | }); 246 | }, 247 | 248 | inject: function(element, where){ 249 | this.bit.inject(element, where); 250 | this.textboxlist.onAdd(this); 251 | return this.fireBitEvent('add'); 252 | }, 253 | 254 | focus: function(){ 255 | if (this.focused) return this; 256 | this.show(); 257 | this.focused = true; 258 | this.textboxlist.onFocus(this); 259 | this.bit.addClass(this.prefix + '-focus').addClass(this.prefix + '-' + this.type + '-focus'); 260 | return this.fireBitEvent('focus'); 261 | }, 262 | 263 | blur: function(){ 264 | if (!this.focused) return this; 265 | this.focused = false; 266 | this.textboxlist.onBlur(this); 267 | this.bit.removeClass(this.prefix + '-focus').removeClass(this.prefix + '-' + this.type + '-focus'); 268 | return this.fireBitEvent('blur'); 269 | }, 270 | 271 | remove: function(){ 272 | this.blur(); 273 | this.textboxlist.onRemove(this); 274 | this.bit.destroy(); 275 | return this.fireBitEvent('remove'); 276 | }, 277 | 278 | show: function(){ 279 | this.bit.setStyle('display', 'block'); 280 | return this; 281 | }, 282 | 283 | hide: function(){ 284 | this.bit.setStyle('display', 'none'); 285 | return this; 286 | }, 287 | 288 | fireBitEvent: function(type){ 289 | type = type.capitalize(); 290 | this.textboxlist.fireEvent('bit' + type, this).fireEvent('bit' + this.name + type, this); 291 | return this; 292 | }, 293 | 294 | is: function(t){ 295 | return this.type == t; 296 | }, 297 | 298 | setValue: function(v){ 299 | this.value = v; 300 | return this; 301 | }, 302 | 303 | getValue: function(){ 304 | return this.value; 305 | }, 306 | 307 | toElement: function(){ 308 | return this.bit; 309 | } 310 | 311 | }); 312 | 313 | TextboxListBit.Editable = new Class({ 314 | 315 | Extends: TextboxListBit, 316 | 317 | options: { 318 | tabIndex: null, 319 | growing: true, 320 | growingOptions: {}, 321 | stopEnter: true, 322 | addOnBlur: false, 323 | addKeys: Event.Keys.enter 324 | }, 325 | 326 | type: 'editable', 327 | 328 | initialize: function(value, textboxlist, options){ 329 | this.parent(value, textboxlist, options); 330 | this.element = new Element('input', {type: 'text', 'class': this.typeprefix + '-input', autocomplete: 'off', value: this.value ? this.value[1] : ''}).inject(this.bit); 331 | if ($chk(this.options.tabIndex)) this.element.tabIndex = this.options.tabIndex; 332 | if (this.options.growing) new GrowingInput(this.element, this.options.growingOptions); 333 | this.element.addEvents({ 334 | focus: function(){ this.focus(true); }.bind(this), 335 | blur: function(){ 336 | this.blur(true); 337 | if (this.options.addOnBlur) this.toBox(); 338 | }.bind(this) 339 | }); 340 | if (this.options.addKeys || this.options.stopEnter){ 341 | this.element.addEvent('keydown', function(ev){ 342 | if (!this.focused) return; 343 | if (this.options.stopEnter && ev.code === Event.Keys.enter) ev.stop(); 344 | if ($splat(this.options.addKeys).contains(ev.code)){ 345 | ev.stop(); 346 | this.toBox(); 347 | } 348 | }.bind(this)); 349 | } 350 | }, 351 | 352 | hide: function(){ 353 | this.parent(); 354 | this.hidden = true; 355 | return this; 356 | }, 357 | 358 | focus: function(noReal){ 359 | this.parent(); 360 | if (!noReal) this.element.focus(); 361 | return this; 362 | }, 363 | 364 | blur: function(noReal){ 365 | this.parent(); 366 | if (!noReal) this.element.blur(); 367 | if (this.hidden && !this.element.value.length) this.hide(); 368 | return this; 369 | }, 370 | 371 | getCaret: function(){ 372 | if (this.element.createTextRange){ 373 | var r = document.selection.createRange().duplicate(); 374 | r.moveEnd('character', this.element.value.length); 375 | if (r.text === '') return this.element.value.length; 376 | return this.element.value.lastIndexOf(r.text); 377 | } else return this.element.selectionStart; 378 | }, 379 | 380 | getCaretEnd: function(){ 381 | if (this.element.createTextRange){ 382 | var r = document.selection.createRange().duplicate(); 383 | r.moveStart('character', -this.element.value.length); 384 | return r.text.length; 385 | } else return this.element.selectionEnd; 386 | }, 387 | 388 | isSelected: function(){ 389 | return this.focused && (this.getCaret() !== this.getCaretEnd()); 390 | }, 391 | 392 | setValue: function(val){ 393 | this.element.value = $chk(val[0]) ? val[0] : val[1]; 394 | if (this.options.growing) this.element.retrieve('growing').resize(); 395 | return this; 396 | }, 397 | 398 | getValue: function(){ 399 | return [null, this.element.value, null]; 400 | }, 401 | 402 | toBox: function(){ 403 | var value = this.getValue(); 404 | var b = this.textboxlist.create('box', value); 405 | if (b){ 406 | b.inject(this.bit, 'before'); 407 | this.setValue([null, '', null]) 408 | return b; 409 | } 410 | return null; 411 | } 412 | 413 | }); 414 | 415 | TextboxListBit.Box = new Class({ 416 | 417 | Extends: TextboxListBit, 418 | 419 | options: { 420 | deleteButton: true 421 | }, 422 | 423 | type: 'box', 424 | 425 | initialize: function(value, textboxlist, options){ 426 | this.parent(value, textboxlist, options); 427 | this.bit.set('html', $chk(this.value[2]) ? this.value[2] : this.value[1]); 428 | this.bit.addEvent('click', this.focus.bind(this)); 429 | if (this.options.deleteButton){ 430 | this.bit.addClass(this.typeprefix + '-deletable'); 431 | this.close = new Element('a', {href: '#', 'class': this.typeprefix + '-deletebutton', events: {click: this.remove.bind(this)}}).inject(this.bit); 432 | } 433 | this.bit.getChildren().addEvent('click', function(e){ e.stop(); }); 434 | } 435 | 436 | }); -------------------------------------------------------------------------------- /Source/close.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rauchg/TextboxList/3b33cee725803d003801e4d3dfd309a94728b799/Source/close.gif -------------------------------------------------------------------------------- /package.yml: -------------------------------------------------------------------------------- 1 | name: TextboxList 2 | author: rauchg 3 | category: Widgets 4 | tags: [keyboard, facebook, tokenizer, input] 5 | docs: http://devthought.com/projects/mootools/textboxlist/ 6 | demo: http://devthought.com/wp-content/project/mootools/textboxlist/Demo/ --------------------------------------------------------------------------------