Создать динамическую панель поиска для элементов флажков JavaScript

Я пытаюсь сделать панель поиска, которая показывает элементы на основе их текста в соответствии с тем, что вы вводите в строке поиска. Но большинство онлайн-инструкций касаются массивов или списков, и я не могу адаптировать свой код для их включения.

У меня есть последовательность флажков, созданных в соответствии с массивом, и я не знаю, как действовать.

Мне бы хотелось что-то вроде, если я напишу "J" в строке поиска, я бы увидел флажки "Январь", "Июнь", "Июль".

Вот фрагмент, который поможет вам понять. Я бы предпочел Javascript вместо jQuery.

//array of options (change this array and you change the checkboxes)
var choices = new Array();
choices[0] = "January";
choices[1] = "February";
choices[2] = "March";
choices[3] = "April";
choices[4] = "May";
choices[5] = "June";
choices[6] = "July";
choices[7] = "August";
choices[8] = "September";
choices[9] = "October";
choices[10] = "November";
choices[11] = "December";

//array of value which have to be automaticly selected
var target = new Array()
target[0] = "9";
target[1] = "8";
target[2] = "11";

var cbh = document.getElementById('checkboxes');
var val = '';
var cap = "";

var j = "";
var t = document.getElementById('t');

// the loop is creating the checkboxes with name, value...
for (var i in choices) {
  //Name of checkboxes are their number so I convert the i into a string. 
  j = i.toString();

  val = j;
  //cap will be the value/text of choices[i]
  var cb = document.createElement('input');
  var label = document.createElement("label");

  cap = choices[i];
  var text = document.createTextNode(cap);
  cb.type = 'checkbox';
  cbh.appendChild(cb);
  cb.name = cap;
  cb.value = val;
  label.appendChild(cb);
  label.appendChild(text);
  cbh.appendChild(label);
  cb.addEventListener('click', updateText)
  if(target.indexOf(i)>=0){
    cb.checked =true ;
  }
}
//function which update the text area according to which checkbox is selected or not
updateText();
function updateText() {
  t.value = [null, ...document.querySelectorAll('#checkboxes [type="checkbox"]')].reduce((s, el) => el && el.checked ? s = (s || '') + el.value + '$#' : s || '')
}
   * {
       box-sizing: border-box;
   }
   #data {
       padding:5px;
    width:100vw;
   }
   .multiselect {
    overflow: visible;
    padding:0;
    padding-left:1px;
    border:none;
    background-color:#eee;
    width:100vw;
    white-space: normal;
    height:75px;
   }
   .checkboxes {
    height:100px;
    width:100px;
    border:1px solid #000;
    background-color:white;
    margin-left:-1px;
    display:inline-block;
   }
      
            label {
    display: inline-block;
    border: 1px grey solid;
    padding:5px;
   }
<span onclick="">All</span> | <span onclick="">Selected</span> <input type="text" id="SearchBar" placeholder="Search for options..">
 <form>
 <div id="data">
  <div class="multiselect">
   <div id="c_b">
    <div id="checkboxes">
    </div>
   </div>
  </div>
 </div>
</form>

<textarea id="t"></textarea>

2 ответа

Решение

Вы можете использовать эту функцию JavaScript/JQuery:

function updateCheckboxes(x) {
  if ($('#SearchBar').val() == '') {
    $('#checkboxes > label').show();
  } else {
    $('#checkboxes > label').hide();
    $('#checkboxes > label:contains('+$('#SearchBar').val()+')').show();
  }
}

И называть это oninput на входе, с этой строкой:

<input id="SearchBar" placeholder="Search for options.." type="text" oninput="updateCheckboxes(this)" autocomplete="off">

И включите JQuery как это внизу / вверху головы / тела;

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

//array of options (change this array and you change the checkboxes)
var choices = new Array();
choices[0] = "January";
choices[1] = "February";
choices[2] = "March";
choices[3] = "April";
choices[4] = "May";
choices[5] = "June";
choices[6] = "July";
choices[7] = "August";
choices[8] = "September";
choices[9] = "October";
choices[10] = "November";
choices[11] = "December";
//array of value which have to be automaticly selected
var target = new Array();
target[0] = "9";
target[1] = "8";
target[2] = "11";
var cbh = document.getElementById('checkboxes');
var val = '';
var cap = "";
var j = "";
var t = document.getElementById('t');
// the loop is creating the checkboxes with name, value...
for (var i in choices) {
  //Name of checkboxes are their number so I convert the i into a string. 
  j = i.toString();
  val = j;
  //cap will be the value/text of choices[i]
  var cb = document.createElement('input');
  var label = document.createElement("label");
  cap = choices[i];
  var text = document.createTextNode(cap);
  cb.type = 'checkbox';
  cbh.appendChild(cb);
  cb.name = cap;
  cb.value = val;
  label.appendChild(cb);
  label.appendChild(text);
  cbh.appendChild(label);
  cb.addEventListener('click', updateText);
  if (target.indexOf(i) >= 0) {
    cb.checked = true;
  }
}
updateText();
//function which update the text area according to which checkbox is selected or not
function updateText() {
  t.value = [null, ...document.querySelectorAll('#checkboxes [type="checkbox"]')].reduce((s, el) => el && el.checked ? s = (s || '') + el.value + '$#' : s || '');
}
$.expr[":"].contains = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});
function updateCheckboxes(x) {
  if ($('#SearchBar').val() == '') {
    $('#checkboxes > label').show();
  } else {
    $('#checkboxes > label').hide();
    $('#checkboxes > label:contains('+$('#SearchBar').val()+')').show();
  }
}
* {
  box-sizing: border-box;
}
#data {
  padding: 5px;
  width: 100vw;
}
.multiselect {
  overflow: visible;
  padding: 0;
  padding-left: 1px;
  border: none;
  background-color: #eee;
  width: 100vw;
  white-space: normal;
  height: 75px;
}
.checkboxes {
  height: 100px;
  width: 100px;
  border: 1px solid #000;
  background-color: white;
  margin-left: -1px;
  display: inline-block;
}
label {
  display: inline-block;
  border: 1px grey solid;
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <span onclick="">All</span> | <span onclick="">Selected</span>
  <form>
    <input id="SearchBar" placeholder="Search for options.." type="text" oninput="updateCheckboxes(this)" autocomplete="off">
  </form>
  <form>
    <div id="data">
      <div class="multiselect">
        <div id="c_b">
          <div id="checkboxes"></div>
        </div>
      </div>
    </div>
  </form>
  <textarea id="t"></textarea>
</body>
</html>

Изменить: чтобы сделать поиск без учета регистра, добавьте этот удивительный JQuery, найденный здесь.

$.expr[":"].contains = $.expr.createPseudo(function(arg) {
    return function( elem ) {
        return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
    };
});

Вы можете использовать oninput-атрибут в поле поиска для вызова JS-функции (давайте просто вызовем ее search(query) для этого примера). Вызов должен выглядеть примерно так:

<input oninput="search(this.value);" type="text" id="SearchBar" placeholder="Search for options.." />

search()-функция перебирает choices-array и сравните, соответствует ли параметр, данный функции, или включен в текущий элемент массива. Если это не так, вы можете добавить какой-то .hidden класс к nth <label> где n - выбор, через который вы сейчас проходите. Если это так, вы можете удалить класс. Вы можете сделать это, используя следующие функции jQuery (скажем, i переменная, которая содержит индекс текущего элемента):

$("label:nth-child(" + i + ")").addClass("hidden");

а также

$("label:nth-child(" + i + ")").removeClass("hidden");

.hidden-класс должен выглядеть так:

.hidden {
    display:none;
}

Надеюсь, это поможет. Если у вас есть вопросы, не стесняйтесь спросить.

Другие вопросы по тегам