/** * Inputosaurus Text * * Must be instantiated on an element * Allows multiple input items. Each item is represented with a removable tag that appears to be inside the input area. * * @requires: * * jQuery 1.7+ * jQueryUI 1.8+ Core * * @version 0.1.6 * @author Dan Kielp * @created October 3,2012 * * @modified by RainLoop Team * @modified by DJMaze */ (function($) { var inputosaurustext = { version: "0.1.6", fakeSpan: $(''), eventprefix: "inputosaurus", options: { // bindable events // // 'change' - triggered whenever a tag is added or removed (should be similar to binding the the change event of the instantiated input // 'keyup' - keyup event on the newly created input // while typing, the user can separate values using these delimiters // the value tags are created on the fly when an inputDelimiter is detected inputDelimiters : [',', ';'], // this separator is used to rejoin all input items back to the value of the original outputDelimiter : ',', allowDuplicates : false, allowDragAndDrop : true, focusCallback : null, parseOnBlur : false, // optional wrapper for widget wrapperElement : null, width : null, // simply passing an autoComplete source (array, string or function) will instantiate autocomplete functionality autoCompleteSource : '', // When forcing users to select from the autocomplete list, allow them to press 'Enter' to select an item if it's the only option left. activateFinalResult : false, // manipulate and return the input value after parseInput() parsing // the array of tag names is passed and expected to be returned as an array after manipulation parseHook : null, elementHook : null, // define a placeholder to display when the input is empty placeholder: null }, _create: function() { var widget = this, els = {}, o = widget.options, placeholder = o.placeholder || this.element.attr('placeholder') || null; this._chosenValues = []; // Create the elements els.ul = $(''); if (this.options.allowDragAndDrop) { els.ul.droppable({ 'drop': function(event, ui) { ui.draggable.addClass('inputosaurus-dropped'); els.input.val(ui.draggable.data('inputosaurus-value')); if (ui.draggable.__widget) { ui.draggable.__widget._removeDraggedTag(ui.draggable); } widget.parseInput(); } }); } els.input = $(''); // els.input = $(''); els.inputCont = $('
  • '); els.origInputCont = $('
  • '); els.lastEdit = ''; els.input.on('focus', function () { widget._focusTrigger(true); }).on('blur', function () { widget._focusTrigger(false); }); // define starting placeholder if (placeholder) { o.placeholder = placeholder; els.input.attr('placeholder', o.placeholder); if (o.width) { els.input.css('min-width', o.width - 50); } } o.wrapperElement && o.wrapperElement.append(els.ul); this.element.replaceWith(o.wrapperElement || els.ul); els.origInputCont.append(this.element).hide(); els.inputCont.append(els.input); els.ul.append(els.inputCont); els.ul.append(els.origInputCont); o.width && els.ul.css('width', o.width); this.elements = els; widget._attachEvents(); // if instantiated input already contains a value, parse that junk if($.trim(this.element.val())){ els.input.val( this.element.val() ); this.parseInput(); } this._instAutocomplete(); }, _focusTriggerTimer : 0, _focusTrigger : function (bValue) { var widget = this; window.clearTimeout(this._focusTriggerTimer); this._focusTriggerTimer = window.setTimeout(function () { widget.elements.ul[!bValue ? 'removeClass' : 'addClass']('inputosaurus-focused'); if (widget.options.focusCallback) { widget.options.focusCallback(bValue); } }, 10); }, _instAutocomplete : function() { if(this.options.autoCompleteSource){ var widget = this; this.elements.input.autocomplete({ position : { of : this.elements.ul }, source : this.options.autoCompleteSource, minLength : 1, autoFocus : true, select : function(ev, ui){ ev.preventDefault(); widget.elements.input.val(ui.item.value); widget.parseInput(); }, open : function() { var menu = $(this).data('ui-autocomplete').menu, $menuItems; menu.element.width(widget.elements.ul.outerWidth() - 6); // auto-activate the result if it's the only one if(widget.options.activateFinalResult){ $menuItems = menu.element.find('li'); // activate single item to allow selection upon pressing 'Enter' if($menuItems.length === 1){ menu[menu.activate ? 'activate' : 'focus']($.Event('click'), $menuItems); } } }, focus: function () { return false; } }); } }, _autoCompleteMenuPosition : function() { var widget; if(this.options.autoCompleteSource){ widget = this.elements.input.data('ui-autocomplete'); widget && widget.menu.element.position({ of: this.elements.ul, my: 'left top', at: 'left bottom', collision: 'none' }); } }, /*_closeAutoCompleteMenu : function() { if(this.options.autoCompleteSource){ this.elements.input.autocomplete('close'); } },*/ parseInput : function(ev) { var widget = (ev && ev.data.widget) || this, val, hook, delimiterFound = false, values = []; val = widget.elements.input.val(); if (val) { if ($.isFunction(widget.options.splitHook)) { hook = widget.options.splitHook(val); } else { delimiterFound = widget._containsDelimiter(val); } } if (hook) { values = hook; } else if(delimiterFound !== false){ values = val.split(delimiterFound); } else if(!ev || ev.which === $.ui.keyCode.ENTER && !$('.ui-menu-item .ui-state-focus').length && !$('#ui-active-menuitem').length){ values.push(val); ev && ev.preventDefault(); // prevent autoComplete menu click from causing a false 'blur' } else if(ev.type === 'blur' && !$('#ui-active-menuitem').length){ values.push(val); } $.isFunction(widget.options.parseHook) && (values = widget.options.parseHook(values)); if(values.length){ widget._setChosen(values); widget.elements.input.val(''); widget._resizeInput(); } widget._resetPlaceholder(); }, _inputFocus : function(ev) { var widget = ev.data.widget || this; widget.elements.input.value || (widget.options.autoCompleteSource.length && widget.elements.input.autocomplete('search', '')); }, _inputKeypress : function(ev) { var widget = ev.data.widget || this; ev.type === 'keyup' && widget._trigger('keyup', ev, widget); switch(ev.which){ case $.ui.keyCode.BACKSPACE: ev.type === 'keydown' && widget._inputBackspace(ev); break; case $.ui.keyCode.LEFT: ev.type === 'keydown' && widget._inputBackspace(ev); break; default : widget.parseInput(ev); widget._resizeInput(ev); } // reposition autoComplete menu as