【问题标题】:How to filter table through checkbox values如何通过复选框值过滤表格
【发布时间】:2013-06-28 13:57:20
【问题描述】:

在我的 Razor 视图中,我有一个包含 3 个未显示属性的表格。 Id_Loaction, Id_Level & Id_Section

在此表上方,我为每个位置、级别和部分提供了 3 个复选框列表,并以适当的 Id 作为值。

@foreach (var section in Model.Sections)
{
    <li>
      <input type="checkbox" data-bind="checked: data" value="@Html.Encode(section.Value)"/>@Html.Encode(section.Text)
    </li>
}   

注意:section.Value 是表格行中也使用的元素的 ID

表格本身构建起来相当简单:

@foreach (var item in Model.Offers) 
{
    <tr data-bind="visible: data.IsChecked == true ">
    <td>
        @Html.DisplayFor(modelItem => item.Description)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Location)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Section.Text)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Section.Value)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Section.IsChecked)
    </td>
    <td>
        @Html.DisplayFor(modelItem => item.Level)
    </td>
    <td>
        @Html.ActionLink("Details", "Details", new { id=item.ID })
    </td>
</tr>
}


<script type="text/javascript">
    var data = @Html.Raw(Json.Encode(Model.Sections));

    function FormViewModel(data) {
        this.data = ko.observableArray(data);
    }

    window.viewModel = new FormViewModel(data);

    console.log(viewModel.data());    
    ko.applyBindings(viewModel);
</script>

/编辑: 我已将代码更新为我的实际混乱。 Model.Sections 是一个 ViewModel,它与用于 Model.Offers.Section 的 ViewModel 相同。两者都包含 Value、Text 和 IsChecked 属性。

如何比较这两者并仅显示选中该部分的表格行?

请对我慢一点。 亲切的问候

【问题讨论】:

  • 您要过滤客户端还是服务器端?
  • 我很想过滤客户端,但是由于我不知道从哪里开始,只要没有页面刷新,我会尽我所能
  • 在这种情况下,您应该展示您的页面是如何设置的。你的表是如何生成的?您标记了淘汰赛,那么您是否使用foreach 绑定?也许放在一起一点 jsFiddle,这会让别人很容易帮助你。
  • 我提到了淘汰赛,因为我有一些非常基本的经验,并且看到了一些很棒的结果。所以本质上:有人取消选中位置 Simbabwe (id4),并且必须隐藏位置 id 4 所在的每一行

标签: javascript jquery asp.net-mvc-4 knockout.js razor-2


【解决方案1】:

这是尝试将淘汰赛与我假设 Serv 正在尝试做的事情的精简版本一起使用。这是对象列表上的简单过滤器示例,可以轻松扩展以包含更多过滤器和更复杂的模型。

小提琴 http://jsfiddle.net/zTRq2/3/

简单的过滤器视图模型:

function filterViewModel(data) {
    var self = this;
    self.text = ko.observable(data.text);
    self.checked = ko.observable(data.checked);
}

精简的商品视图模型:

function offerViewModel(offer) {
    var self = this;
    self.description = offer.description;
    self.location = offer.location;
}

主视图模型:

function FormViewModel(data) {
    var self = this;
    // map data from server to locations filter
    self.locations = ko.observableArray(ko.utils.arrayMap(data.locations, function (filter) {
        return new filterViewModel(filter);
    }));

    self.offersView = ko.computed(function () {
        // get list of offers that were passed in, we'll manipulate filteredOffers from now on
        var filteredOffers = data.offers;

        // get all selected locations view models
        var selectedFilterLocations = ko.utils.arrayFilter(self.locations(), function (location) {
            return location.checked();
        });

        // run through util function to filter only offers that match any selected location
        filteredOffers = ko.utils.arrayFilter(filteredOffers, function (offer) {
            var matchesLocation = false;
            ko.utils.arrayForEach(selectedFilterLocations, function (location) {
                if (offer.location === location.text()) matchesLocation = true;
            });
            return matchesLocation;
        });

        return filteredOffers;
    });
};

HTML:

<!-- list of location checkboxes -->
<ul class="unstyled inline" data-bind="foreach: locations">
    <li>
        <input type="checkbox" data-bind="checked: checked" /> <span data-bind="text: text"></span>

    </li>
</ul>

<!-- table which is bound to the offersView computed observable -->
<!-- offersView is recalculated everytime a selection changes from the filter list -->
<table class="table-bordered">
    <tbody data-bind="foreach: offersView">
        <tr>
            <td data-bind="text: description"></td>
            <td data-bind="text: location"></td>
        </tr>
    </tbody>
</table>

【讨论】:

  • 我必须稍后检查您的解决方案。我现在完全被另一个项目使用了。
  • 这看起来非常像我正在寻找的东西,但是我在哪里将我的服务器端模型注入到 js 代码中?
  • 这条线给我带来了麻烦:if (offer.location == location.text()) matchesLocation = true; 它在你的小提琴中工作,但如果我 console.log(offer.location) 它总是未定义。
  • 如果我接受 (offer.Section.Text == location.text()) matchesLocation = true; 它应该可以工作,但我收到错误:Uncaught Error: Unable to parse bindings. Message: ReferenceError: description is not defined; Bindings value: text: description 就像我之前所说:offer.location 未定义(它是部分或部门以便更好地理解)根据到我的服务器端模型。 offer.Section.Text 是必须比较的值,但让我遇到绑定错误。
  • Unable to parse bindings 错误通常是因为当前上下文不包含名为 description 的属性。在我的小提琴中,我有一个 offerViewModel,它有一个名为 description 的属性,如果你想出一个具有不同属性名称的不同模型,那么需要更新 data-bind="text: description" 以匹配它,将 description 替换为您想使用的任何变量。你能把你所拥有的东西发布到 jsfiddle 吗?
【解决方案2】:

除非你必须,否则我不会使用 jQuery 的 each。

knockout 为您的视图提供了 foreach 方法。使用该语句和 if 语句或可见绑定。

<ul data-bind="foreach: entity">
    <!-- ko if:checked() -->
         <!-- display your Li here -->
         <li></li>
    <!-- /ko -->
  </ul>

或者,您可以删除 ko if container less 语句并改用以下语句

 <li data-bind="visible: checked()"></li>

但请记住,这两个测试都是说如果检查等于 true。如果您的值是字符串,则需要针对字符串进行测试。

编辑

如果你有一些 id 或 value 来测试你可以这样做 -

<li data-bind="visible: section.checked() === true"></li>

或其他一些逻辑测试

【讨论】:

    【解决方案3】:

    如果选中,则需要将 tr 的样式设置为无(如果只想显示选中的,则设置为非“无”值),仅此而已 例如:

    var viewModel= function(){
    var self=this;
    self.tableData=ko.observableArray(),
    init=function(){
        for(var i=0;i<5;i++){
            //Put all your data here
            var data={
                selected:ko.observable(false),
                id:ko.observable('loc'+i),
                desc:'desc'+i
                };
            self.tableData.push(data);
        }
    };
    init();
    }
    ko.applyBindings(new viewModel());
    

    那么 HTML 就像

        <div data-bind="foreach:tableData">
        <input type="checkbox" data-bind="checked:selected"/><span data-bind="text:id"></span>
        </div>
    
       <table>
        <thead>
            <th>Location</th>
            <th>Desc</th>
        </thead>
        <tbody data-bind="foreach:tableData">
            <tr data-bind="{style:{display:selected()?'none':''}}">
                <td data-bind="text:id"></td>
                <td data-bind="text:desc"></td>
            </tr>
        </tbody>
       </table>
    

    这里是 jsfiddle : http://jsfiddle.net/Dhana/keT7B/

    【讨论】:

    • 你也可以只使用visible: selected()。它做同样的事情。
    • 是的,更新后可见的 jsfiddle 在这里:jsfiddle.net/Dhana/keT7B/1
    【解决方案4】:

    我认为“行”是指 li。 jQuery 库中的each() 方法用于遍历数组,在本例中是由jQuery 选择器$('input[type="checkbox"]') 返回的匹配元素数组。

    $('input[type="checkbox"]').each(function(){
        if(this.checked)  
            $(this).closest('li').hide()
    })
    

    http://jsfiddle.net/sailorob/4bC2P/

    http://api.jquery.com/jQuery.each/

    【讨论】:

      【解决方案5】:

      如果你:

      1. 为 ul 提供一个包含复选框的 id
      2. 给表格一个 id
      3. 对包含 id 的 tr css 类使用一些约定

      那么你可以 - jsfiddle:

      $('#sectionslist input').change(function() {
         $('#offersTable .offerId' + $(this).val()).toggle();
      });
      

      【讨论】:

        【解决方案6】:

        我猜你只是想做一些简单的客户端过滤?看看这个小提琴:http://jsfiddle.net/dzul1983/e6ADe/2/

        由于会有很多部分,所以在 JS 中硬编码它们并不理想。相反,您可以使用 .NET 在 TR 元素中输出它们。

        例如(如果你用我的小提琴)

        <tr data-bind="visible: isChecked('@Html.Encode(item.Section.Value)') ">

        【讨论】:

          猜你喜欢
          • 2011-12-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-30
          • 1970-01-01
          • 2023-03-22
          • 2012-09-08
          • 1970-01-01
          相关资源
          最近更新 更多