Совместная работа с несколькими типами фильтров - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть несколько различных типов фильтров. Типы фильтров - это флажки, ранговая цена и опция выбора. Каждый из этих фильтров работает индивидуально. Но я хочу, чтобы групповые фильтры работали. Пожалуйста, помогите моему.

let FlyList = [{
	"id": "1",
	"flight_number": "961",
	"type_ticket": "systemi",
	"airline": "ata",
	"fly_time": "04:00",
	"class_type": "economy",
	"price": "10000",
	"capacity": "2",
}, {
	"id": "2",
	"flight_number": "960",
	"type_ticket": "chartery",
	"airline": "Air-Tour",
	"fly_time": "08:00",
	"class_type": "Business",
	"price": "20000",
	"capacity": "3",
}, {
	"id": "3",
	"flight_number": "950",
	"type_ticket": "systemi",
	"airline": "taban",
	"fly_time": "11:00",
	"class_type": "Business",
	"price": "30000",
	"capacity": "5",
},
];

let filters = new Array();

function rangeSlider() {
	$(".range-slider").ionRangeSlider({
		hide_min_max: true,
		keyboard: true,
		min: 0,
		max: 150,
		from: 0,
		to: 140,
		type: 'double',
		step: 1,
		prefix: "$",
		grid: true,
		onFinish: function(data) {
			var _price = filters.findIndex(item => item.field === 'price');
			if (_price != -1) filters[_price]['value'] = [data.from, data.to];
			else addOrRemoveFilter('price', [data.from, data.to], true);
			customFilter();
			// console.log(addOrRemoveFilter('price', [data.from, data.to], true));
			
		}		
	});
}
function customFilter() {
	let filtered_list = [];
	FlyList.filter(item => {
		filters.forEach(function(el, i) {
			let _field = el['field'];
			let _value = el['value'];
			// console.log(_value);
			
			

			if (typeof(_value) === 'object' && _value.length) {
			
				if(parseInt(item[_field]) >= (parseInt(_value[0] * 1000)) && parseInt(item[_field]) <= (parseInt(_value[1]*1000))){
					filtered_list.push(item);
				}
				else{
					FlyList = [];
				}

			} else {
				let isMulti = _value.split(',');
	
				//RANGE PRICE SLIDER  
				if (isMulti.length > 1) {
					let time = miliseconds(item[_field].split(':')[0], item[_field].split(':')[1])
					let num1 = miliseconds(isMulti[0].split(':')[0], isMulti[0].split(':')[1]);
					let num2 = miliseconds(isMulti[1].split(':')[0], isMulti[1].split(':')[1]);
					if (time >= num1 && time <= num2) filtered_list.push(item);
				} else {
					//end RANGE PRICE SLIDER  
					item[_field] == _value ? filtered_list.push(item) : false;
				}
			}
		})
	});

	function miliseconds(hrs,min) {
		return((hrs*60*60+min*60)*1000);
	}

	$('#flights').updateDom(filtered_list.length ? filtered_list : FlyList, {
		animate: true,
	});	
}




let filterCheckboxes = document.querySelectorAll('.filtersAll');
filterCheckboxes.forEach(checkbox => checkbox.addEventListener('change', (e) => {
	e.preventDefault();
	let filterTypeElement = findFilterTypeElement(e.target);
	if (filterTypeElement) {
		
		let field = filterTypeElement.getAttribute('data-field');
		let val = e.target.value;

		addOrRemoveFilter(field,val,e.target.checked);
		
		customFilter();
	}
	
}));


document.getElementById('optionAll').addEventListener('change' ,(e)=>{
	e.preventDefault();
	let filterTypeElement = findFilterTypeElement(e.target);
	if (filterTypeElement) {
		
		let field = filterTypeElement.getAttribute('data-field');
		let val = e.target.value;

		addOrRemoveFilter(field,val,true);

		for(var index = 0 ; index < e.target.options.length ; index++)
		{
			addOrRemoveFilter(field,e.target.options[index].value,false);
		}

		addOrRemoveFilter(field,val,true);
		
		customFilter();
	}
})


function addOrRemoveFilter(f,v,add) {
	if(add) {
		filters.push({field : f.toLowerCase() , value : v});
	} else {
		for(let i = 0;i < filters.length ; i++) {
			if(filters[i].field === f.toLowerCase() && filters[i].value === v) {
				filters.splice(i,1);
			}
		}
	}
	// console.log(filters);
}


function getParents(el, parentSelector /* optional */) {

	// If no parentSelector defined will bubble up all the way to *document*
	if (parentSelector === undefined) {
		parentSelector = document;
	}

	var parents = [];
	var p = el.parentNode;

	while (p && (p !== parentSelector || p.parentNode)) {
		var o = p;
		parents.push(o);
		p = o.parentNode;
	}
	parents.push(parentSelector); // Push that parentSelector you wanted to stop at

	return parents;
}

function findFilterTypeElement(el) {
	var result = null;
	var parents = getParents(el);

	parents.forEach((item) => {
		if (hasClass(item, 'filter_type') && result == null) {
			result = item;
		}
	});
	return result;
}

function hasClass(element, className) {
	return (' ' + element.className + ' ').indexOf(' ' + className + ' ') > -1;
}

1 Ответ

0 голосов
/ 21 февраля 2019

То, что вы хотите сделать, это иметь одну функцию, которую вы вызываете при обновлении любого из фильтров.Я бы структурировал это примерно так (при условии, что есть способ отключить фильтр):

let filter1 = {
    isActive: () => {},
    passesFilter: item => {}
}

let filter2 = {
    isActive: () => {},
    passesFilter: item => {}
}

let filter3 = {
    isActive: () => {},
    passesFilter: item => {}
}

let filters = [filter1, filter2, filter3]

function passFilters(item) {
    return filters.every(filter => {
        if (!filter.isActive()) return true;
        return filter.passesFilter(item);
    })
}

function onFilterUpdate() {
    let itemsThatPass = items.filter(item => passFilters(item));
    // do something with itemsThatPass here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...