Помогите реализовать фильтрацию имеющегося списка.
Задача состоит в том, что после изменения соответствующего селекта или чек-бокса метод dispalyCars
каждый раз должен отрисовывать в DOM необходимое количество элементов с классом cars-list__item
.
var dataController = (function() {
var cars = [{
brand: 'Toyota',
year: 2012,
price: 600000,
owners: 2,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Audi',
year: 2002,
price: 350000,
owners: 3,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Ford',
year: 2015,
price: 500000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Volkswagen',
year: 1992,
price: 99999,
owners: 6,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Volkswagen',
year: 2005,
price: 450000,
owners: 3,
features: {
transmission: 'manual',
ac: true
}
},
{
brand: 'Toyota',
year: 2017,
price: 900000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'BMW',
year: 2010,
price: 750000,
owners: 3,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Ford',
year: 2012,
price: 520000,
owners: 3,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Audi',
year: 2000,
price: 250000,
owners: 5,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Subaru',
year: 2013,
price: 750000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
},
];
return {
getData: function() {
return cars;
}
}
})();
var UIcontroller = (function() {
return {
dispalyCars: function(carsList) {
var carsBlock = document.querySelector('.cars-list');
var fragment = document.createDocumentFragment();
for (var i = 0; i < carsList.length; i++) {
if (carsList[i].features.transmission === 'auto') {
carsList[i].features.transmission = 'автомат';
} else {
carsList[i].features.transmission = 'механическая';
};
if (carsList[i].features.ac === true) {
carsList[i].features.ac = 'да';
} else {
carsList[i].features.ac = 'нет';
};
var newCar = document.createElement('li');
newCar.className = 'cars-list__item';
newCar.textContent = 'Марка: ' + carsList[i].brand + ', Год выпуска: ' + carsList[i].year + ', Цена: ' + carsList[i].price + ' руб. ' + 'Собственников по ПТС: ' + carsList[i].owners + '. Дополнительно ' + '(' + 'коробка: ' + carsList[i].features.transmission + ', кондиционер: ' + carsList[i].features.ac + ')';
fragment.appendChild(newCar);
}
carsBlock.appendChild(fragment);
}
}
})();
var controller = (function(dataCtrl, UICtrl) {
// Получить массив с данными
var carsList = dataCtrl.getData();
// Отрисовать список авто
UICtrl.dispalyCars(carsList);
})(dataController, UIcontroller);
.cars-list {
padding: 0;
margin: 0;
min-height: 360px;
}
.cars-list__item {
background-color: rgba(64, 161, 241, 0.753);
box-sizing: border-box;
width: 1000px;
height: 30px;
margin-top: 5px;
margin-bottom: 5px;
padding-top: 5px;
padding-left: 5px;
border-radius: 10px;
list-style: none;
}
.filter {
background-color: silver;
width: 1000px;
height: 30px;
margin-top: 20px;
padding-top: 5px;
padding-left: 5px;
border-radius: 10px;
}
<div class="main">
<ul class="cars-list"></ul>
<form action="#" class="filter" autocomplete="off">
<select name="barnd" id="brand-type" class="filter__brand">
<option value="any" selected>Любaя марка</option>
<option value="toyota">Toyota</option>
<option value="audi">Audi</option>
<option value="ford">Ford</option>
<option value="volkswagen">Volkswagen</option>
<option value="bmw">BMW</option>
<option value="subaru">Subaru</option>
</select>
<select name="year" id="cars-year" class="filter__year">
<option value="any" selected>Любой год выпуска</option>
<option value="1">до 2000 года</option>
<option value="2">до 2010 года</option>
<option value="3">после 2010 года</option>
</select>
<select name="price" id="cars-price" class="filter__price">
<option value="any" selected>Любая цена</option>
<option value="low">до 100000₽</option>
<option value="middle">100000 - 500000₽</option>
<option value="high">от 500000₽</option>
</select>
<select name="owners" id="cars-owners" class="filter__owners">
<option value="any" selected>Любое число собственников</option>
<option value="1">Один</option>
<option value="2">Два</option>
<option value="3">Три и более</option>
</select>
<input type="checkbox" name="features" value="auto" id="transmisson">
<label class="feature feature--auto" for="transmisson">Автоматическая коробка передач</label>
<input type="checkbox" name="features" value="yes" id="conditioner">
<label class="feature feature--conditioner" for="conditioner">Кондиционер</label>
</form>
</div>
Если нужно отфильтровать массив - можно воспользоваться функцией filter
var filtered = carsList.filter(car => condition1 && condition2 && ...)
Где вместо conditionN
идет проверка нужных свойств в соответствии с выбранными элементами в селекте.
после фильтрации нужно просто передать полученный массив в функцию UICtrl.dispalyCars
. Стоит заметить, что данная функция не очищает предварительно блок .cars-list, что может привести к дублированию элементов. Поэтому это нужно либо добавить в саму функцию, либо сделать перед ее вызовом.
Саму фильтрацию следует производить в обработчиках change
нужных селектов и чекбоксов.
В общем работает, но есть только необходимость сделать фильтрацию по чек-боксам более универсальной на тот случай, если их будет гораздо больше, чем 2
var dataController = (function() {
var cars = [{
brand: 'Toyota',
year: 2012,
price: 600000,
owners: 2,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Audi',
year: 2002,
price: 350000,
owners: 3,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Ford',
year: 2015,
price: 500000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Volkswagen',
year: 1992,
price: 99999,
owners: 6,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Volkswagen',
year: 2005,
price: 450000,
owners: 3,
features: {
transmission: 'manual',
ac: true
}
},
{
brand: 'Toyota',
year: 2017,
price: 900000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'BMW',
year: 2010,
price: 750000,
owners: 3,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Ford',
year: 2012,
price: 520000,
owners: 3,
features: {
transmission: 'auto',
ac: true
}
},
{
brand: 'Audi',
year: 2000,
price: 250000,
owners: 5,
features: {
transmission: 'manual',
ac: false
}
},
{
brand: 'Subaru',
year: 2013,
price: 750000,
owners: 1,
features: {
transmission: 'auto',
ac: true
}
}
];
console.log(cars);
return {
getData: function() {
return cars;
}
}
})();
var UIcontroller = (function() {
return {
dispalyCars: function(carsList) {
var carsBlock = document.querySelector('.cars-list');
var fragment = document.createDocumentFragment();
carsList.forEach(function(item){
var newCar = document.createElement('li');
newCar.className = 'cars-list__item';
newCar.textContent = 'Марка: ' + item.brand + ', Год выпуска: ' + item.year + ', Цена: ' + item.price + ' руб. ' + 'Собственников по ПТС: ' + item.owners + '. Дополнительно ' + '(' + 'коробка: ' + item.features.transmission + ', кондиционер: ' + item.features.ac + ')';
fragment.appendChild(newCar);
});
carsBlock.appendChild(fragment);
},
filterData: function(carsList) {
var brand = document.querySelector('.filter__brand');
var year = document.querySelector('.filter__year');
var price = document.querySelector('.filter__price');
var owners = document.querySelector('.filter__owners');
var features = document.getElementsByName('features');
var newList = carsList.filter(function(item) {
switch (brand.value) {
case 'toyota':
return item.brand === 'Toyota';
break;
case 'audi':
return item.brand === 'Audi';
break;
case 'ford':
return item.brand === 'Ford';
break;
case 'volkswagen':
return item.brand === 'Volkswagen';
break;
case 'bmw':
return item.brand === 'BMW';
break;
case 'subaru':
return item.brand === 'Subaru';
break;
case 'any':
return item
}
}).
filter(function(item) {
switch (year.value) {
case '1':
return item.year <= 2000;
break;
case '2':
return item.year <= 2010;
break;
case '3':
return item.year >= 2010;
break;
case 'any':
return item;
}
}).
filter(function(item) {
switch (price.value) {
case 'low':
return item.price <= 100000;
break;
case 'middle':
return (item.price >= 100000 && item.price <= 500000);
break;
case 'high':
return item.price >= 500000;
break;
case 'any':
return item;
}
}).
filter(function(item) {
switch (owners.value) {
case '1':
return item.owners === 1;
break;
case '2':
return item.owners === 2;
break;
case '3':
return item.owners >= 3;
break;
case 'any':
return item;
}
}).
filter(function(item) {
if (features[0].checked) {
return item.features.transmission === 'auto';
} else {
return item;
}
}).
filter(function(item) {
if (features[1].checked) {
return item.features.ac === true;
} else {
return item;
}
});
console.log(newList);
return newList
},
clearList: function() {
var listItem = document.querySelectorAll('.cars-list__item');
for (var i = 0; i < listItem.length; i++) {
listItem[i].remove();
}
},
}
})();
var controller = (function(dataCtrl, UICtrl) {
// 1. Получить массив с исходными данными
var carsList = dataCtrl.getData();
// 2. Отрисовать исходный список авто
UICtrl.dispalyCars(carsList);
//Выполнить фильтрацию
var filterForm = document.querySelector('.filter');
var filterFormHandler = function() {
// 1. Получить данные отфильтрованного массива
var filteredList = UICtrl.filterData(carsList);
// 2. Очистить старый список
UIcontroller.clearList();
// 3. Oтрисовать новый список
UICtrl.dispalyCars(filteredList);
}
filterForm.addEventListener('change', filterFormHandler);
})(dataController, UIcontroller);
.cars-list {
padding: 0;
margin: 0;
min-height: 360px;
}
.cars-list__item {
background-color: rgba(64, 161, 241, 0.753);
box-sizing: border-box;
width: 1000px;
height: 30px;
margin-top: 5px;
margin-bottom: 5px;
padding-top: 5px;
padding-left: 5px;
border-radius: 10px;
list-style: none;
}
.filter {
background-color: silver;
width: 1000px;
height: 30px;
margin-top: 20px;
padding-top: 5px;
padding-left: 5px;
border-radius: 10px;
}
<div class="main">
<ul class="cars-list"></ul>
<form action="#" class="filter" autocomplete="off">
<select name="barnd" id="brand-type" class="filter__brand">
<option value="any" selected>Любaя марка</option>
<option value="toyota">Toyota</option>
<option value="audi">Audi</option>
<option value="ford">Ford</option>
<option value="volkswagen">Volkswagen</option>
<option value="bmw">BMW</option>
<option value="subaru">Subaru</option>
</select>
<select name="year" id="cars-year" class="filter__year">
<option value="any" selected>Любой год выпуска</option>
<option value="1">до 2000 года</option>
<option value="2">до 2010 года</option>
<option value="3">после 2010 года</option>
</select>
<select name="price" id="cars-price" class="filter__price">
<option value="any" selected>Любая цена</option>
<option value="low">до 100000₽</option>
<option value="middle">100000 - 500000₽</option>
<option value="high">от 500000₽</option>
</select>
<select name="owners" id="cars-owners" class="filter__owners">
<option value="any" selected>Любое число собственников</option>
<option value="1">Один</option>
<option value="2">Два</option>
<option value="3">Три и более</option>
</select>
<input type="checkbox" name="features" value="auto" id="transmisson">
<label class="feature feature--auto" for="transmisson">Автоматическая коробка передач</label>
<input type="checkbox" name="features" value="yes" id="conditioner">
<label class="feature feature--conditioner" for="conditioner">Кондиционер</label>
</form>
</div>
Виртуальный выделенный сервер (VDS) становится отличным выбором
Разрабатываю приложение на laravel+vue, и возникло пару вопросов:
Задумался вот о чём: на сайтах по js написано, что лучше всего реализовывать модуль через такой приём: