var ComboAutoBox = { // constructor addTo: function (container, options) { // generatea an ID based on current time var generateShortId = function(prefix) { var now = 0; while ($('input[name*="[' + prefix +"-" + now + ']"]').length != 0) { now++; } return prefix + "-" + now; }; // generatea an ID based on current time var generateAnId = function(prefix) { var now = new Date().getTime(); while ($("#" + prefix +"-" + now).length != 0) { now++; } return prefix + "-" + now; }; var splitValidEmails = function (inputId, inputValue) { if ((options.type != 'multiple') || (!options.email)) { return false; } var emails = inputValue.split(/[\,\s\;]+/); for (var i = 0; i < emails.length; i++) { if (!emails[i].match(/[^@\s]+@([^@\s]+\.)+[^@\s]+/)) { return false; } } $('#' + inputId).autocomplete( "close" ); if ((options.source_not_found) && (!options.not_found_accepted)) { selectData('', ''); } else { for (var i = 0; i < emails.length; i++) { addMultipleItem(inputId, emails[i], emails[i]); selectData(emails[i], emails[i]); } } $('#' + inputId).val(''); return true; } // binds autocomplete to text field var bindAutoComplete = function (inputId) { var previuosValue = ''; $('#' + inputId).keydown(function(e) { if ((e.keyCode == 8) && ($('#' + inputId).val() == '')) { if (options.type == 'multiple') { removeLastMultipleItem(); } else if (options.type == 'searchable') { removeLastSearchableItemForRansack(); } } else if ((e.keyCode == 9) && (inputVal != '') && (options.source_not_found) && (options.type == 'simple')) { $('#' + inputId).autocomplete( "close"); if (!options.not_found_accepted) { $('#' + inputId).val(''); } selectData($('#' + inputId).val(), $('#' + inputId).val()); return true; } else if ((e.keyCode == 9) && (inputVal != '') && (options.source_not_found) && (options.type == 'multiple')) { $('#' + inputId).autocomplete( "close"); var inputVal = $('#' + inputId).val().replace(/\t$/, ''); if (options.not_found_accepted) { addMultipleItem(inputId, inputVal, inputVal); } else { inputVal = ''; } selectData(inputVal, inputVal); $('#' + inputId).val(''); return true; } }); // CTRL+V or CMD+V $('#' + inputId).bind('paste', function() { var $this = $(this); setTimeout(function(){ splitValidEmails(inputId, $this.val()); }, 20); //just break the callstack to let the event finish }); $('#' + inputId).keypress(function(e) { // 44 is "," - 32 is SPACE - 59 is ";" if (((e.which === 32) || (e.which === 44) || (e.which === 59)) && (options.type == 'multiple') && (options.email) && ($('#' + inputId).val().match(/[^@\s]+@([^@\s]+\.)+[^@\s]+/))) { $('#' + inputId).autocomplete( "close" ); if ((options.source_not_found) && (!options.not_found_accepted)) { $('#' + inputId).val(''); } else { addMultipleItem(inputId, $('#' + inputId).val(), $('#' + inputId).val()); } selectData($('#' + inputId).val(), $('#' + inputId).val()); setTimeout(function(){ $('#' + inputId).val(''); }, 20); } else if ((e.which === 13) && ($('#' + inputId).val() != '')) { if (options.type == 'full') { $('#' + inputId).autocomplete( "close" ); selectData($('#' + inputId).val(), $('#' + inputId).val()); } else if ((options.source_not_found) && (options.type == 'simple')) { $('#' + inputId).autocomplete( "close"); if (!options.not_found_accepted) { $('#' + inputId).val(''); } selectData($('#' + inputId).val(), $('#' + inputId).val()); } else if (options.type == 'multiple') { $('#' + inputId).autocomplete( "close" ); if ((options.source_not_found) && (!options.not_found_accepted)) { $('#' + inputId).val(''); } else { addMultipleItem(inputId, $('#' + inputId).val(), $('#' + inputId).val()); } selectData($('#' + inputId).val(), $('#' + inputId).val()); $('#' + inputId).val(''); } else if (options.type == 'searchable') { try { $('#' + inputId).autocomplete('close'); var item = sourceForSearchable(inputId)[0]; addSearchableItemForRansack(inputId, item.id, item.label); selectData(item.id, item.label); $('#' + inputId).val(''); } catch (error) { } } return false; } else if ((e.which === 13) && ($('#' + inputId).val() == '')) { return false; } }); $('#' + inputId).autocomplete({ source: setAutoCompleteSource(inputId), select: function(event, ui) { if ((options.source_not_found) && (options.type == 'simple')) { if (!options.not_found_accepted) { $('#' + inputId).val(''); } selectData($('#' + inputId).val(), $('#' + inputId).val()); return false; } if ((options.source_not_found) && (options.type == 'multiple')) { var inputVal = $('#' + inputId).val(); $('#' + inputId).val(''); if (options.not_found_accepted) { addMultipleItem(inputId, inputVal, inputVal); } else { inputVal = ''; } selectData(inputVal, inputVal); return false; } else if (options.type == 'simple') { return selectData(ui.item.id, ui.item.label); } else if (options.type == 'full') { return selectData($('#' + inputId).val(), $('#' + inputId).val()); } else if (options.type == 'multiple') { $('#' + inputId).val(''); addMultipleItem(inputId, ui.item.id, ui.item.label); selectData(ui.item.id, ui.item.label); return false; } else if (options.type == 'searchable') { $('#' + inputId).val(''); addSearchableItemForRansack(inputId, ui.item.id, ui.item.label); selectData(ui.item.id, ui.item.label); return false; } }, search: function(event, ui) { if (options.type == 'searchable') { $('#' + inputId).autocomplete("option", { source: setAutoCompleteSource(inputId) }); } }, change: function (event, ui) { if ((!ui.item) && (!options.source_not_found)) { $(this).val(''); selectData('', ''); } }, focus: function (event, ui) { event.preventDefault(); }, }); }; // set autocomplete source var setAutoCompleteSource = function (inputId) { if (options.type == 'searchable') { return sourceForSearchable(inputId); } else { return function(request, response) { if (typeof options.source == 'string') { var term = 'term=' + $('#' + inputId).val(); var params = (options.data == null) ? term : options.data + '&' + term; $.getJSON(options.source + '?' + params, function(data) { if ((data.length == 0) && ((options.type == 'simple') || (options.type == 'multiple'))) { return response(sourceForNotFound(inputId)); } else { options.source_not_found = false; response($.map(data, function (item) { return item; })); } }); } else { var selectedSource = new Array(); $.each(options.source, function( index, value ){ var pattern = new RegExp($('#' + inputId).val(), 'i'); if (value.label.match(pattern)) { selectedSource.push(value); } }); if ((selectedSource.length == 0) && ((options.type == 'simple') || (options.type == 'multiple'))) { return response(sourceForNotFound(inputId)); } else { options.source_not_found = false; return response(selectedSource); } } } } }; // source items for not found item var sourceForNotFound = function (inputId) { options.source_not_found = true; return [ { id: $('#' + inputId).val(), label: '"' + $('#' + inputId).val() + '" ' + options.not_found_message } ]; } // source items for searchable var sourceForSearchable = function (inputId) { var new_source = new Array(); var operators = i18nMath(options.lang); $.each(options.source, function(i){ validIndexes = validSource(options.source[i]); $.each(operators, function(j){ if (validIndexes.indexOf(j) >= 0) { new_source.push( { id: options.source[i]['id'] + '_' + operators[j]['id'], label: options.source[i]['label'] + ' ' + operators[j]['label'] + ' ' + $('#' + inputId).val()} ); } }); }); return new_source; } // get i18n math comparisons var i18nMath = function (language) { var operators = new Array(); switch(language.toLowerCase()) { case 'en': operators = [ { id: 'cont', label: 'contains' }, { id: 'eq', label: 'equal' }, { id: 'gteq', label: 'greater or equal' }, { id: 'lteq', label: 'less or equal' } ]; break; case 'pt-br': operators = [ { id: 'cont', label: 'contém' }, { id: 'eq', label: 'igual' }, { id: 'gteq', label: 'maior ou igual' }, { id: 'lteq', label: 'menor ou igual' } ]; break; case 'pt': operators = [ { id: 'cont', label: 'contém' }, { id: 'eq', label: 'igual' }, { id: 'gteq', label: 'maior ou igual' }, { id: 'lteq', label: 'menor ou igual' } ]; break; case 'fr': operators = [ { id: 'cont', label: 'contient' }, { id: 'eq', label: 'égal' }, { id: 'gteq', label: 'supérieur ou égal' }, { id: 'lteq', label: 'inférieur ou égal' } ]; break; case 'es': operators = [ { id: 'cont', label: 'contiene' }, { id: 'eq', label: 'igual' }, { id: 'gteq', label: 'mayor o igual' }, { id: 'lteq', label: 'menos o igual' } ]; break; case 'it': operators = [ { id: 'cont', label: 'contiene' }, { id: 'eq', label: 'uguale' }, { id: 'gteq', label: 'maggiore o uguale' }, { id: 'lteq', label: 'minore o uguale' } ]; break; default: operators = [ { id: 'cont', label: '~=' }, { id: 'eq', label: '=' }, { id: 'gteq', label: '>=' }, { id: 'lteq', label: '<=' } ]; } return operators; }; var i18nShowSearchOptions = function (language) { var title = 'Show search options'; switch(language.toLowerCase()) { case 'pt-br': title = 'Exibir opções de busca'; break; case 'pt': title = 'Exibir opções de busca'; break; case 'fr': title = 'Afficher les options de recherche'; break; case 'es': title = 'Mostrar opciones de búsqueda'; break; case 'it': title = 'Visualizza opzioni di ricerca'; break; } return title; }; var i18nSourceNotFound = function (language) { var title = 'not found'; switch(language.toLowerCase()) { case 'pt-br': title = 'não encontrado'; break; case 'pt': title = 'não encontrado'; break; case 'fr': title = 'pas trouvé'; break; case 'es': title = 'no encontrado'; break; case 'it': title = 'non trovato'; break; } return title; }; var i18nSelectAll = function (language) { var title = 'Select All'; switch(language.toLowerCase()) { case 'pt-br': title = 'Selecionar Tudo'; break; case 'pt': title = 'Selecionar Tudo'; break; case 'fr': title = 'Sélectionner Tout'; break; case 'es': title = 'Seleccionar Todo'; break; case 'it': title = 'Seleziona Tutto'; break; } return title; }; // generates text field with html options var generateInputTag = function () { var html = 'input type="text"'; if (options.html != null) { $.each(options.html, function(key, value) { if ((key == 'name') && ((options.type == 'multiple') || (options.type == 'searchable'))) { return true; } html = html + ' '+ key +'="' + value + '"'; }); } if ((options.html == null) || (options.html.id == null)) { html = html + ' id="' + generateAnId('combo-auto-box') + '"'; } if ((options.bootstrap) && (options.type == "simple")) { html = html + ' class="form-control" ' } return '<' + html + '>'; }; // On click opens modal image tag inside "i" tag through css var generateExpander = function () { if (options.type == 'simple') { if (options.bootstrap) { return ''; } else { return ''; } } else if (options.type == 'multiple') { if (options.style == "mail") { return '' + options.label + ''; } else { return ''; } } }; var adjustExpanderImage = function() { if ((options.bootstrap) && (options.type == "simple")) { return true; } if (options.type == 'simple') { spanTag = $('#' + container + ' > div.container-combo-auto-box > span.simple'); inputWidth = getTextFieldWidth(textField); inputHeight = getTextFieldHeight(textField); inputBorderTop = getTextFieldBorder(textField, 'top'); inputBorderBottom = getTextFieldBorder(textField, 'bottom'); if (inputHeight % 2 != 0) { inputBorderTop = inputBorderTop + 2; } iWidth = 20; if (inputWidth < 20) { iWidth = 10; } spanTag.css('margin-top', inputBorderTop.toString() + 'px'); spanTag.css('margin-left', (inputWidth - iWidth + 4).toString() + 'px'); spanTag.children(':first').css('width', iWidth.toString() + 'px'); spanTag.children(':first').css('height', inputHeight.toString() + 'px'); return true; } else if (options.type == 'multiple') { inputTop = 0; try { spanHeight = $('#' + container + ' > div.container-combo-auto-box > span.multiple').height(); if (spanHeight == 0) { spanHeight = 20; } inputTop = (getTextFieldHeight(textField) / 2) - ((getTextFieldBorder(textField, 'top') + spanHeight) / 2) - 2; $('#' + container + ' > div.container-combo-auto-box > span.multiple').css('margin-top', (inputTop).toString() + 'px'); } catch (error) { } } else { return false; } } var getTextFieldWidth = function (textField) { var widthTotal = 0; if (textField.width() != null) { widthTotal = widthTotal + textField.width(); } if (textField.css('padding-right') != null) { padding_right = textField.css('padding-right').toString().replace(/[a-zA-Z]+/g, ''); widthTotal = widthTotal + parseInt(padding_right); } return widthTotal; } var getTextFieldBorder = function (textField, side) { var heightTotal = 0; try { var matched = textField.css('border-' + side).match(/([\d\.]+)(px)/); heightTotal = heightTotal + parseFloat(matched[1]); } catch (error) { } return heightTotal; } var getTextFieldHeight = function (textField) { var heightTotal = 0; try { if (textField.height() != null) { heightTotal = heightTotal + textField.height(); } } catch (error) {} try { if (textField.css('padding-top') != null) { padding_top = textField.css('padding-top').toString().replace(/[a-zA-Z]+/g, ''); heightTotal = heightTotal + parseInt(padding_top); } } catch (error) {} try { if (textField.css('padding-bottom') != null) { padding_bottom = textField.css('padding-bottom').toString().replace(/[a-zA-Z]+/g, ''); heightTotal = heightTotal + parseInt(padding_bottom); } } catch (error) {} return heightTotal; } // Global div for combo auto box var generateDivTag = function () { var klass = 'container-combo-auto-box' if (options.type == 'multiple') { if (options.bootstrap) { klass = klass + '-bootstrap'; } klass = klass + ' multiple'; } else if (options.type == 'searchable') { klass = klass + ' searchable' } else if ((options.type == 'simple') && (options.bootstrap)) { klass = klass + '-bootstrap input-group' } return '