/*jslint eqeq: true, plusplus: true, undef: true, sloppy: true, vars: true, forin: true */ (function ($) { var defaults = { inputClass: '', invalid: [], rtl: false, showInput: true, group: false, groupLabel: 'Groups' }; $.mobiscroll.presetShort('select'); $.mobiscroll.presets.select = function (inst) { var orig = $.extend({}, inst.settings), s = $.extend(inst.settings, defaults, orig), elm = $(this), multiple = elm.prop('multiple'), id = this.id + '_dummy', option = multiple ? (elm.val() ? elm.val()[0] : $('option', elm).attr('value')) : elm.val(), group = elm.find('option[value="' + option + '"]').parent(), prev = group.index() + '', gr = prev, prevent, l1 = $('label[for="' + this.id + '"]').attr('for', id), l2 = $('label[for="' + id + '"]'), label = s.label !== undefined ? s.label : (l2.length ? l2.text() : elm.attr('name')), invalid = [], origValues = [], main = {}, grIdx, optIdx, timer, input, roPre = s.readonly, w; function genWheels() { var cont, wg = 0, values = [], keys = [], w = [[]]; if (s.group) { if (s.rtl) { wg = 1; } $('optgroup', elm).each(function (i) { values.push($(this).attr('label')); keys.push(i); }); w[wg] = [{ values: values, keys: keys, label: s.groupLabel }]; cont = group; wg += (s.rtl ? -1 : 1); } else { cont = elm; } values = []; keys = []; $('option', cont).each(function () { var v = $(this).attr('value'); values.push($(this).text()); keys.push(v); if ($(this).prop('disabled')) { invalid.push(v); } }); w[wg] = [{ values: values, keys: keys, label: label }]; return w; } function setVal(v, fill, change) { var value = []; if (multiple) { var sel = [], i = 0; for (i in inst._selectedValues) { sel.push(main[i]); value.push(i); } input.val(sel.join(', ')); } else { input.val(v); value = fill ? inst.values[optIdx] : null; } if (fill) { elm.val(value); if (change) { prevent = true; elm.change(); } } } function onTap(li) { if (multiple && li.hasClass('dw-v') && li.closest('.dw').find('.dw-ul').index(li.closest('.dw-ul')) == optIdx) { var val = li.attr('data-val'), selected = li.hasClass('dw-msel'); if (selected) { li.removeClass('dw-msel').removeAttr('aria-selected'); delete inst._selectedValues[val]; } else { li.addClass('dw-msel').attr('aria-selected', 'true'); inst._selectedValues[val] = val; } if (inst.live) { setVal(val, true, true); } return false; } } // if groups is true and there are no groups fall back to no grouping if (s.group && !$('optgroup', elm).length) { s.group = false; } if (!s.invalid.length) { s.invalid = invalid; } if (s.group) { if (s.rtl) { grIdx = 1; optIdx = 0; } else { grIdx = 0; optIdx = 1; } } else { grIdx = -1; optIdx = 0; } $('#' + id).remove(); input = $(''); if (s.showInput) { input.insertBefore(elm); } $('option', elm).each(function () { main[$(this).attr('value')] = $(this).text(); }); inst.attachShow(input); var v = elm.val() || [], i = 0; for (i; i < v.length; i++) { inst._selectedValues[v[i]] = v[i]; } setVal(main[option]); elm.off('.dwsel').on('change.dwsel', function () { if (!prevent) { inst.setValue(multiple ? elm.val() || [] : [elm.val()], true); } prevent = false; }).addClass('dw-hsel').attr('tabindex', -1).closest('.ui-field-contain').trigger('create'); // Extended methods // --- if (!inst._setValue) { inst._setValue = inst.setValue; } inst.setValue = function (d, fill, time, temp, change) { var value, v = $.isArray(d) ? d[0] : d; option = v !== undefined ? v : $('option', elm).attr('value'); if (multiple) { inst._selectedValues = {}; var i = 0; for (i; i < d.length; i++) { inst._selectedValues[d[i]] = d[i]; } } if (s.group) { group = elm.find('option[value="' + option + '"]').parent(); gr = group.index(); value = s.rtl ? [option, group.index()] : [group.index(), option]; if (gr !== prev) { // Need to regenerate wheels, if group changed s.wheels = genWheels(); inst.changeWheel([optIdx]); prev = gr + ''; } } else { value = [option]; } inst._setValue(value, fill, time, temp, change); // Set input/select values if (fill) { var changed = multiple ? true : option !== elm.val(); setVal(main[option], changed, change); } }; inst.getValue = function (temp) { var val = temp ? inst.temp : inst.values; return val[optIdx]; }; // --- return { width: 50, wheels: w, headerText: false, multiple: multiple, anchor: input, formatResult: function (d) { return main[d[optIdx]]; }, parseValue: function () { var v = elm.val() || [], i = 0; if (multiple) { inst._selectedValues = {}; for (i; i < v.length; i++) { inst._selectedValues[v[i]] = v[i]; } } option = multiple ? (elm.val() ? elm.val()[0] : $('option', elm).attr('value')) : elm.val(); group = elm.find('option[value="' + option + '"]').parent(); gr = group.index(); prev = gr + ''; return s.group && s.rtl ? [option, gr] : s.group ? [gr, option] : [option]; }, validate: function (dw, i, time) { if (i === undefined && multiple) { var v = inst._selectedValues, j = 0; $('.dwwl' + optIdx + ' .dw-li', dw).removeClass('dw-msel').removeAttr('aria-selected'); for (j in v) { $('.dwwl' + optIdx + ' .dw-li[data-val="' + v[j] + '"]', dw).addClass('dw-msel').attr('aria-selected', 'true'); } } if (i === grIdx) { gr = inst.temp[grIdx]; if (gr !== prev) { group = elm.find('optgroup').eq(gr); gr = group.index(); option = group.find('option').eq(0).val(); option = option || elm.val(); s.wheels = genWheels(); if (s.group) { inst.temp = s.rtl ? [option, gr] : [gr, option]; s.readonly = [s.rtl, !s.rtl]; clearTimeout(timer); timer = setTimeout(function () { inst.changeWheel([optIdx], undefined, true); s.readonly = roPre; prev = gr + ''; }, time * 1000); return false; } } else { s.readonly = roPre; } } else { option = inst.temp[optIdx]; } var t = $('.dw-ul', dw).eq(optIdx); $.each(s.invalid, function (i, v) { $('.dw-li[data-val="' + v + '"]', t).removeClass('dw-v'); }); }, onBeforeShow: function (dw) { if (multiple && s.counter) { s.headerText = function () { var length = 0; $.each(inst._selectedValues, function () { length++; }); return length + " " + s.selectedText; }; } s.wheels = genWheels(); if (s.group) { inst.temp = s.rtl ? [option, group.index()] : [group.index(), option]; } }, onClear: function (dw) { inst._selectedValues = {}; input.val(''); $('.dwwl' + optIdx + ' .dw-li', dw).removeClass('dw-msel').removeAttr('aria-selected'); }, onMarkupReady: function (dw) { dw.addClass('dw-select'); $('.dwwl' + grIdx, dw).on('mousedown touchstart', function () { clearTimeout(timer); }); if (multiple) { dw.addClass('dwms'); $('.dwwl', dw).eq(optIdx).addClass('dwwms').attr('aria-multiselectable', 'true'); $('.dwwl', dw).on('keydown', function (e) { if (e.keyCode == 32) { // Space e.preventDefault(); e.stopPropagation(); onTap($('.dw-sel', this)); } }); origValues = $.extend({}, inst._selectedValues); } }, onValueTap: onTap, onSelect: function (v) { setVal(v, true, true); if (s.group) { inst.values = null; } }, onCancel: function () { if (s.group) { inst.values = null; } if (!inst.live && multiple) { inst._selectedValues = $.extend({}, origValues); } }, onChange: function (v) { if (inst.live && !multiple) { input.val(v); prevent = true; elm.val(inst.temp[optIdx]).change(); } }, onDestroy: function () { input.remove(); elm.removeClass('dw-hsel').removeAttr('tabindex'); } }; }; })(jQuery);