Changeset 9805 for trunk/themes
- Timestamp:
- Mar 21, 2011, 1:14:49 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/themes/default/js/plugins/jquery.fcbkcomplete.js
r5067 r9805 1 /* 2 FCBKcomplete 2.7 1 /** 2 FCBKcomplete 2.7.5 3 3 - Jquery version required: 1.2.x, 1.3.x, 1.4.x 4 4 5 Based on TextboxList by Guillermo Rauch http://devthought.com/ 6 5 7 Changelog: 6 - 2.00 8 - 2.00 new version of fcbkcomplete 7 9 8 10 - 2.01 fixed bugs & added features 9 10 11 12 13 14 11 fixed filter bug for preadded items 12 focus on the input after selecting tag 13 the element removed pressing backspace when the element is selected 14 input tag in the control has a border in IE7 15 added iterate over each match and apply the plugin separately 16 set focus on the input after selecting tag 15 17 16 18 - 2.02 fixed fist element selected bug 17 19 fixed defaultfilter error bug 18 20 19 - 2.5 20 21 22 23 24 21 - 2.5 removed selected="selected" attribute due ie bug 22 element search algorithm changed 23 better performance fix added 24 fixed many small bugs 25 onselect event added 26 onremove event added 25 27 26 - 2.6 ie6/7 support fix added 27 added new public method addItem due request 28 added new options "firstselected" that you can set true/false to select first element on dropdown list 29 autoexpand input element added 30 removeItem bug fixed 31 and many more bug fixed 32 fixed public method to use it $("elem").trigger("addItem",[{"title": "test", "value": "test"}]); 33 34 - 2.7 jquery 1.4 compability 35 item lock possability added by adding locked class to preadded option <option value="value" class="selected locked">text</option> 36 maximum item that can be added to the list 28 - 2.6 ie6/7 support fix added 29 added new public method addItem due request 30 added new options "firstselected" that you can set true/false to select first element on dropdown list 31 autoexpand input element added 32 removeItem bug fixed 33 and many more bug fixed 34 fixed public method to use it $("elem").trigger("addItem",[{"title": "test", "value": "test"}]); 35 36 - 2.7 jquery 1.4 compability 37 item lock possability added by adding locked class to preadded option <option value="value" class="selected locked">text</option> 38 maximum item that can be added 39 40 - 2.7.1 bug fixed 41 ajax delay added thanks to http://github.com/dolorian 42 43 - 2.7.2 some minor bug fixed 44 minified version recompacted due some problems 45 46 - 2.7.3 event call fixed thanks to William Parry <williamparry!at!gmail.com> 47 48 - 2.7.4 standart event change call added on addItem, removeItem 49 preSet also check if item have "selected" attribute 50 addItem minor fix 51 52 - 2.7.5 event call removeItem fixed 53 new public method destroy added needed to remove fcbkcomplete element from dome 54 37 55 */ 38 56 /* Coded by: emposha <admin@emposha.com> */ 39 /* Copyright: Emposha.com <http://www.emposha.com/> - Distributed under MIT - Keep this message! */ 40 /* 57 /* Copyright: Emposha.com <http://www.emposha.com> - Distributed under MIT - Keep this message! */ 58 59 /** 41 60 * json_url - url to fetch json object 42 * cache 61 * cache - use cache 43 62 * height - maximum number of element shown before scroll will apear 44 63 * newel - show typed text like a element 45 * firstselected 64 * firstselected - automaticly select first element from dropdown 46 65 * filter_case - case sensitive filter 47 66 * filter_selected - filter selected items from list 48 67 * complete_text - text for complete page 49 * maxshownitems - maximum numbers that will be shown at dropdown list (less better performance) 50 * onselect - fire event on item select 51 * onremove - fire event on item remove 52 * maxitimes - maximum items that can be added 68 * maxshownitems - maximum numbers that will be shown at dropdown list (less better performance) 69 * onselect - fire event on item select 70 * onremove - fire event on item remove 71 * maxitimes - maximum items that can be added 72 * delay - delay between ajax request (bigger delay, lower server time request) 73 * addontab - add first visible element on tab or enter hit 74 * attachto - after this element fcbkcomplete insert own elements 53 75 */ 54 jQuery(function($) {55 $.fn.fcbkcomplete = function(opt) {56 return this.each(function() {57 function init() {76 jQuery(function($) { 77 $.fn.fcbkcomplete = function(opt) { 78 return this.each(function() { 79 function init() { 58 80 createFCBK(); 59 81 preSet(); 60 82 addInput(0); 61 83 } 62 63 function createFCBK() {84 85 function createFCBK() { 64 86 element.hide(); 65 87 element.attr("multiple", "multiple"); … … 67 89 element.attr("name", element.attr("name") + "[]"); 68 90 } 69 91 70 92 holder = $(document.createElement("ul")); 71 93 holder.attr("class", "holder"); 72 element.after(holder);73 94 95 if (options.attachto) { 96 if (typeof(options.attachto) == "object") { 97 options.attachto.append(holder); 98 } 99 else { 100 $(options.attachto).append(holder); 101 } 102 103 } 104 else { 105 element.after(holder); 106 } 107 74 108 complete = $(document.createElement("div")); 75 109 complete.addClass("facebook-auto"); 76 110 complete.append('<div class="default">' + options.complete_text + "</div>"); 77 78 if (browser_msie) { 79 complete.append('<iframe class="ie6fix" scrolling="no" frameborder="0"></iframe>'); 80 browser_msie_frame = complete.children('.ie6fix'); 81 } 111 complete.hover(function() {options.complete_hover = 0;}, function() {options.complete_hover = 1;}); 82 112 83 113 feed = $(document.createElement("ul")); 84 114 feed.attr("id", elemid + "_feed"); 85 115 86 116 complete.prepend(feed); 87 117 holder.after(complete); 88 118 feed.css("width", complete.width()); 89 119 } 90 91 function preSet() {92 element.children("option").each(function(i, option) {93 option = $(option); 120 121 function preSet() { 122 element.children("option").each(function(i, option) { 123 option = $(option); 94 124 if (option.hasClass("selected")) { 95 125 addItem(option.text(), option.val(), true, option.hasClass("locked")); 96 126 option.attr("selected", "selected"); 97 127 } 98 else {99 option.removeAttr("selected");100 }101 102 128 cache.push({ 103 caption: option.text(),129 key: option.text(), 104 130 value: option.val() 105 131 }); … … 107 133 }); 108 134 } 109 135 110 136 //public method to add new item 111 $(this).bind("addItem", function(event, data){ 112 addItem(data.title, data.value); 137 $(this).bind("addItem", 138 function(event, data) { 139 addItem(data.title, data.value, 0, 0, 0); 140 }); 141 142 //public method to remove item 143 $(this).bind("removeItem", 144 function(event, data) { 145 var item = holder.children('li[rel=' + data.value + ']'); 146 if (item.length) { 147 removeItem(item); 148 } 113 149 }); 114 150 115 function addItem(title, value, preadded, locked){ 151 //public method to remove item 152 $(this).bind("destroy", 153 function(event, data) { 154 holder.remove(); 155 complete.remove(); 156 element.show(); 157 }); 158 159 function addItem(title, value, preadded, locked, focusme) { 116 160 if (!maxItems()) { 117 161 return false; … … 120 164 var txt = document.createTextNode(title); 121 165 var aclose = document.createElement("a"); 122 var liclass = "bit-box" + (locked ? " locked" 166 var liclass = "bit-box" + (locked ? " locked": ""); 123 167 $(li).attr({ 124 168 "class": liclass, … … 130 174 "href": "#" 131 175 }); 132 176 133 177 li.appendChild(aclose); 134 178 holder.append(li); 135 136 $(aclose).click(function() {179 180 $(aclose).click(function() { 137 181 removeItem($(this).parent("li")); 138 182 return false; 139 183 }); 140 184 141 185 if (!preadded) { 142 186 $("#" + elemid + "_annoninput").remove(); 143 187 var _item; 144 addInput( 1);188 addInput(focusme); 145 189 if (element.children("option[value=" + value + "]").length) { 146 190 _item = element.children("option[value=" + value + "]"); 147 191 _item.get(0).setAttribute("selected", "selected"); 192 _item.attr("selected", "selected"); 148 193 if (!_item.hasClass("selected")) { 149 194 _item.addClass("selected"); 150 195 } 151 196 } 152 else 197 else{ 153 198 var _item = $(document.createElement("option")); 154 199 _item.attr("value", value).get(0).setAttribute("selected", "selected"); 200 _item.attr("value", value).attr("selected", "selected"); 155 201 _item.attr("value", value).addClass("selected"); 156 202 _item.text(title); 157 203 element.append(_item); 158 204 } 159 if (options.onselect .length) {205 if (options.onselect) { 160 206 funCall(options.onselect, _item) 161 207 } 208 element.change(); 162 209 } 163 210 holder.children("li.bit-box.deleted").removeClass("deleted"); 164 211 feed.hide(); 165 browser_msie ? browser_msie_frame.hide() : ''; 166 } 167 168 function removeItem(item){ 169 var parent = item.parent("li"); 170 if (!parent.hasClass('locked')) { 171 parent.fadeOut("fast"); 172 if (options.onremove.length) { 212 } 213 214 function removeItem(item) { 215 216 if (!item.hasClass('locked')) { 217 item.fadeOut("fast"); 218 if (options.onremove) { 173 219 var _item = element.children("option[value=" + item.attr("rel") + "]"); 174 220 funCall(options.onremove, _item) 175 221 } 176 element.children("option[value=" + item.attr("rel") + "]").removeAttr("selected"); 177 element.children("option[value=" + item.attr("rel") + "]").removeClass("selected"); 222 element.children('option[value="' + item.attr("rel") + '"]').removeAttr("selected").removeClass("selected"); 178 223 item.remove(); 224 element.change(); 179 225 deleting = 0; 180 226 } 181 227 } 182 183 function addInput(focusme) {228 229 function addInput(focusme) { 184 230 var li = $(document.createElement("li")); 185 231 var input = $(document.createElement("input")); 186 232 var getBoxTimeout = 0; 233 187 234 li.attr({ 188 235 "class": "bit-input", … … 195 242 }); 196 243 holder.append(li.append(input)); 197 198 input.focus(function() {244 245 input.focus(function() { 199 246 complete.fadeIn("fast"); 200 247 }); 201 202 input.blur(function(){ 203 complete.fadeOut("fast"); 204 }); 205 206 holder.click(function(){ 248 249 input.blur(function() { 250 if (options.complete_hover) { 251 complete.fadeOut("fast"); 252 } 253 else { 254 input.focus(); 255 } 256 }); 257 258 holder.click(function() { 207 259 input.focus(); 208 260 if (feed.length && input.val().length) { 209 261 feed.show(); 210 262 } 211 else 263 else{ 212 264 feed.hide(); 213 browser_msie ? browser_msie_frame.hide() : '';214 265 complete.children(".default").show(); 215 266 } 216 267 }); 217 218 input.keypress(function(event) {268 269 input.keypress(function(event) { 219 270 if (event.keyCode == 13) { 220 271 return false; 221 272 } 222 //auto expand input 273 //auto expand input 223 274 input.attr("size", input.val().length + 1); 224 275 }); 225 226 input.keydown(function(event) {276 277 input.keydown(function(event) { 227 278 //prevent to enter some bad chars when input is empty 228 279 if (event.keyCode == 191) { … … 231 282 } 232 283 }); 233 234 input.keyup(function(event) {284 285 input.keyup(function(event) { 235 286 var etext = xssPrevent(input.val()); 236 287 237 288 if (event.keyCode == 8 && etext.length == 0) { 238 289 feed.hide(); 239 browser_msie ? browser_msie_frame.hide() : '';240 290 if (!holder.children("li.bit-box:last").hasClass('locked')) { 241 291 if (holder.children("li.bit-box.deleted").length == 0) { … … 243 293 return false; 244 294 } 245 else 295 else{ 246 296 if (deleting) { 247 297 return; 248 298 } 249 299 deleting = 1; 250 holder.children("li.bit-box.deleted").fadeOut("fast", function(){ 300 holder.children("li.bit-box.deleted").fadeOut("fast", 301 function() { 251 302 removeItem($(this)); 252 303 return false; … … 255 306 } 256 307 } 257 258 if (event.keyCode != 40 && event.keyCode != 38 && e text.length != 0) {308 309 if (event.keyCode != 40 && event.keyCode != 38 && event.keyCode!=37 && event.keyCode!=39 && etext.length != 0) { 259 310 counter = 0; 260 311 261 312 if (options.json_url) { 262 313 if (options.cache && json_cache) { … … 264 315 bindEvents(); 265 316 } 266 else { 267 $.getJSON(options.json_url + "?tag=" + etext, null, function(data){ 268 addMembers(etext, data); 269 json_cache = true; 270 bindEvents(); 271 }); 317 else{ 318 getBoxTimeout++; 319 var getBoxTimeoutValue = getBoxTimeout; 320 setTimeout(function() { 321 if (getBoxTimeoutValue != getBoxTimeout) return; 322 $.getJSON(options.json_url, {tag: etext}, 323 function(data) { 324 addMembers(etext, data); 325 json_cache = true; 326 bindEvents(); 327 }); 328 }, 329 options.delay); 272 330 } 273 331 } 274 else 332 else{ 275 333 addMembers(etext); 276 334 bindEvents(); … … 281 339 }); 282 340 if (focusme) { 283 setTimeout(function() {341 setTimeout(function() { 284 342 input.focus(); 285 343 complete.children(".default").show(); 286 }, 1); 287 } 288 } 289 290 function addMembers(etext, data){ 344 }, 345 1); 346 } 347 } 348 349 function addMembers(etext, data) { 291 350 feed.html(''); 292 293 if (!options.cache ) {351 352 if (!options.cache && data != null) { 294 353 cache = new Array(); 295 354 search_string = ""; 296 355 } 297 356 298 357 addTextItem(etext); 299 358 300 359 if (data != null && data.length) { 301 $.each(data, function(i, val){ 360 $.each(data, 361 function(i, val) { 302 362 cache.push({ 303 caption: val.caption,363 key: val.key, 304 364 value: val.value 305 365 }); 306 search_string += "" + (cache.length - 1) + ":" + val. caption+ ";";366 search_string += "" + (cache.length - 1) + ":" + val.key + ";"; 307 367 }); 308 368 } 309 310 var maximum = options.maxshownitems < cache.length ? options.maxshownitems 369 370 var maximum = options.maxshownitems < cache.length ? options.maxshownitems: cache.length; 311 371 var filter = "i"; 312 372 if (options.filter_case) { 313 373 filter = ""; 314 374 } 315 316 var myregexp, match; 317 try { 375 376 var myregexp, 377 match; 378 try{ 318 379 myregexp = eval('/(?:^|;)\\s*(\\d+)\\s*:[^;]*?' + etext + '[^;]*/g' + filter); 319 380 match = myregexp.exec(search_string); 320 } 321 catch 322 };323 381 } 382 catch(ex) { 383 }; 384 324 385 var content = ''; 325 386 while (match != null && maximum > 0) { … … 328 389 if (options.filter_selected && element.children("option[value=" + object.value + "]").hasClass("selected")) { 329 390 //nothing here... 330 }331 else 332 content += '<li rel="' + object.value + '">' + itemIllumination(object. caption, etext) + '</li>';391 } 392 else{ 393 content += '<li rel="' + object.value + '">' + itemIllumination(object.key, etext) + '</li>'; 333 394 counter++; 334 395 maximum--; … … 337 398 } 338 399 feed.append(content); 339 400 340 401 if (options.firstselected) { 341 402 focuson = feed.children("li:visible:first"); 342 403 focuson.addClass("auto-focus"); 343 404 } 344 405 345 406 if (counter > options.height) { 346 407 feed.css({ … … 348 409 "overflow": "auto" 349 410 }); 350 if (browser_msie) { 351 browser_msie_frame.css({ 352 "height": (options.height * 24) + "px", 353 "width": feed.width() + "px" 354 }).show(); 355 } 356 } 357 else { 411 } 412 else{ 358 413 feed.css("height", "auto"); 359 if (browser_msie) { 360 browser_msie_frame.css({ 361 "height": feed.height() + "px", 362 "width": feed.width() + "px" 363 }).show(); 364 } 365 } 366 } 367 368 function itemIllumination(text, etext){ 414 } 415 } 416 417 function itemIllumination(text, etext) { 369 418 if (options.filter_case) { 370 try 419 try{ 371 420 eval("var text = text.replace(/(.*)(" + etext + ")(.*)/gi,'$1<em>$2</em>$3');"); 372 } 373 catch 374 };375 376 else 377 try 421 } 422 catch(ex) { 423 }; 424 } 425 else{ 426 try{ 378 427 eval("var text = text.replace(/(.*)(" + etext.toLowerCase() + ")(.*)/gi,'$1<em>$2</em>$3');"); 379 } 380 catch 381 };382 428 } 429 catch(ex) { 430 }; 431 } 383 432 return text; 384 433 } 385 386 function bindFeedEvent() {387 feed.children("li").mouseover(function() {434 435 function bindFeedEvent() { 436 feed.children("li").mouseover(function() { 388 437 feed.children("li").removeClass("auto-focus"); 389 438 $(this).addClass("auto-focus"); 390 439 focuson = $(this); 391 440 }); 392 393 feed.children("li").mouseout(function() {441 442 feed.children("li").mouseout(function() { 394 443 $(this).removeClass("auto-focus"); 395 444 focuson = null; 396 445 }); 397 446 } 398 399 function removeFeedEvent() {447 448 function removeFeedEvent() { 400 449 feed.children("li").unbind("mouseover"); 401 450 feed.children("li").unbind("mouseout"); 402 feed.mousemove(function() {451 feed.mousemove(function() { 403 452 bindFeedEvent(); 404 453 feed.unbind("mousemove"); 405 454 }); 406 455 } 407 408 function bindEvents() {456 457 function bindEvents() { 409 458 var maininput = $("#" + elemid + "_annoninput").children(".maininput"); 410 459 bindFeedEvent(); 411 460 feed.children("li").unbind("mousedown"); 412 feed.children("li").mousedown(function() {461 feed.children("li").mousedown(function() { 413 462 var option = $(this); 414 addItem(option.text(), option.attr("rel") );463 addItem(option.text(), option.attr("rel"), 0, 0, 1); 415 464 feed.hide(); 416 browser_msie ? browser_msie_frame.hide() : '';417 465 complete.hide(); 418 466 }); 419 467 420 468 maininput.unbind("keydown"); 421 maininput.keydown(function(event) {469 maininput.keydown(function(event) { 422 470 if (event.keyCode == 191) { 423 471 event.preventDefault(); 424 472 return false; 425 473 } 426 474 427 475 if (event.keyCode != 8) { 428 476 holder.children("li.bit-box.deleted").removeClass("deleted"); 429 477 } 430 431 if ( event.keyCode == 13&& checkFocusOn()) {478 479 if ((event.keyCode == 13 || event.keyCode == 9) && checkFocusOn()) { 432 480 var option = focuson; 433 addItem(option.text(), option.attr("rel") );481 addItem(option.text(), option.attr("rel"), 0, 0, 1); 434 482 complete.hide(); 435 483 event.preventDefault(); … … 437 485 return false; 438 486 } 439 440 if ( event.keyCode == 13&& !checkFocusOn()) {487 488 if ((event.keyCode == 13 || event.keyCode == 9) && !checkFocusOn()) { 441 489 if (options.newel) { 442 490 var value = xssPrevent($(this).val()); 443 addItem(value, value );491 addItem(value, value, 0, 0, 1); 444 492 complete.hide(); 445 493 event.preventDefault(); 446 494 focuson = null; 447 } 448 return false; 449 } 450 495 return false; 496 } 497 498 if (options.addontab) { 499 focuson = feed.children("li:visible:first"); 500 var option = focuson; 501 addItem(option.text(), option.attr("rel"), 0, 0, 1); 502 complete.hide(); 503 event.preventDefault(); 504 focuson = null; 505 return false; 506 } 507 } 508 451 509 if (event.keyCode == 40) { 452 510 removeFeedEvent(); … … 455 513 feed.get(0).scrollTop = 0; 456 514 } 457 else 515 else{ 458 516 focuson.removeClass("auto-focus"); 459 517 focuson = focuson.nextAll("li:visible:first"); … … 473 531 feed.get(0).scrollTop = parseInt(focuson.get(0).scrollHeight, 10) * (parseInt(feed.children("li:visible").length, 10) - Math.round(options.height / 2)); 474 532 } 475 else 533 else{ 476 534 focuson.removeClass("auto-focus"); 477 535 focuson = focuson.prevAll("li:visible:first"); … … 487 545 }); 488 546 } 489 490 function maxItems() {547 548 function maxItems() { 491 549 if (options.maxitems != 0) { 492 550 if (holder.children("li.bit-box").length < options.maxitems) { 493 551 return true; 494 552 } 495 else 553 else{ 496 554 return false; 497 555 } 498 556 } 499 557 } 500 501 function addTextItem(value) {558 559 function addTextItem(value) { 502 560 if (options.newel && maxItems()) { 503 561 feed.children("li[fckb=1]").remove(); … … 513 571 counter++; 514 572 } 515 else 573 else{ 516 574 return; 517 575 } 518 576 } 519 520 function funCall(func, item) {577 578 function funCall(func, item) { 521 579 var _object = ""; 522 580 for (i = 0; i < item.get(0).attributes.length; i++) { … … 526 584 } 527 585 _object = "{" + _object + " notinuse: 0}"; 528 try { 529 eval(func + "(" + _object + ")"); 530 } 531 catch (ex) { 532 }; 533 } 534 535 function checkFocusOn(){ 586 func.call(func, _object); 587 } 588 589 function checkFocusOn() { 536 590 if (focuson == null) { 537 591 return false; … … 542 596 return true; 543 597 } 544 545 function xssPrevent(string) {598 599 function xssPrevent(string) { 546 600 string = string.replace(/[\"\'][\s]*javascript:(.*)[\"\']/g, "\"\""); 547 601 string = string.replace(/script(.*)/g, ""); … … 550 604 return string; 551 605 } 552 606 553 607 var options = $.extend({ 554 608 json_url: null, … … 556 610 height: "10", 557 611 newel: false, 612 addontab: false, 558 613 firstselected: false, 559 614 filter_case: false, 560 filter_ hide: false,615 filter_selected: false, 561 616 complete_text: "Start to type...", 562 617 maxshownitems: 30, 563 maxitems: 0, 564 onselect: "", 565 onremove: "" 566 }, opt); 567 618 maxitems: 10, 619 onselect: null, 620 onremove: null, 621 attachto: null, 622 delay: 350 623 }, 624 opt); 625 568 626 //system variables 569 627 var holder = null; … … 576 634 var focuson = null; 577 635 var deleting = 0; 578 var browser_msie = "\v" == "v"; 579 var browser_msie_frame; 580 636 var complete_hover = 1; 637 581 638 var element = $(this); 582 639 var elemid = element.attr("id"); 583 640 init(); 584 641 585 642 return this; 586 643 });
Note: See TracChangeset
for help on using the changeset viewer.