简体   繁体   English

隐藏具有多个切换的元素

[英]Hiding an element with multiple toggles

I have a table that lists a lot of data (each row is an offer, and there can be a couple hundred of them). 我有一个表,其中列出了很多数据(每一行都是一个报价,并且可能有数百个)。 Each offer has data associated with it: a group ID (multiple offers can be in the same group), a cost, if you must trade other items as a requirement to fulfill offer, etc. 每个报价都有与之相关的数据:组ID(多个报价可以在同一个组中),成本,是否必须交易其他物料以履行报价的条件等。

I've made a fiddle to demonstrate: http://jsfiddle.net/gd5Nd/ 我做了一个小提琴来演示: http : //jsfiddle.net/gd5Nd/

and since i need to include code with fiddle links: 并且由于我需要包含带有小提琴链接的代码:

    <label class='checkbox'>
    <input type='checkbox' class='toggle' id='filterToggle' value='true' data-toggle='filtering' />Filtering Options</label>
<fieldset id='filtering'>
    <label class='checkbox'>
        <input type='checkbox' class='filter' value='1' data-type='req' />Offers with Required Items</label>
    <label class='checkbox'>
        <input type='checkbox' class='toggle' id='groupToggle' value='true' data-toggle='groups' />Filter By Group</label>
    <fieldset id='groups'>
        <div class="col-md-3">
            <label class='checkbox'>
                <input type='checkbox' class='filter' value='11' data-type='group' />Cap Boosters</label>
        </div>
        <div class="col-md-3">
            <label class='checkbox'>
                <input type='checkbox' class='filter' value='475' data-type='group' />Datacores</label>
        </div>
        <div class="col-md-3">
            <label class='checkbox'>
                <input type='checkbox' class='filter' value='24' data-type='group' />Gunslinger Implants</label>
        </div>
    </fieldset>
</fieldset>
<table class='table table-striped table-hover table-condensed' id='offerList'>
    <tr>
        <th>Offer</th>
        <th>Items Req</th>
        <th>LP Cost</th>
        <th>ISK Cost</th>
    </tr>
    <tr id='offer-1607' data-group='11' data-isk='60000' data-lp='60' data-req='1'>
        <td><a href='offer/1607/'>20x Navy Cap Booster 25</a>

        </td>
        <td>1</td>
        <td>60</td>
        <td>60,000</td>
    </tr>
    <tr id='offer-1608' data-group='11' data-isk='125000' data-lp='125' data-req='1'>
        <td><a href='offer/1608/'>20x Navy Cap Booster 50</a>

        </td>
        <td>1</td>
        <td>125</td>
        <td>125,000</td>
    </tr>
    <tr id='offer-1609' data-group='11' data-isk='185000' data-lp='185' data-req='1'>
        <td><a href='offer/1609/'>20x Navy Cap Booster 75</a>

        </td>
        <td>1</td>
        <td>185</td>
        <td>185,000</td>
    </tr>
    <tr id='offer-1431' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
        <td><a href='offer/1431/'>5x Datacore - Amarrian Starship Engineering</a>

        </td>
        <td>0</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-1432' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
        <td><a href='offer/1432/'>5x Datacore - High Energy Physics</a>

        </td>
        <td>0</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-1433' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
        <td><a href='offer/1433/'>5x Datacore - Laser Physics</a>

        </td>
        <td>0</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-1434' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
        <td><a href='offer/1434/'>5x Datacore - Mechanical Engineering</a>

        </td>
        <td>0</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-1435' data-group='475' data-isk='250000' data-lp='250' data-req='0'>
        <td><a href='offer/1435/'>5x Datacore - Nanite Engineering</a>

        </td>
        <td>0</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-1464' data-group='11' data-isk='250000' data-lp='250' data-req='1'>
        <td><a href='offer/1464/'>20x Navy Cap Booster 100</a>

        </td>
        <td>1</td>
        <td>250</td>
        <td>250,000</td>
    </tr>
    <tr id='offer-249' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
        <td><a href='offer/249/'>1x Eifyr and Co. 'Gunslinger' Large Projectile Turret
      LP-1001</a>

        </td>
        <td>0</td>
        <td>375</td>
        <td>375,000</td>
    </tr>
    <tr id='offer-252' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
        <td><a href='offer/252/'>1x Eifyr and Co. 'Gunslinger' Medium Projectile Turret
      MP-801</a>

        </td>
        <td>0</td>
        <td>375</td>
        <td>375,000</td>
    </tr>
    <tr id='offer-255' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
        <td><a href='offer/255/'>1x Eifyr and Co. 'Gunslinger' Motion Prediction
      MR-701</a>

        </td>
        <td>0</td>
        <td>375</td>
        <td>375,000</td>
    </tr>
    <tr id='offer-258' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
        <td><a href='offer/258/'>1x Eifyr and Co. 'Gunslinger' Small Projectile Turret
      SP-601</a>

        </td>
        <td>0</td>
        <td>375</td>
        <td>375,000</td>
    </tr>
    <tr id='offer-261' data-group='24' data-isk='375000' data-lp='375' data-req='0'>
        <td><a href='offer/261/'>1x Eifyr and Co. 'Gunslinger' Surgical Strike
      SS-901</a>

        </td>
        <td>0</td>
        <td>375</td>
        <td>375,000</td>
    </tr>
</table>

JS: JS:

$(document).ready(function () {
    // !- Bind checkboxes to show filters
    $('input[type="checkbox"].toggle').bind("change", function () {
        if (typeof $(this).data('toggle') != 'undefined') {
            if ($(this).is(":checked")) {
                $("#" + $(this).data('toggle')).show();
            } else {
                $("#" + $(this).data('toggle')).hide();
            }
        }
    }).trigger('change');

    $('input[type="checkbox"].filter').bind("change", function () {
        switch ($(this).data('type')) {
            case 'group':
                var filtered = $('*[data-group="' + this.value + '"]');
                console.log("Affected offers for " + this.value + ": " + filtered.length);

                filtered.toggleClass('danger');
                break;
            case 'req':
                var filtered = $('*[data-req="1"]');
                filtered.toggleClass('danger');
                break;
        }
    }).trigger('toggle');
});

The problem I'm having is that multiple filters may point to the same data row. 我遇到的问题是多个过滤器可能指向同一数据行。 For example: I have an offer that is part of group 11 (Cap Boosters), and it also requires items to trade. 例如:我有一个属于第11组(Cap Boosters)的报价,并且还需要交易商品。 I have two filters that affect this: Has required items filter, and the group filter. 我有两个影响此的过滤器:具有必需的项目过滤器和组过滤器。

If I were to activate the group filter for group 11, I highlight the group 11 offers. 如果要激活组11的组过滤器,请突出显示组11的报价。 However, when I activate the filter for offers with required items, I want it to remain highlighted. 但是,当我激活包含必需项的商品的过滤器时,我希望它保持突出显示状态。 Instead, it removes the highlight. 相反,它将删除高光。

This is because I'm toggling the class for the highlight on/off. 这是因为我正在切换班级以选择高亮显示。 I've tried show()/hide() which pretty much do the same thing (of course). 我试过了show()/ hide(),它们几乎做同样的事情(当然)。 One thing I tried that didn't work was addClass() and removeClass(). 我尝试了不起作用的一件事是addClass()和removeClass()。 I thought it would append the class, so that if you had two filters that added the class, and then removed one filter, the other filter's class would still be active, but it seems that addClass only adds the class if it's not already present. 我以为它将追加该类,因此,如果您有两个添加了该类的过滤器,然后删除了一个过滤器,则另一个过滤器的类仍将处于活动状态,但是看来addClass仅在不存在的情况下添加该类。

I could do some checking, such as if I choose to deactivate the group toggle, it will check to see if the req items toggle is still checked. 我可以进行一些检查,例如是否选择停用组切换,它将检查是否仍选中要求项切换。 However, that seems like a hack, and I'm not sure if it will work well (the example I have is a simplified version; in reality, there are about 10 groups and I would like to add more filters, so I'm not sure how feasible it would be to recursively check all filters and if they affect the data row every time one filter is checked/unchecked). 但是,这似乎是一种hack,并且我不确定它是否能很好地工作(我的示例是简化版本;实际上,大约有10个组,我想添加更多过滤器,所以我不确定是否递归检查所有过滤器以及每次检查/取消检查一个过滤器是否会影响数据行的可行性。

I was curious as to how best solve this problem of multiple filters pointing to the same data row. 我很好奇如何最好地解决多个过滤器指向同一数据行的问题。

Solution

I basically set up, as part of routine JS init, a 'filter container' object initially structured as so: rowID : Array() . 作为例程JS init的一部分,我基本上设置了一个初始构造如下的“过滤器容器”对象: rowID : Array() Every time I add a filter, the filter will add itself to array for that row (so, having two filters in this example, each row could be filtered with group or req ). 每次添加过滤器时,该过滤器都会将自身添加到该行的数组中(因此,在此示例中有两个过滤器,每行都可以使用groupreq进行过滤)。 Every time a filter is applied, we loop through the matching rows, and add/remove the filter from the list. 每次应用过滤器时,我们都会遍历匹配的行,然后从列表中添加/删除过滤器。 If we're adding a filter, we go ahead and .hide() the element as well. 如果我们要添加一个过滤器,那么我们还要继续.hide()这个元素。 If we remove the filter, we check to see if the array is empty, which means no filters are applied and we then .show() the element. 如果删除过滤器,我们将检查数组是否为空,这意味着未应用任何过滤器,然后对元素进行.show()

Sweet. 甜。 A fellow EVE pilot. 一名EVE飞行员。

I think your primary problem here is relying too much on simple notions like CSS classes or something to accomplish your goal. 我认为您的主要问题是过多依赖CSS类之类的简单概念或某些东西来实现您的目标。 It sounds like what you need to do is keep track of all the different market items in a data structure, then go through and "turn on highlight" for the items you want. 听起来您需要做的是在数据结构中跟踪所有不同的市场项目,然后遍历并“打开突出显示”所需的项目。 If it's already highlighted, who cares, otherwise turn it on (and vice versa). 如果它已经突出显示,那么谁在乎,否则将其打开(反之亦然)。 This is a strategy I typically use when I have complex hierarchies of collapsible items, or complex groupings such as what you're dealing with. 当我具有复杂的可折叠项目层次结构或复杂的分组(例如您要处理的内容)时,通常使用这种策略。

I think the solution you describe as a "hack" is fine - and is the only way I can think to do it simply. 我认为您形容为“黑客”的解决方案很好-这是我认为可以简单地做到这一点的唯一方法。 I had an idea involving adding an additional data-attribute for every filter option and then applying the styling via those instead of the class IE: 我有一个想法,涉及为每个过滤器选项添加一个额外的数据属性,然后通过那些而不是IE类应用样式:

<style>
.danger,
[data-req_style=1],
[data-group_style=11],
[data-group_style=475]{
    ...
}
</style>

Then rather than toggling the class you could safely add remove multiple filters without interfering with others. 然后,您可以安全地添加而不是切换课程,而无需干扰其他人即可删除多个过滤器。 BUT that becomes really unmaintainable if you have an arbitrary or ever expanding list of filters. 但是,如果您拥有任意或不断扩大的过滤器列表,则将变得难以维护。

Your "hack" solution is how I would implement it were it my project. 您的“ hack”解决方案就是我将其实施为我的项目的方式。 Class selectors and determining the status of check boxes are comparably pretty fast so I wouldn't worry too much about performance even with really large data sets. 类选择器和确定复选框状态的速度相当快,因此即使有非常大的数据集,我也不必担心性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM