0

I have a jQuery-UI which is supposed to act as a filter on a table column header. It worked perfectly fine when I wrote the implementation as a seperate html file.

This is the file which does work with all the script tags included. Here, ColumnFilters.js below is the implementation of the whole filter box which is a dialog box.

    <!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8" />



    <script src="Scripts/jquery-1.10.2.js"></script>
    <script src="Scripts/jquery-1.10.2.min.js"></script>
    <script src="Scripts/jquery-ui.js"></script>
    <script src="Scripts/jquery-ui.min.js"></script>
    <script src="Scripts/bootstrap.js"></script>
    <script src="Scripts/bootstrap.min.js"></script>
    <link href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" rel="stylesheet" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">


</head>
<body>
    <style>
        span i.glyphicon.glyphicon-filter {
            visibility: hidden;
        }

        span:hover i.glyphicon.glyphicon-filter {
            visibility: visible !important;
        }
    </style>
    <script src="ColumnFilters.js"></script>
    <form id="dialog" style="background-color:gainsboro" class="table-bordered">
        <select id="filterclause">
            <option selected>Equals</option>
            <option>Contains</option>
            <option>Does not Contain</option>
            <option>Not Equal to</option>
        </select>
        <div>
            <label for="FirstBox">Field 1</label>
            <input id="FirstBox" />
        </div>

                <!--<button type="submit" class="btn btn-primary">Submit</button>-->

        <div>
           <button class="btn btn-primary" id="ApplyFilter">Apply Filter</button>
            <button class="btn btn-primary" id="ClearFilter">Clear Filter</button>
        </div>
    </form>
     <div class="container">
        <h2>Basic Table</h2>
        <p>The .table class adds basic styling (light padding and only horizontal dividers) to a table:</p>
        <table class="table table-bordered" id="AddressTable">
            <thead>
                <tr>
                    <th data-filterclause="" data-filtervalue=""><span>Firstname</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    <!--<span><i class="material-icons">filter_list</i></span>-->
                    </th>
                    <th data-filterclause="" data-filtervalue=""><span>Lastname</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    </th>
                    <th data-filterclause="" data-filtervalue="">
                        <span>Email</span>
                        <span style="float:right"><i class="glyphicon glyphicon-filter"></i></span>
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>John</td>
                    <td>Doe</td>
                    <td>[email protected]</td>
                </tr>
                <tr>
                    <td>Mary</td>
                    <td>Moe</td>
                    <td>[email protected]</td>
                </tr>
                <tr>
                    <td>July</td>
                    <td>Dooley</td>
                    <td>[email protected]</td>
                </tr>
            </tbody>
        </table>
    </div>

</body>
</html>

But when I try to integrate the same implementation in table created through MVC framework, its not working. Following is the page source for the MVC page -

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Shared - My ASP.NET Application</title>
    <link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
<link href="/Content/wait.css" rel="stylesheet"/>

    <script src="/Scripts/modernizr-2.6.2.js"></script>

    <script src="/Scripts/jquery-1.10.2.js"></script>
<script src="/Scripts/jquery-1.10.2.min.js"></script>
<script src="/Scripts/jquery-ui.js"></script>
<script src="/Scripts/jquery-ui.min.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/bootstrap.min.js"></script>

     <script src="/Scripts/jquery.unobtrusive-ajax.js"></script>




</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/">Application name</a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav">
                    <li><a href="/">Home</a></li>
                    <li><a href="/Home/About">About</a></li>
                    <li><a href="/Home/Contact">Contact</a></li>
                    <li><a href="/Products">Products</a>/li>
                    <li><a href="/Customers">Customers</a>/li>
                    <li><a href="/Addresses/Shared">Addresses</a>/li>
                    <li><a href="/ProductModels">ProductModels</a>/li>
</ul>
            </div>
        </div>
    </div>

    <div class="container body-content">




<script>
    var filterindex = 0;
        $(document).ready(function ()
        {
            $("#dialog").dialog({
                autoOpen: false,
                closeOnEscape: true,
                draggable: true,
                title: "Filter Box"
            });
            $(".glyphicon .glyphicon-filter").click(function (e) {
                filterindex = $(event.target).closest('th').index();

                $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
                $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
                $("#dialog").dialog({

                    position: { at: "right bottom", my: "left top", of: $(e.target) }
                });
                $("#dialog").dialog("open");
            });
            $("#close").click(function () {

                $("#dialog").dialog("close");
            });

            $("#ApplyFilter").click(function (e) {

                e.preventDefault();

                $("th:eq(" + filterindex + ")").data("filterclause", $("#filterclause").find("option:selected").text());
                $("th:eq(" + filterindex + ")").data("filtervalue", $("#FirstBox").val());
                FilterAddressTable();
            });


            function FilterAddressTable() {

                $("#AddressTable tr").each(function () {

                    $(this).show();
                });

                $("#AddressTable th").each(function () {

                    var headerindex = $(this).index();


                    $(this).closest("table").find("tr:has(td):visible").each(function () {

                        if (!$("th:eq(" + headerindex + ")").data("filtervalue")) {
                            $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "hidden");
                        }
                        else {

                            $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "visible");

                            switch ($("th:eq(" + headerindex + ")").data("filterclause")) {

                                case "Equals":

                                    if ($(this).find("td:eq(" + headerindex + ")").text() === $("th:eq(" + headerindex + ")").data("filtervalue")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    }
                                    break;
                                case "Contains":

                                    if ($(this).find("td:eq(" + headerindex + ")").is(":contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + ")")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    } break;
                                case "Does not Contain":

                                    if ($(this).find("td:eq(" + headerindex + ")").is(":not(:contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + "))")) {
                                        $(this).show();
                                    }
                                    else {
                                        $(this).hide();
                                    } break;
                                case "Not Equal to": if ($(this).find("td:eq(" + headerindex + ")").text() != $("th:eq(" + headerindex + ")").data("filtervalue")) {
                                    $(this).show();
                                }
                                else {
                                    $(this).hide();
                                }
                                    break;
                            }
                        }
                    });
                });
            }

            $("#ClearFilter").click(function (e) {

                e.preventDefault();

                $("th:eq(" + filterindex + ")").data("filterclause", "");
                $("th:eq(" + filterindex + ")").data("filtervalue", "");
                FilterAddressTable();
            });

            var Options =
                {
                    url: "/Addresses/" + "Index",
                    type: "GET"
                };
            $.ajax(Options).done(function(data)
            {

                $("#DynamicView").html(data);

            });
            $(document).ajaxStart(function () {
                $("#ProductsTable").css('visibility', 'hidden');
                $(".signal").css('visibility', 'visible');
            });
            $(document).ajaxComplete(function () {
                $("#ProductsTable").css('visibility', 'visible');
                $(".signal").css('visibility', 'hidden');
            });



        });
    </script>

<link href="http://code.jquery.com/ui/1.9.1/themes/base/jquery-ui.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<style>
    span i.glyphicon.glyphicon-filter {
        visibility: hidden;
    }
     span:hover i.glyphicon.glyphicon-filter {
        visibility: visible !important;
    }
</style>
<div class="signal"></div>
<form id="dialog" style="background-color:gainsboro" class="table-bordered">
    <select id="filterclause">
        <option selected>Equals</option>
        <option>Contains</option>
        <option>Does not Contain</option>
        <option>Not Equal to</option>
    </select>
    <div>
        <label for="FirstBox">Field 1</label>
        <input id="FirstBox" />
    </div>

    <!--<button type="submit" class="btn btn-primary">Submit</button>-->

    <div>
        <button class="btn btn-primary" id="ApplyFilter">Apply Filter</button>
        <button class="btn btn-primary" id="ClearFilter">Clear Filter</button>
    </div>
</form>
<div id="DynamicView">
</div>




        <hr />
        <footer>
            <p>&copy; 2019 - My ASP.NET Application</p>
        </footer>
    </div>



<!-- Visual Studio Browser Link -->
<script type="application/json" id="__browserLink_initializationData">
    {"appName":"Chrome","requestId":"d5fb4162ac90439bb233266c5228c43c"}
</script>
<script type="text/javascript" src="http://localhost:3085/335000e36b2e4c7aa1efbc045945ee81/browserLink" async="async"></script>
<!-- End Browser Link -->

</body>
</html>

In this page, the table is not visible as I am loading the table body from another html. However, the part marked with id=dialog, should work as a dialog and should open when I click on an icon on the table header - this is how I have configured it in the click event of the filter icon. It's not opening and I have tried everything from placing the ColumnFilters.js code in the body to placing all the script references in the body, none of these seem to work.

10
  • Why jquery and jquery min . Also ui and ui min . Just single is enough to work.
    – 4b0
    Commented Jun 17, 2019 at 3:25
  • You can start by fixing event.target Commented Jun 17, 2019 at 4:04
  • @Roamer-1888 - what about event.target??It is being used to open the dialog at the place where filter icon is clicked. The first html is working . You can copy the whole thing and save it as an html file , the features will work when you open that file in the browser. But why not in the second html? Commented Jun 17, 2019 at 11:06
  • @Shree - its really confusing whether min is required or both are required. So , out of desperation , I added both. Commented Jun 17, 2019 at 11:06
  • Add both mess the things and code not work properly. Just include one is enough.
    – 4b0
    Commented Jun 17, 2019 at 11:07

1 Answer 1

0

One thing to look at is here:

$(".glyphicon .glyphicon-filter").click(function(e) {
  filterindex = $(event.target).closest('th').index();
  $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
  $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
  $("#dialog").dialog({
    position: {
      at: "right bottom",
      my: "left top",
      of: $(e.target)
    }
  });
  $("#dialog").dialog("open");
});

The click callback is being passed e yet you call event.target which does not exist. This should cause an Error like:

Uncaught TypeError: Cannot read property 'type' of undefined
    at e.setFieldValue
    at HTMLFormElement.formKeydownListener

That needs to be addressed first to ensure that this is not a show stopper for that function.

Second, the item $(".glyphicon .glyphicon-filter") does not appear to exist. I do not see a .glyphicon element that contains .glyphicon-filter as a child. I do see $(".glyphicon.glyphicon-filter") and this appears to work properly.

Here is my test code: https://jsfiddle.net/Twisty/oLh5wf2z/9/

JavaScript

var filterindex = 0;
$(function() {
  $("#dialog").dialog({
    autoOpen: false,
    closeOnEscape: true,
    draggable: true,
    title: "Filter Box"
  });
  $(".glyphicon.glyphicon-filter").click(function(e) {
    filterindex = $(e.target).closest('th').index();

    $("#dialog #filterclause").val($("th:eq(" + filterindex + ")").data("filterclause"));
    $("#dialog #FirstBox").val($("th:eq(" + filterindex + ")").data("filtervalue"));
    $("#dialog").dialog({

      position: {
        at: "right bottom",
        my: "left top",
        of: $(e.target)
      }
    });
    $("#dialog").dialog("open");
  });
  $("#close").click(function() {

    $("#dialog").dialog("close");
  });

  $("#ApplyFilter").click(function(e) {

    e.preventDefault();

    $("th:eq(" + filterindex + ")").data("filterclause", $("#filterclause").find("option:selected").text());
    $("th:eq(" + filterindex + ")").data("filtervalue", $("#FirstBox").val());
    FilterAddressTable();
  });


  function FilterAddressTable() {

    $("#AddressTable tr").each(function() {

      $(this).show();
    });

    $("#AddressTable th").each(function() {

      var headerindex = $(this).index();


      $(this).closest("table").find("tr:has(td):visible").each(function() {

        if (!$("th:eq(" + headerindex + ")").data("filtervalue")) {
          $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "hidden");
        } else {

          $("th:eq(" + headerindex + ")").find("span:has(i.glyphicon.glyphicon-filter)").find("i.glyphicon.glyphicon-filter").css("visibility", "visible");

          switch ($("th:eq(" + headerindex + ")").data("filterclause")) {

            case "Equals":

              if ($(this).find("td:eq(" + headerindex + ")").text() === $("th:eq(" + headerindex + ")").data("filtervalue")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Contains":

              if ($(this).find("td:eq(" + headerindex + ")").is(":contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + ")")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Does not Contain":

              if ($(this).find("td:eq(" + headerindex + ")").is(":not(:contains(" + $("th:eq(" + headerindex + ")").data("filtervalue") + "))")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
            case "Not Equal to":
              if ($(this).find("td:eq(" + headerindex + ")").text() != $("th:eq(" + headerindex + ")").data("filtervalue")) {
                $(this).show();
              } else {
                $(this).hide();
              }
              break;
          }
        }
      });
    });
  }

  $("#ClearFilter").click(function(e) {

    e.preventDefault();

    $("th:eq(" + filterindex + ")").data("filterclause", "");
    $("th:eq(" + filterindex + ")").data("filtervalue", "");
    FilterAddressTable();
  });

  var Options = {
    url: "/Addresses/" + "Index",
    type: "GET"
  };
  $.ajax(Options).done(function(data) {

    $("#DynamicView").html(data);

  });
  $(document).ajaxStart(function() {
    $("#ProductsTable").css('visibility', 'hidden');
    $(".signal").css('visibility', 'visible');
  });
  $(document).ajaxComplete(function() {
    $("#ProductsTable").css('visibility', 'visible');
    $(".signal").css('visibility', 'hidden');
  });
});

Update

Please review: https://www.w3schools.com/cssref/css_selectors.asp

jQuery, and CSS, use selectors to help identify objects.

.class1.class2 Selects all elements with both name1 and name2 set within it's class attribute

.class1 .class2 Selects all elements with name2 that is a descendant of an element with name1 Hope that helps.

element>element Selects all

elements where the parent is a element

Hope that helps.

3
  • First of all , thank you for putting in the effort to run the first html. In the second html , the reason you dont see any table is that its ajax loaded content. The event and e part , it didnt work for me with e and when I looked up solutions , event was suggested. Apparently event is some jQuery thing too. But I am very sure its not the issue. About glyphicon and glyphicon-filter , does the space make a difference?because I though .glyphicon.glphicon-filter and the same with space were equivalent selectors Commented Jun 18, 2019 at 2:46
  • @GameFromScratch yes, a space in the selector makes a big difference. For example, $(".glyphicon .glyphicon-filter"), $(".glyphicon.glyphicon-filter"), and $(".glyphicon > .glyphicon-filter") each mean something different for selecting an element. I'll add an update to help explain.
    – Twisty
    Commented Jun 18, 2019 at 3:38
  • yes it worked. although it is working slower in 2nd html , but the dialog box is coming now. thanks . Commented Jun 18, 2019 at 10:52

Not the answer you're looking for? Browse other questions tagged or ask your own question.