377 lines
12 KiB
JavaScript
377 lines
12 KiB
JavaScript
/*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 = $('<input type="text" id="' + id + '" class="' + s.inputClass + '" readonly />');
|
|
|
|
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);
|