Создание выпадающего checkbox списка для текстового input
Необходимо вместо обычного текстового поля сделать выпадающий список с чекбоксами. Что-то похожее на вот такой вид:
При этом, в исходном виде значения вписывались вот так:
То есть, через запятую, а если еще так-то отметить первый пункт, вообще было бы прекрасно. Чтоб, например, отметив 3-е значение как первое оно встало в начало списка, а остальные уже по порядку. Уже склепал скрипт:
$(document).ready(function() {
// Добавляем значения
var val_data = {
"val1": "Значение 1",
"val2": "Значение 2",
"val3": "Значение 3",
"val4": "Значение 4",
"val5": "Значение 5"
};
var input = $('[name="other1"]');
// Создаем общий блок с классом
var val_cont = document.createElement('div');
$(val_cont).addClass("dropdown");
// Создаем кнопку открытия списка и поле для записи значений
$(val_cont).append("Выбрать значение");
// Создаем выпдающий список и вкладываем в общий блок
var ul = document.createElement('ul');
for (elem in val_data) {
$(ul).append("
");
}
$(ul).appendTo(val_cont);
$(ul).hide();
// Размещаем общий блок после нужного input-а
$(input).after(val_cont);
// Скрываем/открываем выпадающий список
$(".dropdown a").on('click', function() {
$(".dropdown ul").slideToggle('fast');
});
$('.dropdown ul input[type="checkbox"]').on('click', function() {
var title_val = $(this).closest('.dropdown ul').find('input[type="checkbox"]').val(),
title = $(this).val() + ", ";
if ($(this).is(':checked')) {
var html = '' + title + '';
$('.value').append(html);
$(".open").hide();
} else {
$('span[data-atr="' + title + '"]').remove();
}
if ($('.value').text() == "") {
$(".open").show();
$(input).val("");
} else {
$(input).val($('.value').text());
}
});
});
* {
box-sizing: border-box;
}
body, ul {
margin: 0;
padding: 0;
font-family: Arial;
}
input[type="text"] {
display: none;
}
.dropdown {
position: relative;
display: table;
margin: 10px auto;
color: #333;
min-width: 220px;
}
.dropdown a {
display: block;
text-decoration: none;
color: #fff;
background: #333;
padding: 12px 20px 10px;
border-radius: 20px;
text-transform: uppercase;
font-size: .95em;
text-align: center;
}
.dropdown ul {
position: relative;
list-style: none;
background: #eee;
margin-top: 10px;
padding: 5px 0;
border-radius: 20px;
font-size: .9em;
}
.dropdown ul:before {
content: '';
position: absolute;
right: 20px;
bottom: 100%;
width: 0;
height: 0;
border-style: solid;
border-width: 0 7px 6px 7px;
border-color: transparent transparent #eeeeee transparent;
}
.dropdown ul li {
padding: 10px 14px;
border-bottom: 1px solid #e0e0e0;
}
.dropdown ul li:last-child {
border: none;
}
.dropdown input[type="checkbox"] {
display: none;
}
.dropdown label {
display: block;
position: relative;
padding-left: 22px;
cursor: pointer;
}
.dropdown label:before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 12px;
height: 12px;
border: 2px solid #666;
border-radius: 4px;
}
.dropdown input[type="checkbox"]:checked ~ label:before {
background: #666;
}
.dropdown label:after {
content: '';
position: absolute;
display: block;
width: 5px;
height: 12px;
top: -5px;
left: 6px;
border: 2px solid #fff;
box-shadow: 1px 2px 2px #555;
border-top-color: transparent;
border-left-color: transparent;
-webkit-transform: rotate(45deg);
transform: rotate(45deg);
z-index: 2;
opacity: 0;
visibility: hidden;
}
.dropdown input[type="checkbox"]:checked ~ label:after {
opacity: 1;
visibility: visible;
}
Итак. Как видим из примера, все работает. Однако, необходимо проверить сам код скрипта, я уверен, что в нем есть косяки или его можно сократить. Самое важное, с чем справится никак не удается, в общем-то, это и есть вопрос: Как проверить содержимое input и при совпадении значений отметить нужные пункты выпадающего списка?
Ответ
Комментарии внутри кода. Вводить значения необходимо через запятую с пробелом (как в изначальном примере).
$(document).ready(function() {
// Добавляем значения
var val_data = {
"val1": "Значение 1",
"val2": "Значение 2",
"val3": "Значение 3",
"val4": "Значение 4",
"val5": "Значение 5"
};
var input = $('[name="other1"]');
// Создаем общий блок с классом
var val_cont = document.createElement('div');
$(val_cont).addClass("dropdown");
// Создаем кнопку открытия списка и поле для записи значений
$(val_cont).append("Выбрать значение");
// Создаем выпдающий список и вкладываем в общий блок
var ul = document.createElement('ul');
for (elem in val_data) {
$(ul).append("
");
}
$(ul).appendTo(val_cont);
$(ul).hide();
// Размещаем общий блок после нужного input-а
$(input).after(val_cont);
// Скрываем/открываем выпадающий список
$(".dropdown a").on('click', function() {
$(".dropdown ul").slideToggle('fast');
});
$('.dropdown ul input[type="checkbox"]').on('click', function() {
var inputValue, innerObj = {};
/* проверяем value текстового инпута. это необходимо для очистки
от лишних запятых при удалении всех элементов и накликивания
чекбоксов заново. если эту проверку не делать, то пустой инпут
добавляется как пустой элемент массива */
if(input.val()) {
/* если инпут не пустой, то закидываем данные из него в массив
по разделителю ", " */
inputValue = input.val().split(', ')
} else {
inputValue = []; // если пустой - присваиваем переменно пустой массив
};
/* промежуточный объект нам необходим для составления массива
только с уникальными элементами */
inputValue.forEach(function(item) {
innerObj[item] = true;
});
/* если чекбокс активен — добавляем его value как ключ к объекту,
а если нет — удаляем этот ключ */
if ($(this).is(':checked')) {
innerObj[$(this).val()] = true;
} else {
delete innerObj[$(this).val()];
}
inputValue = Object.keys(innerObj); // преобразуем ключи объекта в массив
input.val(inputValue.join(', ')); // преобразуем массив в строку, разделяя элементы ", " и записываем в value инпута
/*var title_val = $(this).closest('.dropdown ul').find('input[type="checkbox"]').val(),
title = $(this).val() + ", ";
if ($(this).is(':checked')) {
var html = '' + title + '';
$('.value').append(html);
$(".open").hide();
} else {
$('span[data-atr="' + title + '"]').remove();
}
if ($('.value').text() == "") {
$(".open").show();
$(input).val("");
} else {
$(input).val($('.value').text());
}*/
});
// новая функция
$('.check').click(function() {
var valuesArray = input.val().split(', '), // собираем данные из инпута в массив, разделитель ", "
$checkboxes = $(ul).find('li input').removeClass('protected'); // удаляем со всех инпутов класс
$.each(valuesArray, function(index, value) { // проходимся циклом по собранному массиву из инпутов
$checkboxes.each(function() { // для каждого значение запускаем цикл по всем чекбоксам
if ($(this).val() === value) { // и если value инпута равно элементу из собранного массива
$(this).prop('checked', true).addClass('protected'); // "чекаем" чекбокс и добавляем ему класс, чтобы на следующем условии чекбокс не стал обратно не выделенным
return true; // уходим на следующую итерацию
} else if ( !$(this).hasClass('protected') ) { // если у чекбокса нет класса protected
$(this).prop('checked', false); // то снимаем выделение с чекбокса
}
});
});
});
});
Комментариев нет:
Отправить комментарий