如何在具有多个选择的jQuery中过滤结果,包括日期范围?

问题描述 投票:1回答:2

我正在尝试根据数据属性过滤结果。在大多数情况下,我认为我在那里(它适用于前三个选择器),但是尝试将日期选择器纳入等式时遇到了麻烦。在这一点上,我对我的方法的看法完全正确-我可以根据需要更改HTML-请随时提供更好的解决方案。

为了方便任何愿意帮助的人,这里是小提琴:https://jsfiddle.net/rnbx0c3j/

谢谢

选择器:

<div id="stats_filter">
    <div id="stats_filter_wrapper" class="grids">
        <div class="grid-3 select-wrapper server first">
            <label class="server">Server</label>
            <select id="select-server">
                <option value="all">All</option>
                <option value="NicNicFunGame">NicNicFunGame</option>
                <option value="GT3_races">GT3_races</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper track">
            <label class="track">Track</label>
            <select id="select-track">
                <option value="all">All</option>
                <option value="ks_brands_hatch">ks_brands_hatch</option>
                <option value="Imola">Imola</option>
                <option value="Spa">Spa</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper car">
            <label class="car">Car</label>
            <select id="select-car">
                <option value="all">All</option>
                <option value="ariel_atom_v8">ariel_atom_v8</option>
                <option value="rr_caterham_academy_620r">rr_caterham_academy_620r</option>
                <option value="ks_porsche_911_gt1">ks_porsche_911_gt1</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper date">
            <label class="date">Date</label>
            <select id="select-date">
                <option value="all">All</option>
                <option value="7">Last 7 days</option>
                <option value="30">Last 30 days</option>
                <option value="182">Last 6 months</option>
                <option value="365">Last 12 months</option>
            </select>
        </div>
    </div>
</div>

要过滤的HTML

<div class="stats-section" id="sectionID_1" data-server="NicNicFunGame" data-track="ks_brands_hatch" data-date="27/09/2019" data-car="ariel_atom_v8">sectionID_1</div>
<div class="stats-section" id="sectionID_2" data-server="NicNicFunGame" data-track="Imola" data-date="03/07/2019" data-car="rr_caterham_academy_620r">sectionID_2</div>
<div class="stats-section" id="sectionID_3" data-server="GT3_races" data-track="Spa" data-date="14/01/2019" data-car="ariel_atom_v8, ks_porsche_911_gt1">sectionID_3</div>

JS

var $select = $('#stats_filter select');
var $statsSection = $('.stats-section');

$select.change(function () {
    var include = '';
    var exclude = [];
    var showAll = true;
    var filterDate = false;

    $select.each(function () {
        var val = $(this).children(':selected').val();

        if (val !== 'all') {

            switch ($(this).prop('id')) {
                case 'select-server':
                    include += "[data-server='" + val + "']";
                    break;
                case 'select-track':
                    include += "[data-track='" + val + "']";
                    break;
                case 'select-car':
                    include += "[data-car*='" + val + "']";
                    break;
                case 'select-date':
                    var selectedDate = new Date(new Date().setDate(new Date().getDate() - val));
                    var dd = selectedDate.getDate();
                    var mm = selectedDate.getMonth() + 1;
                    var yyyy = selectedDate.getFullYear();
                    if (dd < 10) {
                        dd = '0' + dd;
                    }
                    if (mm < 10) {
                        mm = '0' + mm;
                    }
                    selectedDate = dd + '/' + mm + '/' + yyyy;

                    //exclude when date is out of range
                    $statsSection.each(function () {
                        var sectionDate = $(this).data('date');

                        if (process(sectionDate) < process(selectedDate)) {
                            exclude.push("[data-date='" + sectionDate + "']");
                        }
                        exclude.join(',');

                    });

                    function process(date) {
                        var parts = date.split("/");
                        return new Date(parts[2], parts[1] - 1, parts[0]);
                    }

                    filterDate = true;
                    break;
            }
            showAll = false;
        }

    });

    if (showAll) {
        $statsSection.show();
    } else {


        //HOW TO DEAL WITH THE DATES??
                if (filterDate == true) {
            alert('the following dates should be excluded from the results: ' + exclude);
        }

        //this works for the non-date selectors
        $statsSection.not($(include)).hide();
        $statsSection.filter($(include)).show();
    }
});
jquery filter date-range
2个回答
1
投票

因此,对于非日期项目,您的技术是为应该包含的元素计算jquery选择器,然后将其应用于数据div。

非常好的方法,因为在构建'include'变量时要构造多个jquery过滤器。

对日期应用相同技术的困难在于,这会产生范围测试,很难将其放入jquery选择器中。我的解决方案是构造一个合格数据日期值的数组,并在最后一步中执行第二个过滤器。

更改是:

步骤1.定义新变量:

var dateInclude = [];

步骤2。在确定日期是否有效的部分中,将有效值推入dataInclude过滤器数组中

//exclude when date is out of range
$statsSection.each(function () {
    var sectionDate = $(this).data('date');

    if (process(sectionDate) > process(selectedDate)) {
        dateInclude.push("[data-date='" + sectionDate + "']");
    }

});

步骤3:现在,在输出部分中,将dateInclude组合为第二个过滤器。请注意,您的初始过滤器以布尔AND的形式运行,但日期过滤器必须以布尔OR的形式运行。因此,第二步将在show()操作中应用dateInclude过滤器。

$statsSection.hide();
include = (dateInclude.length > 0 && include === '' ? '*' : include);
dateInclude = (dateInclude.length === 0 ? ['*'] : dateInclude );
$('#info').html(include + ' :: ' + dateInclude.join());
$statsSection.filter(include).filter(dateInclude.join()).show();

第一行(下面)可抢先隐藏所有数据div。

$statsSection.hide();

下一行(下面)在过滤器上进行操作以确保它们都具有值。如果没有日期过滤器,我们将插入一个全部匹配项,其他选择框的“包含”过滤器也将全部插入。

include = (dateInclude.length > 0 && include === '' ? '*' : include);
dateInclude = (dateInclude.length === 0 ? ['*'] : dateInclude );

最后,如下所述。

$statsSection.filter(include).filter(dateInclude.join()).show();

为了帮助可视化,我在小提琴中添加了一些输出

例如,选择服务器= NicNicFunGame,并且日期=最近六个月将产生过滤器:

$statsSection.filter("[data-server='NicNicFunGame']").filter("[data-date='27/09/2019'],[data-date='03/07/2019']").show();

查看我在https://jsfiddle.net/JamesE442/qktfbp15/38/上的小提琴


1
投票

您可以将所有stats-section存储到对象数组中并使用array filter搜索

var t0 = performance.now(); 
var initialized = false;
var $select = $('#stats_filter select'); 
function initialize() {
  mySelectors = [];
  $statsSection = $('.stats-section');
    console.log("First search will be costly");
    $($statsSection).each(function (i, e) {
        let temp = $(e).data();
        temp.element = $(e);
        let myDate = temp.date.split("/");
        temp.date = new Date(myDate[1] + "/" + myDate[0] + "/" + myDate[2]).getTime();//fix date format and convert to timestamp
        mySelectors.push(temp);
    });
    initialized = true;
}



$select.change(function () {
    var t0 = performance.now();
    if (!initialized)
        initialize();
    var result = mySelectors;
    $select.each(function () {
        var val = $(this).val(); //you don't need to search the selected child
        if (val !== 'all') {
            switch ($(this).prop('id')) {
                case 'select-server':
                    result = result.filter(obj => {
                        return obj.server === val;
                    });
                    break;
                case 'select-track':
                    result = result.filter(obj => {
                        return obj.track === val;
                    });
                    break;
                case 'select-car':
                    result = result.filter(obj => {
                        return obj.car === val;
                    });
                    break;
                case 'select-date':
                    var selectedDate = new Date(new Date().setDate(new Date().getDate() - val)).getTime(); // timestamp
                    result = result.filter(obj => {
                        return obj.date > selectedDate;
                    });
            }
        }

    });
    $($statsSection).hide();
    $.each(result, function (i, e) {
        $(e.element).show();
    });
    var t1 = performance.now();
    console.log("Search performance " + (t1 - t0) + " milliseconds.");
});
var t1 = performance.now();
console.log("Initialize performance " + (t1 - t0) + " milliseconds.");
.grids { clear: both;max-width: 1920px;margin: 0;}
#stats_filter_wrapper .select-wrapper { width: 25%; float:left; }
#stats_filter_wrapper .select-wrapper label { overflow: hidden; font-weight: 700; }
#stats_filter_wrapper .select-wrapper select { display: block; font-size: 16px; color: #6a6d73; line-height: 1.3; padding: 8px 25px 5px 8px; width: 100%; max-width: 100%; box-sizing: border-box; margin: 0; }
.stats-section{padding:20px 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="stats_filter">
    <div id="stats_filter_wrapper" class="grids">
        <div class="grid-3 select-wrapper server first">
            <label class="server">Server</label>
            <select id="select-server">
                <option value="all">All</option>
                <option value="NicNicFunGame">NicNicFunGame</option>
                <option value="GT3_races">GT3_races</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper track">
            <label class="track">Track</label>
            <select id="select-track">
                <option value="all">All</option>
                <option value="ks_brands_hatch">ks_brands_hatch</option>
                <option value="Imola">Imola</option>
                <option value="Spa">Spa</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper car">
            <label class="car">Car</label>
            <select id="select-car">
                <option value="all">All</option>
                <option value="ariel_atom_v8">ariel_atom_v8</option>
                <option value="rr_caterham_academy_620r">rr_caterham_academy_620r</option>
                <option value="ks_porsche_911_gt1">ks_porsche_911_gt1</option>
            </select>
        </div>
        <div class="grid-3 select-wrapper date">
            <label class="date">Date</label>
            <select id="select-date">
                <option value="all">All</option>
                <option value="7">Last 7 days</option>
                <option value="30">Last 30 days</option>
                <option value="182">Last 6 months</option>
                <option value="365">Last 12 months</option>
            </select>
        </div>
    </div>
</div>
<div class="stats-section" id="sectionID_1" data-server="NicNicFunGame" data-track="ks_brands_hatch" data-date="27/09/2019" data-car="ariel_atom_v8">sectionID_1</div>
<div class="stats-section" id="sectionID_2" data-server="NicNicFunGame" data-track="Imola" data-date="03/07/2019" data-car="rr_caterham_academy_620r">sectionID_2</div>
<div class="stats-section" id="sectionID_3" data-server="GT3_races" data-track="Spa" data-date="14/01/2019" data-car="ariel_atom_v8, ks_porsche_911_gt1">sectionID_3</div>
© www.soinside.com 2019 - 2024. All rights reserved.