jQuery UI Widgets › Forums › Plugins › AngularJS › jqxgrid refreshing while !ng-show with filterrow -> JS error
Tagged: Angular, angular grid, angularjs, display none, grid, jqxgrid, method, ng-show, refresh
This topic contains 3 replies, has 2 voices, and was last updated by Dimitar 8 years, 10 months ago.
-
Author
-
Dear all
I encountered problems (JS exceptions), if I have a jqx-grid inside a <div>, which is sometimes hidden and sometimes shown (with ng-show) and the grid is refreshed (sometimes in the hidden state.)
I traced down the problem and remarked, that this only happens, if
showfilterrow: true
. The example below (based on your angularjs-grid-refresh.htm) lets reproduce the problem (of course, this simple sample does not make sence on its own – but it shows the actual JS exception I also get on my real project and in such scenarios, the grid displays the unrefreshed (old) data -> this is the real problem in this case).To reproduce it, click “Hide Grid”, then click at least two times on “Refresh Source” -> The JS exception is thrown.
<!DOCTYPE html> <html ng-app="demoApp"> <head> <title id="Description">AngularJS Grid directive. Refresh Source</title> <link rel="stylesheet" type="text/css" href="../../../jqwidgets/styles/jqx.base.css" /> <script type="text/javascript" src="../../../scripts/angular.min.js"></script> <script type="text/javascript" src="../../../scripts/jquery-1.11.1.min.js"></script> <script type="text/javascript" src="../../../jqwidgets/jqx-all.js"></script> <script type="text/javascript" src="../../../scripts/demos.js"></script> <script type="text/javascript"> var demoApp = angular.module("demoApp", ["jqwidgets"]); demoApp.controller("demoController", function ($scope) { // Grid data. var data = new Array(); var firstNames = ["Nancy", "Andrew", "Janet", "Margaret", "Steven", "Michael", "Robert", "Laura", "Anne"]; var lastNames = ["Davolio", "Fuller", "Leverling", "Peacock", "Buchanan", "Suyama", "King", "Callahan", "Dodsworth"]; var titles = ["Sales Representative", "Vice President, Sales", "Sales Representative", "Sales Representative", "Sales Manager", "Sales Representative", "Sales Representative", "Inside Sales Coordinator", "Sales Representative"]; var city = ["Seattle", "Tacoma", "Kirkland", "Redmond", "London", "London", "London", "Seattle", "London"]; var country = ["USA", "USA", "USA", "USA", "UK", "UK", "UK", "USA", "UK"]; for (var i = 0; i < 4; i++) { var row = {}; row["firstname"] = firstNames[i]; row["lastname"] = lastNames[i]; row["title"] = titles[i]; row["city"] = city[i]; row["country"] = country[i]; data.push(row); } $scope.settings = { altrows: true, width: 800, height: 200, ready: function() { $scope.settings.apply('selectrow', 1); }, sortable: true, filterable: true, showfilterrow: true, source: new $.jqx.dataAdapter({ localdata: data, datafields: [ {name: "firstname", type: "string" }, {name: "lastname", type: "string"}, {name: "title", type: "string"}, {name: "city", type: "string"}, {name: "country", type: "string"} ] }), columns: [ { text: 'First Name', datafield: 'firstname', width: 150 }, { text: 'Last Name', datafield: 'lastname', width: 150 }, { text: 'Title', datafield: 'title', width: 150 }, { text: 'City', datafield: 'city', width: 150 }, { text: 'Country', datafield: 'country' } ] } $scope.refresh = function () { data = new Array(); for (var i = 0; i < 10; i++) { var row = {}; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["title"] = titles[Math.floor(Math.random() * titles.length)]; row["city"] = city[Math.floor(Math.random() * city.length)]; row["country"] = country[Math.floor(Math.random() * country.length)]; data.push(row); } $scope.settings.source = new $.jqx.dataAdapter({ localdata: data, datafields: [ { name: "firstname", type: "string" }, { name: "lastname", type: "string" }, { name: "title", type: "string" }, { name: "city", type: "string" }, { name: "country", type: "string" } ] }); } $scope.showGrid = true; $scope.toggleGrid = function () { $scope.showGrid = !$scope.showGrid; } }); </script> </head> <body> <div ng-controller="demoController"> <jqx-button jqx-on-click="refresh()">Refresh Source</jqx-button> <jqx-button jqx-on-click="toggleGrid()">{{showGrid ? 'Hide Grid' : 'Show Grid'}}</jqx-button> <br/> <br/> <div ng-show="showGrid"> <jqx-grid jqx-settings="settings"></jqx-grid> </div> </div> </body> </html>
Best regards,
– baderaHello badera,
When the grid is hidden, its CSS property display is set to none. Widget methods should not be called for widgets that are hidden this way (as opposed to
visibility: hidden;
) to avoid unexpected behaviour. This is a general rule and is not restricted to the AngularJS environment.Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/Thank you, Dimitar, for the explanation – and, indeed, hiding with visibility: hidden does not give any problem.
Just because of interest and to see a little bit more in the background: Why does it give problems with display:none (and why not with visibility: hidden)? I think that in both cases the whole DOM tree is available, each element of the grid is built up… so what is the difference in point of view of the grid?Hi badera,
The main issue with this is that width and height cannot be reliably measured when an element’s ancestor is hidden with
display: none;
. For more information, please refer to these pages: https://dev.jquery.com/ticket/125 and http://stackoverflow.com/questions/9935023/css-no-div-width-when-display-set-to-none.Best Regards,
DimitarjQWidgets team
http://www.jqwidgets.com/ -
AuthorPosts
You must be logged in to reply to this topic.