locked
How to add a Filter to a checkbox list group which have a select all checkbox, plus add the arrows. RRS feed

  • Question

  • User483634116 posted

    I got the following code in a thread from here ( https://forums.asp.net/t/2114493.aspx? ) : 

        <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script type="text/javascript">
            $(function () {
                $("#cboAll").click(function () {
                    if ($(this).is(":checked")) {
                        $(".w3-check").prop('checked', true);
                    }
                    else {
                        $(".w3-check").prop('checked', false);
                    }
                });
            })
        </script>
    
            <div>
                <input id="cboAll" type="checkbox" value="CheckAll / unCheck" /> All<br />
                <input id="cbo1" type="checkbox" value="AAA" class="w3-check" />AAA<br />
                <input id="cbo2" type="checkbox" value="BBB" class="w3-check" />BBB<br />
                 <input id="cbo3" type="checkbox" value="CCC" class="w3-check" />CCC<br />
            </div>

    This code is just what I need! And what I want to use, but I would like to add two extra functions to the code:
    1) A search field that allows you to filter the data by the name it shows.
    2) Those space arrows. (I'm sorry, I don't know what the technical name of that component is)

    I will illustrate what I want with an picture: 
    Search Filter

    How can I achieve this? What alternatives do I have? I don't know how to add the missing code to get this result, mainly because I don't know how the javascript code actually works.

    Monday, December 21, 2020 4:23 PM

All replies

  • User1535942433 posted

    Hi roxylalondef,

    This code is just what I need! And what I want to use, but I would like to add two extra functions to the code:
    1) A search field that allows you to filter the data by the name it shows.

    Accroding  to your description,I suggest you could create a new textbox and a button.When you enter the search value in the textbox and click the button,you could each checkboxes and check their value.If they are different,you could hide the checkboxes and the text element.

    2) Those space arrows. (I'm sorry, I don't know what the technical name of that component is)

    I'm guessing that you need a container with scroll.I suggest you could use panel or div.

    Just like this:

    <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
        <script type="text/javascript">
            $(function () {
                $("#cboAll").click(function () {
                    if ($(this).is(":checked")) {
                        $(".w3-check").prop('checked', true);
                    }
                    else {
                        $(".w3-check").prop('checked', false);
                    }
                });
                $("input[id*=btn]").click(function () {
                    var searchvalue = $("input[id*=txt]").val();
                    if (searchvalue != "") {
                        $(".w3-check").each(function () {
                            if ($(this).val() == searchvalue) {
                                $(this).show();
                            }
                            else {
                                $(this).hide();
                                $(this.nextSibling).wrap('<span style="display:none"></style>');   
                            }
                        })
                    }
                    else {
                        $("#cboAll,.w3-check").show();
                    }
    
                })
            })
        </script>
    
     <div>
                <input id="txt" type="text" value="" />
                <input id="btn" type="button" value="Search" />
            </div>
            <div>
                <input id="cboAll" type="checkbox" value="CheckAll / unCheck" />
                All<br />
                <asp:Panel ID="Panel1" runat="server" Style="overflow-y: scroll; width: 500px; height: 200px;">
                    <input id="cbo1" type="checkbox" value="AAA" class="w3-check" />AAA<br />
                    <input id="cbo2" type="checkbox" value="BBB" class="w3-check" />BBB<br />
                    <input id="cbo3" type="checkbox" value="CCC" class="w3-check" />CCC<br />
                    <input id="cbo4" type="checkbox" value="DDD" class="w3-check" />DDD<br />
                    <input id="cbo5" type="checkbox" value="EEE" class="w3-check" />EEE<br />
                    <input id="cbo6" type="checkbox" value="FFF" class="w3-check" />FFF<br />
                    <input id="cbo7" type="checkbox" value="GGG" class="w3-check" />GGG<br />
                    <input id="cbo8" type="checkbox" value="HHH" class="w3-check" />HHH<br />
                    <input id="cbo9" type="checkbox" value="III" class="w3-check" />III<br />
                    <input id="cbo10" type="checkbox" value="JJJ" class="w3-check" />JJJ<br />
    <input id="cbo11" type="checkbox" value="KKK" class="w3-check" />KKK<br /> </asp:Panel> </div>

    Result:

    Best regards,

    Yijing Sun

    Tuesday, December 22, 2020 4:40 AM
  • User483634116 posted

    Hi Yij Sun,

    Thank you very much! You really helped me a lot! But after testing this code in my application, I ran into some problems so I would appreciate if you can help me again with what is left (Or anyone who can improve this code even more).

    Maybe the new problems are a product of the way I use my code, in my View I have something similar to this:

     <div class="form-group">
                    <input id="cboAll" type="checkbox" value="CheckAll / unCheck" />
                    All<br />
                    <asp:Panel ID="Panel1" runat="server" Style="overflow-y: scroll; width: 500px; height: 200px;">
                        @foreach (var cdos in ViewBag.Modelon.Cdos)
                        {
                            <input id=@cdos.Id type="checkbox" value=@cdos.Name class="w3-check" />@cdos.Name<br />
                        }
                    </asp:Panel>
                </div>
    
                <div>
                    <input id="txt" type="text" value="" />
                    <input id="btn" type="button" value="Search" />
                </div>
                <div class="form-group">
                    <input id="cboAll" type="checkbox" value="CheckAll / unCheck" />
                    All<br />
                    <asp:Panel ID="Panel2" runat="server" Style="overflow-y: scroll; width: 500px; height: 200px;">
                        @foreach (var ctres in ViewBag.Modelon.Ctres)
                        {
                            <input id=@ctres.Id type="checkbox" value=@ctres.Name class="w3-check" />@ctres.Name<br />
                        }
                    </asp:Panel>
                </div>

    This creates two amount N of CheckBoxs, each one from a different group, based on data that the View gets from the Database, but the script creates the following problems:

    1) When the search button is pressed a second time, the filter CheckBox label, disappears.
    This is what happens now in my View, using the script code:
    One way that I can think of to fix this is to force the page to reload when the search button is pressed for second time, but in addition to not knowing how I can do it, it should be done without losing the second search request, this brings me to the second problem:

    2) The CheckBox group doesn't re-ordered.
    The way the code works now, if for example I search for BBB, all the CheckBoxes disappear except for the BBB one, but BBB still appears in the same place where it originally loaded. This is impractical because if I have 100 Checkbox and the one I search for is the number 100, I will have a lot of empty space from the ALL to the CheckBox 100. So I would like the code to also take the CheckBoxs of the search result, to the first position and so on.

    3) I was interested in the search not being exact.
    Now the way the code works is that it only finds it by perfect match, when I would like it to find, for example, the CheckBox "BBB" also if I am just searching for "BB" instead of just showing it to me that Checkbox if I search for "BBB".

    4) Scroll Bar doesn't appear even if I have 100 CheckBoxs.
    I think this happens because I am working on ASP.NET CORE and the div code you gave me was for just Asp.net, is that it?

    5) Since I have two groups of CheckBox, the code filters Both.
    I would like that when I click on the first Search button, this just filter data in the first group of CheckBoxs, and when I click on the second that just filter data for the second group of Checkboxs.

    I tried to solve this by doing a double Script code and changing the identifiers of the Divs for each group, but that only caused the second search button to not work.

    <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#cboAll").click(function () {
                if ($(this).is(":checked")) {
                    $(".w3-check").prop('checked', true);
                }
                else {
                    $(".w3-check").prop('checked', false);
                }
            });
            $("input[id*=btn]").click(function () {
                var searchvalue = $("input[id*=txt]").val();
                if (searchvalue != "") {
                    $(".w3-check").each(function () {
                        if ($(this).val() == searchvalue) {
                            $(this).show();
                        }
                        else {
                            $(this).hide();
                            $(this.nextSibling).wrap('<span style="display:none"></style>');
                        }
                    })
                }
                else {
                    $("#cboAll,.w3-check").show();
                }
            })
        })
    </script>
    
    <script type="text/javascript">
        $(function () {
            $("#cboAll2").click(function () {
                if ($(this).is(":checked")) {
                    $(".w4-check").prop('checked', true);
                }
                else {
                    $(".w4-check").prop('checked', false);
                }
            });
            $("input[id*=btn2]").click(function () {
                var searchvalue = $("input[id*=txt]").val();
                if (searchvalue != "") {
                    $(".w4-check").each(function () {
                        if ($(this).val() == searchvalue) {
                            $(this).show();
                        }
                        else {
                            $(this).hide();
                            $(this.nextSibling).wrap('<span style="display:none"></style>');
                        }
                    })
                }
                else {
                    $("#cboAll,.w4-check").show();
                }
            })
        })
    </script>
    

    Anyway, thank you much for reading and your attention! I apologize in advance if I am asking for a lot with this second reply, if this isn't the right place to develop this second point, I have no problem moving my question to another thread.

    Best regards,

    roxylalondef.


    Tuesday, December 22, 2020 8:02 PM
  • User1535942433 posted

    Hi roxylalondef,

    One way that I can think of to fix this is to force the page to reload when the search button is pressed for second time, but in addition to not knowing how I can do it, it should be done without losing the second search request,

    As far as I think,you could use updatepanel as  an asynchronous postback control.

    More details,you could refer to below article:

    https://docs.microsoft.com/en-us/dotnet/api/system.web.ui.asyncpostbacktrigger?view=netframework-4.8

    2) The CheckBox group doesn't re-ordered.
    The way the code works now, if for example I search for BBB, all the CheckBoxes disappear except for the BBB one, but BBB still appears in the same place where it originally loaded. This is impractical because if I have 100 Checkbox and the one I search for is the number 100, I will have a lot of empty space from the ALL to the CheckBox 100. So I would like the code to also take the CheckBoxs of the search result, to the first position and so on.

    The problem is <br/> in the input element.You could add <div>instead of all <br/>.Just like this:

    <asp:Panel ID="Panel1" runat="server" Style="overflow-y: scroll; width: 500px; height: 200px;">
                        @foreach (var cdos in ViewBag.Modelon.Cdos)
                        {
                          <div><input id=@cdos.Id type="checkbox" value=@cdos.Name class="w3-check" />@cdos.Name</div>
                        }
                    </asp:Panel>

    3) I was interested in the search not being exact.
    Now the way the code works is that it only finds it by perfect match, when I would like it to find, for example, the CheckBox "BBB" also if I am just searching for "BB" instead of just showing it to me that Checkbox if I search for "BBB".

    You could prop the check property when you find the search value.

    $("input[id*=btn]").click(function () {
                var searchvalue = $("input[id*=txt]").val();
                if (searchvalue != "") {
                    $(".w3-check").each(function () {
                        if ($(this).val() == searchvalue) {
                         //   $(this).show();
                              $(this).prop('checked', true);
                        }
                        else {
                            $(this).hide();
                            $(this.nextSibling).wrap('<span style="display:none"></style>');
                        }
                    })
                }
                else {
                    $("#cboAll,.w3-check").show();
                }
            })

    4) Scroll Bar doesn't appear even if I have 100 CheckBoxs.
    I think this happens because I am working on ASP.NET CORE and the div code you gave me was for just Asp.net, is that it?

    As far as I think,style 'overflow-y: scroll' could work fine in asp.net core.I suggest you could press F12 to check the style when you run the project.

    5) Since I have two groups of CheckBox, the code filters Both.
    I would like that when I click on the first Search button, this just filter data in the first group of CheckBoxs, and when I click on the second that just filter data for the second group of Checkboxs.

    As far as I think,you could add more jquery selector to limit which checkboxes will excute the jquery.Just like this:

    <script type="text/javascript">
        $(function () {
            $("#cboAll2").click(function () {
                if ($(this).is(":checked")) {
                    $(".w4-check").prop('checked', true);
                }
                else {
                    $(".w4-check").prop('checked', false);
                }
            });
            $("input[id*=btn2]").click(function () {
                var searchvalue = $("input[id*=txt]").val();
                if (searchvalue != "") {
                    $("#Panel1 .w4-check").each(function () {
                        if ($(this).val() == searchvalue) {
                            $(this).show();
                        }
                        else {
                            $(this).hide();
                            $(this.nextSibling).wrap('<span style="display:none"></style>');
                        }
                    })
                }
                else {
                    $("#cboAll,.w4-check").show();
                }
            })
        })
    </script>

    Best regards,

    Yijing Sun

    Wednesday, December 23, 2020 7:16 AM
  • User483634116 posted

    Hi, Yijing Sun

    yij sun

    You could prop the check property when you find the search value.

    I think there was a misunderstanding here, maybe I don't specify this part well, the code that you gave me here what it does is mark a CheckBox when it finds it, when that wasn't what I was looking for.

    1) The code only filters the data under exact match, when that isn't what I would like. 


    Those two pics, show how the code works right now.
    If for example write "Mateo" and press the search button; Ok the view only shows me the CheckBox for Mateo, the same if I write Pablo, but this doesn't find me either of the two if I write for example "Mat" or "Pabl"; When I would like that when I search for "Pabl" it shows to me all the CheckBox that contain something written with the sequence of characters "Pabl", the only exception to this is that the script considers spaces, so if I look for Jan, it finds me "Jan Dos", because there is a space separation between the words 'Jan' and 'Dos'.


    But as I said, the way I would like it to work, is to show me all the CheckBoxes that contain the sequence "Pabl" when I search for "Pabl".

    Then there is a new problem, which I didn't realize before.

    2) The ALL button always selects everything.

    The way this code works now, is that if I filter the data, and I press ALL, all the Checkboxes are selected, even those which were hidden, when I would like that if click on ALL and the data is filtered, this only select all the Checkboxes, that went through the filter (the not hidden ones).

    3) Regarding the disappearing checkboxes, and the scroll.

    Well I still don't solve it, I still don't try anything with update-panel yet but yes 'overflow-y: scroll' doesn't work for some reason, regarding check the style with F12, I'm not sure, what I should be looking at right now?



    yij sun

    The problem is <br/> in the input element.You could add <div>instead of all <br/>.Just like this:

    yij sun

    As far as I think,you could add more jquery selector to limit which checkboxes will excute the jquery.Just like this:



    Regarding those two solutions, both worked!

    if it is useful in this context, I'm going to put my full code as it is now.

    View:

    @model C.Models.CM
    
    <h4>CM</h4>
    <hr />
    <div class="row">
        <div class="col-md-4">
    <form asp-action="Create">
                <div class="form-group">
                    <label asp-for="Date" class="control-label"></label>
                    <input asp-for="Date" class="form-control" />
                    <span asp-validation-for="Date" class="text-danger"></span>
                </div>
                <div class="row">
                    <select data-placeholder="Select Item" asp-for="IdItem" class="form-control" asp-items="ViewBag.Items"></select>
                </div>
    
                <div>
                    <input id="txt" type="text" value="" />
                    <input id="btn" type="button" value="Search" />
                </div>
                <div class="form-group">
                    <input id="cboAll" type="checkbox" value="CheckAll / unCheck" />
                    ALL<br />
                    <asp:Panel ID="Panel1" runat="server" Style="overflow-y: scroll; width: 500px; height: 200px;">
                     @foreach (var cdos in ViewBag.Modelon.Cdos)
                      { 
                            <div><input id=@cdos.Id type="checkbox" name="selectedCdos" value=@cdos.Name class="w3-check" />@cdos.Name</div>
                        }
                    </asp:Panel>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <script src="https://code.jquery.com/jquery-3.1.1.js"></script>
    <script type="text/javascript">
        $(function () {
            $("#cboAll").click(function () {
                if ($(this).is(":checked")) {
                    $(".w3-check").prop('checked', true);
                }
                else {
                    $(".w3-check").prop('checked', false);
                }
            });
            $("input[id*=btn]").click(function () {
                var searchvalue = $("input[id*=txt]").val();
                if (searchvalue != "") {
                    $(".w3-check").each(function () {
                        if ($(this).val() == searchvalue) {
                            $(this).show();
                        }
                        else {
                            $(this).hide();
                            $(this.nextSibling).wrap('<span style="display:none"></style>');
                        }
                    })
                }
                else {
                    $("#cboAll,.w3-check").show();
                }
            })
        })
    </script>

    Models: 

    using C.Models;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    
    namespace C.Models
    {
        public class CM
        {
            [DataType(DataType.Date)]
            public DateTime Date { get; set; }
            public List<string> selectedCdos { get; set; }
            public int IdItem { get; set; }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace C.Models
    {
        public class Item
        {
            [Key]
            public int Id { get; set; }
            [Required]
            public string Item { get; set; }
        }
    }
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace C.Models
    {
        public class Cdos
        {
            [key]
            public int Id { get; set; }
            [Required]
            public string Name { get; set; }
            [Required]
            public int C { get; set; }
        }
    }

    And I have this code in a Method of my controller:

    public IActionResult Create()
            {
                var items = _context.Item.ToList();
                ViewData["Items"] = new SelectList(items, "Id", "Item");
                Cdos viewModel = new Cdos();
                viewModel.Cdos = _context.Cdos;
                ViewBag.Modelon = viewModel;
                return View();
            }

    All this together generates a quantity N of CheckBoxes equal to the quantity of Cdos entities in my Database, which uses the attribute name of Cdos as the value of each CheckBox.

    So well I still have to solve the 4 problems that I mentioned, despite having tried a few things.

    1) That the filtering is by sequence of characters, instead of "words".
    2) The ALL button always selects everything.
    3) The thing text of the CheckBox disappears if I click the search button a Second time, what I have to do is install a library and give the panel an update-panel value?
    4) Scroll Bar.

    For the sake of simplicity, I'm only working with one Checkbox group right now, while trying to get this to work.

    If you can help me with the script code, which is what I am trying to fix now, I would appreciate it.

    Friday, December 25, 2020 8:42 PM
  • User1535942433 posted

    Hi roxylalondef,

    1) That the filtering is by sequence of characters, instead of "words".

    Accroding to your description,as far as I think,you could use fuzzy search.

    More details,you could refer to below article:

    https://stackoverflow.com/questions/7948689/using-js-jquery-to-do-string-search-fuzzy-matching

    2) The ALL button always selects everything.

    You could filter checkboxes which are showing and select everything when click the all button.

    3) The thing text of the CheckBox disappears if I click the search button a Second time, what I have to do is install a library and give the panel an update-panel value?

    I don't understand your requirment clearly.Could you post more details to us.

    4) Scroll Bar.

    You need to do in the F12 panel: select Elements --> press Ctrl+Shift+C -->select the element which you need to add css style.--> Add css style in the style panel.

    Best regards,

    Yijing Sun

    Wednesday, January 13, 2021 4:06 AM