/*
* jQuery Form Styler v1.7.8
* https://github.com/Dimox/jQueryFormStyler
*
* Copyright 2012-2017 Dimox (http://dimox.name/)
* Released under the MIT license.
*
* Date: 2017.02.17
*
*/
;(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// CommonJS
module.exports = factory($ || require('jquery'));
} else {
factory(jQuery);
}
}(function($) {
'use strict';
var pluginName = 'styler',
defaults = {
idSuffix: '-styler',
filePlaceholder: 'Файл не выбран',
fileBrowse: 'Обзор...',
fileNumber: 'Выбрано файлов: %s',
selectPlaceholder: 'Выберите...',
selectSearch: false,
selectSearchLimit: 10,
selectSearchNotFound: 'Совпадений не найдено',
selectSearchPlaceholder: 'Поиск...',
selectVisibleOptions: 0,
singleSelectzIndex: '100',
selectSmartPositioning: true,
locale: 'ru',
locales: {
'en': {
filePlaceholder: 'No file selected',
fileBrowse: 'Browse...',
fileNumber: 'Selected files: %s',
selectPlaceholder: 'Select...',
selectSearchNotFound: 'No matches found',
selectSearchPlaceholder: 'Search...'
}
},
onSelectOpened: function() {},
onSelectClosed: function() {},
onFormStyled: function() {}
};
function Plugin(element, options) {
this.element = element;
this.options = $.extend({}, defaults, options);
var locale = this.options.locale;
if (this.options.locales[locale] !== undefined) {
$.extend(this.options, this.options.locales[locale]);
}
this.init();
}
Plugin.prototype = {
// инициализация
init: function() {
var el = $(this.element);
var opt = this.options;
var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/i) && !navigator.userAgent.match(/(Windows\sPhone)/i)) ? true : false;
var Android = (navigator.userAgent.match(/Android/i) && !navigator.userAgent.match(/(Windows\sPhone)/i)) ? true : false;
function Attributes() {
if (el.attr('id') !== undefined && el.attr('id') !== '') {
this.id = el.attr('id') + opt.idSuffix;
}
this.title = el.attr('title');
this.classes = el.attr('class');
this.data = el.data();
}
// checkbox
if (el.is(':checkbox')) {
var checkboxOutput = function() {
var att = new Attributes();
var checkbox = $('
')
.attr({
id: att.id,
title: att.title
})
.addClass(att.classes)
.data(att.data)
;
// прячем оригинальный чекбокс
el.css({
position: 'absolute',
zIndex: '-1',
opacity: 0,
margin: 0,
padding: 0
}).after(checkbox).prependTo(checkbox);
checkbox.attr('unselectable', 'on').css({
'-webkit-user-select': 'none',
'-moz-user-select': 'none',
'-ms-user-select': 'none',
'-o-user-select': 'none',
'user-select': 'none',
display: 'inline-block',
position: 'relative',
overflow: 'hidden'
});
if (el.is(':checked')) checkbox.addClass('checked');
if (el.is(':disabled')) checkbox.addClass('disabled');
// клик на псевдочекбокс
checkbox.click(function(e) {
e.preventDefault();
if (!checkbox.is('.disabled')) {
if (el.is(':checked')) {
el.prop('checked', false);
checkbox.removeClass('checked');
} else {
el.prop('checked', true);
checkbox.addClass('checked');
}
el.focus().change();
}
});
// клик на label
el.closest('label').add('label[for="' + el.attr('id') + '"]').on('click.styler', function(e) {
if (!$(e.target).is('a') && !$(e.target).closest(checkbox).length) {
checkbox.triggerHandler('click');
e.preventDefault();
}
});
// переключение по Space или Enter
el.on('change.styler', function() {
if (el.is(':checked')) checkbox.addClass('checked');
else checkbox.removeClass('checked');
})
// чтобы переключался чекбокс, который находится в теге label
.on('keydown.styler', function(e) {
if (e.which == 32) checkbox.click();
})
.on('focus.styler', function() {
if (!checkbox.is('.disabled')) checkbox.addClass('focused');
})
.on('blur.styler', function() {
checkbox.removeClass('focused');
});
}; // end checkboxOutput()
checkboxOutput();
// обновление при динамическом изменении
el.on('refresh', function() {
el.closest('label').add('label[for="' + el.attr('id') + '"]').off('.styler');
el.off('.styler').parent().before(el).remove();
checkboxOutput();
});
// end checkbox
// radio
} else if (el.is(':radio')) {
var radioOutput = function() {
var att = new Attributes();
var radio = $('
')
.attr({
id: att.id,
title: att.title
})
.addClass(att.classes)
.data(att.data)
;
// прячем оригинальную радиокнопку
el.css({
position: 'absolute',
zIndex: '-1',
opacity: 0,
margin: 0,
padding: 0
}).after(radio).prependTo(radio);
radio.attr('unselectable', 'on').css({
'-webkit-user-select': 'none',
'-moz-user-select': 'none',
'-ms-user-select': 'none',
'-o-user-select': 'none',
'user-select': 'none',
display: 'inline-block',
position: 'relative'
});
if (el.is(':checked')) radio.addClass('checked');
if (el.is(':disabled')) radio.addClass('disabled');
// определяем общего родителя у радиокнопок с одинаковым name
// http://stackoverflow.com/a/27733847
$.fn.commonParents = function (){
var cachedThis = this;
return cachedThis.first().parents().filter(function () {
return $(this).find(cachedThis).length === cachedThis.length;
});
};
$.fn.commonParent = function (){
return $(this).commonParents().first();
};
// клик на псевдорадиокнопке
radio.click(function(e) {
e.preventDefault();
if (!radio.is('.disabled')) {
var inputName = $('input[name="' + el.attr('name') + '"]');
inputName.commonParent().find(inputName).prop('checked', false).parent().removeClass('checked');
el.prop('checked', true).parent().addClass('checked');
el.focus().change();
}
});
// клик на label
el.closest('label').add('label[for="' + el.attr('id') + '"]').on('click.styler', function(e) {
if (!$(e.target).is('a') && !$(e.target).closest(radio).length) {
radio.triggerHandler('click');
e.preventDefault();
}
});
// переключение стрелками
el.on('change.styler', function() {
el.parent().addClass('checked');
})
.on('focus.styler', function() {
if (!radio.is('.disabled')) radio.addClass('focused');
})
.on('blur.styler', function() {
radio.removeClass('focused');
});
}; // end radioOutput()
radioOutput();
// обновление при динамическом изменении
el.on('refresh', function() {
el.closest('label').add('label[for="' + el.attr('id') + '"]').off('.styler');
el.off('.styler').parent().before(el).remove();
radioOutput();
});
// end radio
// file
} else if (el.is(':file')) {
// прячем оригинальное поле
el.css({
position: 'absolute',
top: 0,
right: 0,
margin: 0,
padding: 0,
opacity: 0,
fontSize: '100px'
});
var fileOutput = function() {
var att = new Attributes();
var placeholder = el.data('placeholder');
if (placeholder === undefined) placeholder = opt.filePlaceholder;
var browse = el.data('browse');
if (browse === undefined || browse === '') browse = opt.fileBrowse;
var file =
$('
' +
'
' + placeholder + '
' +
'
' + browse + '
' +
'
')
.css({
display: 'inline-block',
position: 'relative',
overflow: 'hidden'
})
.attr({
id: att.id,
title: att.title
})
.addClass(att.classes)
.data(att.data)
;
el.after(file).appendTo(file);
if (el.is(':disabled')) file.addClass('disabled');
el.on('change.styler', function() {
var value = el.val();
var name = $('div.jq-file__name', file);
if (el.is('[multiple]')) {
value = '';
var files = el[0].files.length;
if (files > 0) {
var number = el.data('number');
if (number === undefined) number = opt.fileNumber;
number = number.replace('%s', files);
value = number;
}
}
name.text(value.replace(/.+[\\\/]/, ''));
if (value === '') {
name.text(placeholder);
file.removeClass('changed');
} else {
file.addClass('changed');
}
})
.on('focus.styler', function() {
file.addClass('focused');
})
.on('blur.styler', function() {
file.removeClass('focused');
})
.on('click.styler', function() {
file.removeClass('focused');
});
}; // end fileOutput()
fileOutput();
// обновление при динамическом изменении
el.on('refresh', function() {
el.off('.styler').parent().before(el).remove();
fileOutput();
});
// end file
} else if (el.is('input[type="number"]')) {
var numberOutput = function() {
var att = new Attributes();
var number =
$('
' +
'' +
'' +
'
')
.attr({
id: att.id,
title: att.title
})
.addClass(att.classes)
.data(att.data)
;
el.after(number).prependTo(number).wrap('');
if (el.is(':disabled')) number.addClass('disabled');
var min,
max,
step,
timeout = null,
interval = null;
if (el.attr('min') !== undefined) min = el.attr('min');
if (el.attr('max') !== undefined) max = el.attr('max');
if (el.attr('step') !== undefined && $.isNumeric(el.attr('step')))
step = Number(el.attr('step'));
else
step = Number(1);
var changeValue = function(spin) {
var value = el.val(),
newValue;
if (!$.isNumeric(value)) {
value = 0;
el.val('0');
}
if (spin.is('.minus')) {
newValue = Number(value) - step;
} else if (spin.is('.plus')) {
newValue = Number(value) + step;
}
// определяем количество десятичных знаков после запятой в step
var decimals = (step.toString().split('.')[1] || []).length;
if (decimals > 0) {
var multiplier = '1';
while (multiplier.length <= decimals) multiplier = multiplier + '0';
// избегаем появления лишних знаков после запятой
newValue = Math.round(newValue * multiplier) / multiplier;
}
if ($.isNumeric(min) && $.isNumeric(max)) {
if (newValue >= min && newValue <= max) el.val(newValue);
} else if ($.isNumeric(min) && !$.isNumeric(max)) {
if (newValue >= min) el.val(newValue);
} else if (!$.isNumeric(min) && $.isNumeric(max)) {
if (newValue <= max) el.val(newValue);
} else {
el.val(newValue);
}
};
if (!number.is('.disabled')) {
number.on('mousedown', 'div.jq-number__spin', function() {
var spin = $(this);
changeValue(spin);
timeout = setTimeout(function(){
interval = setInterval(function(){ changeValue(spin); }, 40);
}, 350);
}).on('mouseup mouseout', 'div.jq-number__spin', function() {
clearTimeout(timeout);
clearInterval(interval);
}).on('mouseup', 'div.jq-number__spin', function() {
el.change();
});
el.on('focus.styler', function() {
number.addClass('focused');
})
.on('blur.styler', function() {
number.removeClass('focused');
});
}
}; // end numberOutput()
numberOutput();
// обновление при динамическом изменении
el.on('refresh', function() {
el.off('.styler').closest('.jq-number').before(el).remove();
numberOutput();
});
// end number
// select
} else if (el.is('select')) {
var selectboxOutput = function() {
// запрещаем прокрутку страницы при прокрутке селекта
function preventScrolling(selector) {
selector.off('mousewheel DOMMouseScroll').on('mousewheel DOMMouseScroll', function(e) {
var scrollTo = null;
if (e.type == 'mousewheel') { scrollTo = (e.originalEvent.wheelDelta * -1); }
else if (e.type == 'DOMMouseScroll') { scrollTo = 40 * e.originalEvent.detail; }
if (scrollTo) {
e.stopPropagation();
e.preventDefault();
$(this).scrollTop(scrollTo + $(this).scrollTop());
}
});
}
var option = $('option', el);
var list = '';
// формируем список селекта
function makeList() {
for (var i = 0; i < option.length; i++) {
var op = option.eq(i);
var li = '',
liClass = '',
liClasses = '',
id = '',
title = '',
dataList = '',
optionClass = '',
optgroupClass = '',
dataJqfsClass = '';
var disabled = 'disabled';
var selDis = 'selected sel disabled';
if (op.prop('selected')) liClass = 'selected sel';
if (op.is(':disabled')) liClass = disabled;
if (op.is(':selected:disabled')) liClass = selDis;
if (op.attr('id') !== undefined && op.attr('id') !== '') id = ' id="' + op.attr('id') + opt.idSuffix + '"';
if (op.attr('title') !== undefined && option.attr('title') !== '') title = ' title="' + op.attr('title') + '"';
if (op.attr('class') !== undefined) {
optionClass = ' ' + op.attr('class');
dataJqfsClass = ' data-jqfs-class="' + op.attr('class') + '"';
}
var data = op.data();
for (var k in data) {
if (data[k] !== '') dataList += ' data-' + k + '="' + data[k] + '"';
}
if ( (liClass + optionClass) !== '' ) liClasses = ' class="' + liClass + optionClass + '"';
li = '
'+ op.html() +'
';
// если есть optgroup
if (op.parent().is('optgroup')) {
if (op.parent().attr('class') !== undefined) optgroupClass = ' ' + op.parent().attr('class');
li = '
'+ op.html() +'
';
if (op.is(':first-child')) {
li = '
' + op.parent().attr('label') + '
' + li;
}
}
list += li;
}
} // end makeList()
// одиночный селект
function doSelect() {
var att = new Attributes();
var searchHTML = '';
var selectPlaceholder = el.data('placeholder');
var selectSearch = el.data('search');
var selectSearchLimit = el.data('search-limit');
var selectSearchNotFound = el.data('search-not-found');
var selectSearchPlaceholder = el.data('search-placeholder');
var singleSelectzIndex = el.data('z-index');
var selectSmartPositioning = el.data('smart-positioning');
if (selectPlaceholder === undefined) selectPlaceholder = opt.selectPlaceholder;
if (selectSearch === undefined || selectSearch === '') selectSearch = opt.selectSearch;
if (selectSearchLimit === undefined || selectSearchLimit === '') selectSearchLimit = opt.selectSearchLimit;
if (selectSearchNotFound === undefined || selectSearchNotFound === '') selectSearchNotFound = opt.selectSearchNotFound;
if (selectSearchPlaceholder === undefined) selectSearchPlaceholder = opt.selectSearchPlaceholder;
if (singleSelectzIndex === undefined || singleSelectzIndex === '') singleSelectzIndex = opt.singleSelectzIndex;
if (selectSmartPositioning === undefined || selectSmartPositioning === '') selectSmartPositioning = opt.selectSmartPositioning;
var selectbox =
$('