[ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 /*----------------------------------------------------------------------------\ 2 | Selectable Elements 1.02 | 3 |-----------------------------------------------------------------------------| 4 | Created by Erik Arvidsson | 5 | (http://webfx.eae.net/contact.html#erik) | 6 | For WebFX (http://webfx.eae.net/) | 7 |-----------------------------------------------------------------------------| 8 | A script that allows children of any element to be selected | 9 |-----------------------------------------------------------------------------| 10 | Copyright (c) 1999 - 2004 Erik Arvidsson | 11 |-----------------------------------------------------------------------------| 12 | This software is provided "as is", without warranty of any kind, express or | 13 | implied, including but not limited to the warranties of merchantability, | 14 | fitness for a particular purpose and noninfringement. In no event shall the | 15 | authors or copyright holders be liable for any claim, damages or other | 16 | liability, whether in an action of contract, tort or otherwise, arising | 17 | from, out of or in connection with the software or the use or other | 18 | dealings in the software. | 19 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 20 | This software is available under the three different licenses mentioned | 21 | below. To use this software you must chose, and qualify, for one of those. | 22 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 23 | The WebFX Non-Commercial License http://webfx.eae.net/license.html | 24 | Permits anyone the right to use the software in a non-commercial context | 25 | free of charge. | 26 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 27 | The WebFX Commercial license http://webfx.eae.net/commercial.html | 28 | Permits the license holder the right to use the software in a commercial | 29 | context. Such license must be specifically obtained, however it's valid for | 30 | any number of implementations of the licensed software. | 31 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | 32 | GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt | 33 | Permits anyone the right to use and modify the software without limitations | 34 | as long as proper credits are given and the original and modified source | 35 | code are included. Requires that the final product, software derivate from | 36 | the original source or any software utilizing a GPL component, such as | 37 | this, is also licensed under the GPL license. | 38 |-----------------------------------------------------------------------------| 39 | 2002-09-19 | Original Version Posted. | 40 | 2002-09-27 | Fixed a bug in IE when mouse down and up occured on different | 41 | | rows. | 42 | 2003-02-11 | Minor problem with addClassName and removeClassName that | 43 | | triggered a bug in Opera 7. Added destroy method | 44 |-----------------------------------------------------------------------------| 45 | Created 2002-09-04 | All changes are in the log above. | Updated 2003-02-11 | 46 \----------------------------------------------------------------------------*/ 47 48 function SelectableElements(oElement, bMultiple) { 49 if (oElement == null) 50 return; 51 52 this._htmlElement = oElement; 53 this._multiple = Boolean(bMultiple); 54 55 this._selectedItems = []; 56 this._fireChange = true; 57 58 var oThis = this; 59 this._onclick = function (e) { 60 if (e == null) e = oElement.ownerDocument.parentWindow.event; 61 oThis.click(e); 62 }; 63 64 if (oElement.addEventListener) 65 oElement.addEventListener("click", this._onclick, false); 66 else if (oElement.attachEvent) 67 oElement.attachEvent("onclick", this._onclick); 68 } 69 70 SelectableElements.prototype.setItemSelected = function (oEl, bSelected) { 71 if (!this._multiple) { 72 if (bSelected) { 73 var old = this._selectedItems[0] 74 if (oEl == old) 75 return; 76 if (old != null) 77 this.setItemSelectedUi(old, false); 78 this.setItemSelectedUi(oEl, true); 79 this._selectedItems = [oEl]; 80 this.fireChange(); 81 } 82 else { 83 if (this._selectedItems[0] == oEl) { 84 this.setItemSelectedUi(oEl, false); 85 this._selectedItems = []; 86 } 87 } 88 } 89 else { 90 if (Boolean(oEl._selected) == Boolean(bSelected)) 91 return; 92 93 this.setItemSelectedUi(oEl, bSelected); 94 95 if (bSelected) 96 this._selectedItems[this._selectedItems.length] = oEl; 97 else { 98 // remove 99 var tmp = []; 100 var j = 0; 101 for (var i = 0; i < this._selectedItems.length; i++) { 102 if (this._selectedItems[i] != oEl) 103 tmp[j++] = this._selectedItems[i]; 104 } 105 this._selectedItems = tmp; 106 } 107 this.fireChange(); 108 } 109 }; 110 111 // This method updates the UI of the item 112 SelectableElements.prototype.setItemSelectedUi = function (oEl, bSelected) { 113 if (bSelected) 114 addClassName(oEl, "selected"); 115 else 116 removeClassName(oEl, "selected"); 117 118 oEl._selected = bSelected; 119 }; 120 121 SelectableElements.prototype.getItemSelected = function (oEl) { 122 return Boolean(oEl._selected); 123 }; 124 125 SelectableElements.prototype.fireChange = function () { 126 if (!this._fireChange) 127 return; 128 if (typeof this.onchange == "string") 129 this.onchange = new Function(this.onchange); 130 if (typeof this.onchange == "function") 131 this.onchange(); 132 }; 133 134 135 SelectableElements.prototype.click = function (e) { 136 var oldFireChange = this._fireChange; 137 this._fireChange = false; 138 139 // create a copy to compare with after changes 140 var selectedBefore = this.getSelectedItems(); // is a cloned array 141 142 // find row 143 var el = e.target != null ? e.target : e.srcElement; 144 while (el != null && !this.isItem(el)) 145 el = el.parentNode; 146 147 if (el == null) { // happens in IE when down and up occur on different items 148 this._fireChange = oldFireChange; 149 return; 150 } 151 152 var rIndex = el; 153 var aIndex = this._anchorIndex; 154 155 // test whether the current row should be the anchor 156 if (this._selectedItems.length == 0 || (e.ctrlKey && !e.shiftKey && this._multiple)) { 157 aIndex = this._anchorIndex = rIndex; 158 } 159 160 if (!e.ctrlKey && !e.shiftKey || !this._multiple) { 161 // deselect all 162 var items = this._selectedItems; 163 for (var i = items.length - 1; i >= 0; i--) { 164 if (items[i]._selected && items[i] != el) 165 this.setItemSelectedUi(items[i], false); 166 } 167 this._anchorIndex = rIndex; 168 if (!el._selected) { 169 this.setItemSelectedUi(el, true); 170 } 171 this._selectedItems = [el]; 172 } 173 174 // ctrl 175 else if (this._multiple && e.ctrlKey && !e.shiftKey) { 176 this.setItemSelected(el, !el._selected); 177 this._anchorIndex = rIndex; 178 } 179 180 // ctrl + shift 181 else if (this._multiple && e.ctrlKey && e.shiftKey) { 182 // up or down? 183 var dirUp = this.isBefore(rIndex, aIndex); 184 185 var item = aIndex; 186 while (item != null && item != rIndex) { 187 if (!item._selected && item != el) 188 this.setItemSelected(item, true); 189 item = dirUp ? this.getPrevious(item) : this.getNext(item); 190 } 191 192 if (!el._selected) 193 this.setItemSelected(el, true); 194 } 195 196 // shift 197 else if (this._multiple && !e.ctrlKey && e.shiftKey) { 198 // up or down? 199 var dirUp = this.isBefore(rIndex, aIndex); 200 201 // deselect all 202 var items = this._selectedItems; 203 for (var i = items.length - 1; i >= 0; i--) 204 this.setItemSelectedUi(items[i], false); 205 this._selectedItems = []; 206 207 // select items in range 208 var item = aIndex; 209 while (item != null) { 210 this.setItemSelected(item, true); 211 if (item == rIndex) 212 break; 213 item = dirUp ? this.getPrevious(item) : this.getNext(item); 214 } 215 } 216 217 // find change!!! 218 var found; 219 var changed = selectedBefore.length != this._selectedItems.length; 220 if (!changed) { 221 for (var i = 0; i < selectedBefore.length; i++) { 222 found = false; 223 for (var j = 0; j < this._selectedItems.length; j++) { 224 if (selectedBefore[i] == this._selectedItems[j]) { 225 found = true; 226 break; 227 } 228 } 229 if (!found) { 230 changed = true; 231 break; 232 } 233 } 234 } 235 236 this._fireChange = oldFireChange; 237 if (changed && this._fireChange) 238 this.fireChange(); 239 }; 240 241 SelectableElements.prototype.getSelectedItems = function () { 242 //clone 243 var items = this._selectedItems; 244 var l = items.length; 245 var tmp = new Array(l); 246 for (var i = 0; i < l; i++) 247 tmp[i] = items[i]; 248 return tmp; 249 }; 250 251 SelectableElements.prototype.isItem = function (node) { 252 return node != null && node.nodeType == 1 && node.parentNode == this._htmlElement; 253 }; 254 255 SelectableElements.prototype.destroy = function () { 256 if (this._htmlElement.removeEventListener) 257 this._htmlElement.removeEventListener("click", this._onclick, false); 258 else if (this._htmlElement.detachEvent) 259 this._htmlElement.detachEvent("onclick", this._onclick); 260 261 this._htmlElement = null; 262 this._onclick = null; 263 this._selectedItems = null; 264 }; 265 266 /* Traversable Collection Interface */ 267 268 SelectableElements.prototype.getNext = function (el) { 269 var n = el.nextSibling; 270 if (n == null || this.isItem(n)) 271 return n; 272 return this.getNext(n); 273 }; 274 275 SelectableElements.prototype.getPrevious = function (el) { 276 var p = el.previousSibling; 277 if (p == null || this.isItem(p)) 278 return p; 279 return this.getPrevious(p); 280 }; 281 282 SelectableElements.prototype.isBefore = function (n1, n2) { 283 var next = this.getNext(n1); 284 while (next != null) { 285 if (next == n2) 286 return true; 287 next = this.getNext(next); 288 } 289 return false; 290 }; 291 292 /* End Traversable Collection Interface */ 293 294 /* Indexable Collection Interface */ 295 296 SelectableElements.prototype.getItems = function () { 297 var tmp = []; 298 var j = 0; 299 var cs = this._htmlElement.childNodes; 300 var l = cs.length; 301 for (var i = 0; i < l; i++) { 302 if (cs[i].nodeType == 1) 303 tmp[j++] = cs[i] 304 } 305 return tmp; 306 }; 307 308 SelectableElements.prototype.getItem = function (nIndex) { 309 var j = 0; 310 var cs = this._htmlElement.childNodes; 311 var l = cs.length; 312 for (var i = 0; i < l; i++) { 313 if (cs[i].nodeType == 1) { 314 if (j == nIndex) 315 return cs[i]; 316 j++; 317 } 318 } 319 return null; 320 }; 321 322 SelectableElements.prototype.getSelectedIndexes = function () { 323 var items = this.getSelectedItems(); 324 var l = items.length; 325 var tmp = new Array(l); 326 for (var i = 0; i < l; i++) 327 tmp[i] = this.getItemIndex(items[i]); 328 return tmp; 329 }; 330 331 332 SelectableElements.prototype.getItemIndex = function (el) { 333 var j = 0; 334 var cs = this._htmlElement.childNodes; 335 var l = cs.length; 336 for (var i = 0; i < l; i++) { 337 if (cs[i] == el) 338 return j; 339 if (cs[i].nodeType == 1) 340 j++; 341 } 342 return -1; 343 }; 344 345 /* End Indexable Collection Interface */ 346 347 348 349 function addClassName(el, sClassName) { 350 var s = el.className; 351 var p = s.split(" "); 352 if (p.length == 1 && p[0] == "") 353 p = []; 354 355 var l = p.length; 356 for (var i = 0; i < l; i++) { 357 if (p[i] == sClassName) 358 return; 359 } 360 p[p.length] = sClassName; 361 el.className = p.join(" "); 362 } 363 364 function removeClassName(el, sClassName) { 365 var s = el.className; 366 var p = s.split(" "); 367 var np = []; 368 var l = p.length; 369 var j = 0; 370 for (var i = 0; i < l; i++) { 371 if (p[i] != sClassName) 372 np[j++] = p[i]; 373 } 374 el.className = np.join(" "); 375 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |