jQWidgets Forums

jQuery UI Widgets Forums Grid Weird filtering bug

This topic contains 7 replies, has 2 voices, and was last updated by  Dimitar 10 years, 8 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
  • Weird filtering bug #56365

    jonfrain
    Participant

    The way my code is organized I have a grid that is displayed when the user hits a button to expand that panel. Everything works fine but when the user minimizes the panel and re-expands I see the following:

    It first displays the filtered grid they had before minimizing, but then the ajax tries to overwrite that grid and gets stuck. the following error occurs:

    
    <strong>Uncaught TypeError: Cannot read property 'length' of undefined jquery-1.10.2.js:631</strong>
    x.extend.each                       jquery-1.10.2.js:631
    a.extend._renderfiltercolumn        jqx-all.js:7
    b.extend.rendergridcontent          jqx-all.js:7
    a.extend.applyfilters               jqx-all.js:7
    b.extend.propertyChangedHandler     jqx-all.js:7
    a.jqx.setvalueraiseevent            jqx-all.js:7
    (anonymous function)                jqx-all.js:7
    x.extend.each                       jquery-1.10.2.js:665
    a.jqx.set                           jqx-all.js:7
    a.jqx.jqxWidgetProxy                jqx-all.js:7
    (anonymous function)                jqx-all.js:7
    x.extend.each                       jquery-1.10.2.js:657
    x.fn.x.each                         jquery-1.10.2.js:266
    a.fn.(anonymous function)           jqx-all.js:7
    $.ajax.complete                     <strong>inventory.jquery.js:415</strong>
    c                                   jquery-1.10.2.js:3048
    p.fireWith                          jquery-1.10.2.js:3160
    k                                   jquery-1.10.2.js:8250
    r

    A lot is handled by ajax and php in the ZF2 framework and so I don’t believe that posting full source code will help. but this is the code for the grid in question.

    The one reference to my code ($.ajax.complete inventory.jquery.js:415) starts at:

    currentDataOpened.find(“.”+currentGrid).jqxGrid({

    I’m hoping someone has run into something similar and has an idea of what may cause it to try to re-render the grid. I will next try to make sure that the variable for each grid is different in case that is causing issues.

    // SEE IF THIS MODULE HAS A GRID
    var grid = currentDataOpened.find(".jqxgrid");
    if ( grid ){
    	// sets custom tooltip text
    	var headerTooltipRenderer = function(text) {                     
    		return function (columnHeaderElement) {
    			$(columnHeaderElement).jqxTooltip( {position: 'mouse', content: text } );
    			return;
    		};
    	};
    
    	var columnsrenderer = function (value) {
    	   return '<div style="text-align: center; margin-top: 5px;">' + value + '</div>';
    	}
    
    	var MINWIDTH = 50;
       
    	var i=1;
    	var currentGrid =  "jqxgrid"+i;
    	if (grid.hasClass(currentGrid)) {
    		var myData  = { module: currentDiv, expansion: currentDataId, grid: currentGrid, data: "header"};
    		var myDatafields = [];
    		var myColumns =[];
    
    		$.ajax({
    			type: "POST",
    			url: url,
    			data: JSON.stringify(myData),
    			dataType: "json",
    			contentType: "application/json; charset=utf-8",
    			complete: function(response){
    				var response2 = response.responseText;
    				if (typeof(response2) == 'string'){
    					jsonData = $.parseJSON(response2);
    					for (var i in jsonData) {
    						myData.data = "data";
    						var entry = jsonData[i];
    						// console.log(entry);
    						
    						var cellsFormat = '';
    						if (  entry.type == 'currency' ) {
    							cellsFormat = 'C2';
    							var dataFieldRow = {name: entry.attribute_var_name, type: 'float'};
    						} 
    						else if ( entry.type == 'date') {
    							cellsFormat = 'yyyy-MM-dd';
    							var dataFieldRow = {name: entry.attribute_var_name, type: 'date'};//, format: 'MM-dd-YYYY'};
    						}
    						else {
    							var dataFieldRow = {name: entry.attribute_var_name, type: entry.type};
    						}
    						myDatafields.push(dataFieldRow);
    
    						// cells align
    						// var cellsAlign = 'left';
    						// if ( (entry.type == 'int') || (entry.type == 'float') || (entry.type == 'currency') ) {
    							cellsAlign = 'center';          
    						//}
    
    						// eventually use variable for field widths //width: entry1.grid_field_width
    						var dataColsRow = { text: entry.display_name, 
    											datafield: entry.attribute_var_name, 
    											width: entry.grid_field_width_percent, 
    											minwidth: entry.grid_field_width, //MINWIDTH, 
    											cellsformat: cellsFormat,
    											cellsalign: cellsAlign,
    											renderer: columnsrenderer,
    											rendered: headerTooltipRenderer(entry.tooltip) 
    											};                                              
    						myColumns.push(dataColsRow);
    					}
    					var mySource =
    					{
    						type: "POST",
    						url: url,
    						data: myData,
    						datatype: "json",
    						contenttype: "application/json; charset=utf-8",
    						datafields: myDatafields,
    						root: "rows",
    						beforeprocessing: function(data){       
    							mySource.totalrecords = data.totalRows;
    						},
    						sort: function (){                                               
    							currentDataOpened.find("."+currentGrid).jqxGrid('updatebounddata');
    						},
    						filter: function () {  
    							//var str = 'currentDataOpened= ' + currentDataOpened + "  currentGrid = " + currentGrid;
    							//console.log(str);
    							currentDataOpened.find("."+currentGrid).jqxGrid('updatebounddata', 'filter');
    						}
    					};
    					var settings = {
    						formatData: function(data){
    							data = JSON.stringify(data);
    							return data;
    						}
    					}
    					var addfilter = function () {
    						var filtergroup = new $.jqx.filter();
    					}
    
    					var myDataAdapter = new $.jqx.dataAdapter(mySource, settings);
    					currentDataOpened.find("."+currentGrid).jqxGrid({
    						width: '100%',               
    						source: myDataAdapter,
    						autoheight: true,
    						pageable: true,
    						sortable: true,
    						altrows: true,
    						filterable: true, //true,
    						columnsresize: true,
    						virtualmode: true,
    						autoshowfiltericon: true,
    						theme: 'darkblue',
    						rendergridrows: function(){
    							return myDataAdapter
    							.records;     
    						},
    						columns: myColumns,
    
    						ready: function () {
    							addfilter();
    							var localizationObject = {
    								filterstringcomparisonoperators:    ['contains'],                                                    
    								filternumericcomparisonoperators:   ['less than', 'greater than'],
    								filterdatecomparisonoperators:      ['less than', 'greater than'],
    								filterbooleancomparisonoperators:   ['equal'],  
    							}
    							currentDataOpened.find("."+currentGrid).jqxGrid('localizestrings', localizationObject);  
    						},
    
    						updatefilterpanel: function (filtertypedropdown1, filtertypedropdown2, filteroperatordropdown, filterinputfield1, filterinputfield2, filterbutton, clearbutton,
    						columnfilter, filtertype, filterconditions) {
    							var index1 = 0;
    							var index2 = 0;
    							if (columnfilter != null) {
    								var filter1 = columnfilter.getfilterat(0);
    								var filter2 = columnfilter.getfilterat(1);
    								if (filter1) {
    									index1 = filterconditions.indexOf(filter1.comparisonoperator);
    									var value1 = filter1.filtervalue;
    									filterinputfield1.val(value1);
    								}
    								if (filter2) {
    									index2 = filterconditions.indexOf(filter2.comparisonoperator);
    									var value2 = filter2.filtervalue;
    									filterinputfield2.val(value2);
    								}
    							}
    							filtertypedropdown1.jqxDropDownList({ autoDropDownHeight: true, selectedIndex: index1 });
    							filtertypedropdown2.jqxDropDownList({ autoDropDownHeight: true, selectedIndex: index2 });
    						},
    						updatefilterconditions: function (type, defaultconditions) {
    							var stringcomparisonoperators = ['CONTAINS'];
    							var numericcomparisonoperators = ['LESS_THAN', 'GREATER_THAN'];
    							var datecomparisonoperators = ['LESS_THAN', 'GREATER_THAN'];
    							var booleancomparisonoperators = ['EQUAL'];
    							switch (type) {
    								case 'stringfilter':
    									return stringcomparisonoperators;
    								case 'numericfilter':
    									return numericcomparisonoperators;
    								case 'datefilter':
    									return datecomparisonoperators;
    								case 'booleanfilter':
    									return booleancomparisonoperators;
    							}
    						}                                          
    					});
    
    				}
    			},
    			error: function(jqXHR, textStatus, errorThrown){
    				console.log(jqXHR);
    			}
    		}); // $ajax
    	}
    		
    	.
    	.
    	.
    	continues for other grids
    Weird filtering bug #56367

    jonfrain
    Participant

    I think eventually I’ll want to store all filter settings per grid on the server, but for now I could close the grid and make them reset the filters in the short term.

    Weird filtering bug #56371

    jonfrain
    Participant

    What I’m actually seeing is one call to get the headers and three calls to get the data:

    6.	Request Payloadview source
    {location_descriptionoperator:and, filtervalue0:orange, filtercondition0:CONTAINS, filteroperator0:0,…}
    1.	data: "data"
    2.	expansion: "expansion1"
    3.	filtercondition0: "CONTAINS"
    4.	filterdatafield0: "location_description"
    5.	filteroperator0: 0
    6.	filterscount: 1
    7.	filtervalue0: "orange"
    8.	grid: "jqxgrid1"
    9.	groupscount: 0
    10.	location_descriptionoperator: "and"
    11.	module: "intransit"
    12.	pagenum: 0
    13.	pagesize: 10
    14.	recordendindex: 10
    15.	recordstartindex: 0
    

    The request above properly returns 1 row of data

    6.	Request Payloadview source
    {location_descriptionoperator:and, filtervalue0:orange, filtercondition0:CONTAINS, filteroperator0:0,…}
    1.	data: "data"
    2.	expansion: "expansion1"
    3.	filtercondition0: "CONTAINS"
    4.	filterdatafield0: "location_description"
    5.	filteroperator0: 0
    6.	filterscount: 1
    7.	filtervalue0: "orange"
    8.	grid: "jqxgrid1"
    9.	groupscount: 0
    10.	location_descriptionoperator: "and"
    11.	module: "intransit"
    12.	pagenum: 0
    13.	pagesize: 10
    14.	recordendindex: 10
    15.	recordstartindex: 0
    

    The request above is exactly identical to the first one and properly returns 1 row of data

    6.	Request Payloadview source
    {filterscount:0, groupscount:0, pagenum:0, pagesize:10, recordstartindex:0, recordendindex:10,…}
    1.	data: "data"
    2.	expansion: "expansion1"
    3.	filterscount: 0
    4.	grid: "jqxgrid1"
    5.	groupscount: 0
    6.	module: "intransit"
    7.	pagenum: 0
    8.	pagesize: 10
    9.	recordendindex: 10
    10.	recordstartindex: 0
    

    This request is completely missing the filtering info and wants to return 34 rows of data but the grid is already locked to just one row. The grid on teh screen shows one empty row and a never ending loading symbol

    Weird filtering bug #56372

    jonfrain
    Participant

    For sorting, the call for grid data occurs twice which is one too many but they are both formed properly. Somehow the filtering adds a third call.

    Weird filtering bug #56374

    jonfrain
    Participant

    I sure wish I could edit posts. Anyway, I assume that sorting makes a second call to get data and filtering makes a third and somehow gets messed up in updating the bounddata on grid redraw?

    sort: function (){                                               
       currentDataOpened.find("."+currentGrid).jqxGrid('updatebounddata');
    },
    
    filter: function () {  
       //var str = 'currentDataOpened= ' + currentDataOpened + "  currentGrid = " + currentGrid;
       //console.log(str);
       currentDataOpened.find("."+currentGrid).jqxGrid('updatebounddata', 'filter');
    }
    Weird filtering bug #56378

    jonfrain
    Participant

    I’m not sure if I’ll get a response to this. Is there a good place to call

    jqxGrid(‘clearfilters’);

    When reloading the grid? Putting it in the ready function didn’t seem to have an affect and I’m trying to find a short term fix of clearing the filters on reload.

    Weird filtering bug #56447

    jonfrain
    Participant

    Any help or advice?

    Is there an easy way to clear the column filters on grid load to at least prevent the nasty bug?

    Weird filtering bug #56491

    Dimitar
    Participant

    Hello jonfrain,

    As a general practice you should only call the grid initialization code once. If you wish to update it at a later time (in the Ajax call complete callback) you should only re-set its source property (provided that the column structure remains the same). In that case, you can clear the filters on the bindingcomplete event if you wish.

    Best Regards,
    Dimitar

    jQWidgets team
    http://www.jqwidgets.com/

Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.