Roo/form/ComboBoxArray.js
[roojs1] / Roo / CompositeElement.js
1 /*
2  * Based on:
3  * Ext JS Library 1.1.1
4  * Copyright(c) 2006-2007, Ext JS, LLC.
5  *
6  * Originally Released Under LGPL - original licence link has changed is not relivant.
7  *
8  * Fork - LGPL
9  * <script type="text/javascript">
10  */
11
12
13 /**
14  * @class Roo.CompositeElement
15  * Standard composite class. Creates a Roo.Element for every element in the collection.
16  * <br><br>
17  * <b>NOTE: Although they are not listed, this class supports all of the set/update methods of Roo.Element. All Roo.Element
18  * actions will be performed on all the elements in this collection.</b>
19  * <br><br>
20  * All methods return <i>this</i> and can be chained.
21  <pre><code>
22  var els = Roo.select("#some-el div.some-class", true);
23  // or select directly from an existing element
24  var el = Roo.get('some-el');
25  el.select('div.some-class', true);
26
27  els.setWidth(100); // all elements become 100 width
28  els.hide(true); // all elements fade out and hide
29  // or
30  els.setWidth(100).hide(true);
31  </code></pre>
32  */
33 Roo.CompositeElement = function(els){
34     this.elements = [];
35     this.addElements(els);
36 };
37 Roo.CompositeElement.prototype = {
38     isComposite: true,
39     addElements : function(els){
40         if(!els) return this;
41         if(typeof els == "string"){
42             els = Roo.Element.selectorFunction(els);
43         }
44         var yels = this.elements;
45         var index = yels.length-1;
46         for(var i = 0, len = els.length; i < len; i++) {
47                 yels[++index] = Roo.get(els[i]);
48         }
49         return this;
50     },
51
52     /**
53     * Clears this composite and adds the elements returned by the passed selector.
54     * @param {String/Array} els A string CSS selector, an array of elements or an element
55     * @return {CompositeElement} this
56     */
57     fill : function(els){
58         this.elements = [];
59         this.add(els);
60         return this;
61     },
62
63     /**
64     * Filters this composite to only elements that match the passed selector.
65     * @param {String} selector A string CSS selector
66     * @param {Boolean} inverse return inverse filter (not matches)
67     * @return {CompositeElement} this
68     */
69     filter : function(selector, inverse){
70         var els = [];
71         inverse = inverse || false;
72         this.each(function(el){
73             var match = inverse ? !el.is(selector) : el.is(selector);
74             if(match){
75                 els[els.length] = el.dom;
76             }
77         });
78         this.fill(els);
79         return this;
80     },
81
82     invoke : function(fn, args){
83         var els = this.elements;
84         for(var i = 0, len = els.length; i < len; i++) {
85                 Roo.Element.prototype[fn].apply(els[i], args);
86         }
87         return this;
88     },
89     /**
90     * Adds elements to this composite.
91     * @param {String/Array} els A string CSS selector, an array of elements or an element
92     * @return {CompositeElement} this
93     */
94     add : function(els){
95         if(typeof els == "string"){
96             this.addElements(Roo.Element.selectorFunction(els));
97         }else if(els.length !== undefined){
98             this.addElements(els);
99         }else{
100             this.addElements([els]);
101         }
102         return this;
103     },
104     /**
105     * Calls the passed function passing (el, this, index) for each element in this composite.
106     * @param {Function} fn The function to call
107     * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)
108     * @return {CompositeElement} this
109     */
110     each : function(fn, scope){
111         var els = this.elements;
112         for(var i = 0, len = els.length; i < len; i++){
113             if(fn.call(scope || els[i], els[i], this, i) === false) {
114                 break;
115             }
116         }
117         return this;
118     },
119
120     /**
121      * Returns the Element object at the specified index
122      * @param {Number} index
123      * @return {Roo.Element}
124      */
125     item : function(index){
126         return this.elements[index] || null;
127     },
128
129     /**
130      * Returns the first Element
131      * @return {Roo.Element}
132      */
133     first : function(){
134         return this.item(0);
135     },
136
137     /**
138      * Returns the last Element
139      * @return {Roo.Element}
140      */
141     last : function(){
142         return this.item(this.elements.length-1);
143     },
144
145     /**
146      * Returns the number of elements in this composite
147      * @return Number
148      */
149     getCount : function(){
150         return this.elements.length;
151     },
152
153     /**
154      * Returns true if this composite contains the passed element
155      * @return Boolean
156      */
157     contains : function(el){
158         return this.indexOf(el) !== -1;
159     },
160
161     /**
162      * Returns true if this composite contains the passed element
163      * @return Boolean
164      */
165     indexOf : function(el){
166         return this.elements.indexOf(Roo.get(el));
167     },
168
169
170     /**
171     * Removes the specified element(s).
172     * @param {Mixed} el The id of an element, the Element itself, the index of the element in this composite
173     * or an array of any of those.
174     * @param {Boolean} removeDom (optional) True to also remove the element from the document
175     * @return {CompositeElement} this
176     */
177     removeElement : function(el, removeDom){
178         if(el instanceof Array){
179             for(var i = 0, len = el.length; i < len; i++){
180                 this.removeElement(el[i]);
181             }
182             return this;
183         }
184         var index = typeof el == 'number' ? el : this.indexOf(el);
185         if(index !== -1){
186             if(removeDom){
187                 var d = this.elements[index];
188                 if(d.dom){
189                     d.remove();
190                 }else{
191                     d.parentNode.removeChild(d);
192                 }
193             }
194             this.elements.splice(index, 1);
195         }
196         return this;
197     },
198
199     /**
200     * Replaces the specified element with the passed element.
201     * @param {String/HTMLElement/Element/Number} el The id of an element, the Element itself, the index of the element in this composite
202     * to replace.
203     * @param {String/HTMLElement/Element} replacement The id of an element or the Element itself.
204     * @param {Boolean} domReplace (Optional) True to remove and replace the element in the document too.
205     * @return {CompositeElement} this
206     */
207     replaceElement : function(el, replacement, domReplace){
208         var index = typeof el == 'number' ? el : this.indexOf(el);
209         if(index !== -1){
210             if(domReplace){
211                 this.elements[index].replaceWith(replacement);
212             }else{
213                 this.elements.splice(index, 1, Roo.get(replacement))
214             }
215         }
216         return this;
217     },
218
219     /**
220      * Removes all elements.
221      */
222     clear : function(){
223         this.elements = [];
224     }
225 };
226 (function(){
227     Roo.CompositeElement.createCall = function(proto, fnName){
228         if(!proto[fnName]){
229             proto[fnName] = function(){
230                 return this.invoke(fnName, arguments);
231             };
232         }
233     };
234     for(var fnName in Roo.Element.prototype){
235         if(typeof Roo.Element.prototype[fnName] == "function"){
236             Roo.CompositeElement.createCall(Roo.CompositeElement.prototype, fnName);
237         }
238     };
239 })();