首页 > 解决方案 > Why doesn't my jQuery-UI dialog work even though all script references are included?

问题描述

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>john@example.com</td>
                </tr>
                <tr>
                    <td>Mary</td>
                    <td>Moe</td>
                    <td>mary@example.com</td>
                </tr>
                <tr>
                    <td>July</td>
                    <td>Dooley</td>
                    <td>july@example.com</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.

标签: jqueryjquery-uijquery-ui-dialog

解决方案


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.


推荐阅读