jQWidgets Forums
jQuery UI Widgets › Forums › Grid › Any way to force a grouped grid to redraw when used inside tabs?
Tagged: grid tabs
This topic contains 8 replies, has 2 voices, and was last updated by slodge 12 years, 7 months ago.
-
Author
-
September 21, 2012 at 2:50 pm Any way to force a grouped grid to redraw when used inside tabs? #8320
Hi
I’m currently seeing this kind of “white group” effect when using multiple grids inside a tab control:
The code to reproduce this is included below. If I remove the tabs, then everything displays normally.
Can you suggest any way to resolve this – e,g, is there any way to request a redraw when I switch between tabs?
Thanks
Stuart
<!DOCTYPE html><html lang="en"><head> <title id='Description'>This example tries to work out how to get grouped grids working inside tabs.</title> <link rel="stylesheet" href="/Content/jqx/jqx.base.css" type="text/css" /> <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> <script src="/Scripts/jqx/jqx-all.js" type="text/javascript"></script> <script type="text/javascript" src="/Scripts/jqx/globalization/jquery.global.js"></script> <script type="text/javascript"> $(document).ready(function () { $('#tabs').jqxTabs({ width: '90%', height: 200, position: 'top' }); var data = generatedata(100); var source = { localdata: data, datatype: "array" }; var dataAdapter = new $.jqx.dataAdapter(source); $("#samplegrid1").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable:true, groups: ['productname'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); $("#samplegrid2").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable:true, groups: ['available'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }); function generatedata(rowscount) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2012, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } </script></head> <body class='default'> <div id="tabs"> <ul> <li>by name</li> <li>by available</li> </ul> <div id="samplegrid1"> </div> <div id="samplegrid2"> </div> </div> </body></html>
September 21, 2012 at 2:56 pm Any way to force a grouped grid to redraw when used inside tabs? #8322Hi slodge,
The Grid is not initialized correctly in this code. See this sample for details how to use jqxGrid or any other widget within jqxTabs: http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxtabs/integration.htm?classic
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comSeptember 21, 2012 at 3:13 pm Any way to force a grouped grid to redraw when used inside tabs? #8325Thanks
If I change the code to use this then I still see the same problem – only now it’s on the first of the two tabs (when I switch back)
Stuart
var init1 = function() { $("#samplegrid1").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable: true, groups: ['productname'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var init2 = function() { $("#samplegrid2").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable: true, groups: ['available'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var initTabsPlease = function(which) { switch (which) { case 0: init1(); break; case 1: init2(); break; } }; $('#tabs').jqxTabs({ width: '90%', height: 200, position: 'top', initTabContent: initTabsPlease }); });
September 21, 2012 at 3:22 pm Any way to force a grouped grid to redraw when used inside tabs? #8326(If it helps) I’m testing in Chrome Canary and IE9 (x64) and seeing the same thing in both
September 21, 2012 at 3:27 pm Any way to force a grouped grid to redraw when used inside tabs? #8327Hi slodge,
This code renders the Grids correctly on my side:
<!DOCTYPE html><html lang="en"><head> <title id='Description'>This example tries to work out how to get grouped grids working inside tabs.</title> <link rel="stylesheet" href="../../jqwidgets/styles/jqx.base.css" type="text/css" /> <script type="text/javascript" src="../../scripts/jquery-1.8.1.min.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxcore.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdata.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxbuttons.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxscrollbar.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxmenu.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.grouping.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.selection.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxgrid.filter.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxlistbox.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxdropdownlist.js"></script> <script type="text/javascript" src="../../jqwidgets/jqxtabs.js"></script> <script type="text/javascript" src="../../scripts/gettheme.js"></script> <script type="text/javascript"> $(document).ready(function () { var init1 = function () { var data = generatedata(100); var source = { localdata: data, datatype: "array" }; var dataAdapter = new $.jqx.dataAdapter(source); $("#samplegrid1").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable: true, groups: ['productname'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var init2 = function () { var data = generatedata(100); var source = { localdata: data, datatype: "array" }; var dataAdapter = new $.jqx.dataAdapter(source); $("#samplegrid2").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable: true, groups: ['available'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var initTabsPlease = function (which) { switch (which) { case 0: init1(); break; case 1: init2(); break; } }; $('#tabs').jqxTabs({ width: '90%', height: 200, position: 'top', initTabContent: initTabsPlease }); }); function generatedata(rowscount) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2012, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } </script></head> <body class='default'> <div id="tabs"> <ul> <li>by name</li> <li>by available</li> </ul> <div id="samplegrid1"> </div> <div id="samplegrid2"> </div> </div> </body></html>
Could you try it with jQWidgets 2.4.2? If it does not work, let me know what’s your browser and the browser’s version.
The result of my code is:
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comSeptember 21, 2012 at 3:49 pm Any way to force a grouped grid to redraw when used inside tabs? #8328Aaaaahhhhh
So the problem in the code I sent was in the shared dataAdapter as well as in the init?
🙂
Thanks for your help – I’m still trying to work out how the objects all work together
Stuart
September 26, 2012 at 8:24 am Any way to force a grouped grid to redraw when used inside tabs? #8498Hi Again
Unfortunately this problem is still dogging me.
What I’m seeing is that if a Grid update occurs while a tab is not visible, then that grid’s redraw is broken.
I’ve worked around this a bit – especially by trying to avoid updates when not visible, but async data sources are causing updates :/
The sample code below illustrates the problem. To run it:
1. Start the page – switch back and forth between tabs – everything works well
2. Use one of the buttons at the top of the page to request dataAdapter.databind() on the tab which isn’t visibleI’m still wondering if there’s any kind of refresh/redraw\repaint command I can use to work around this?
Stuart
<!DOCTYPE html><html lang="en"><head> <title id='Description'>This example tries to work out how to get grouped grids working inside tabs.</title> <link rel="stylesheet" href="/Content/jqx/jqx.base.css" type="text/css" /> <script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script> <script src="/Scripts/jqx/jqx-all.js" type="text/javascript"></script> <script type="text/javascript" src="/Scripts/jqx/globalization/jquery.global.js"></script> <script type="text/javascript"> $(document).ready(function () { var data = generatedata(100); var source = { localdata: data, datatype: "array" }; var dataAdapter = new $.jqx.dataAdapter(source); $('#updateFirst').click(function () { dataAdapter.dataBind(); }); var init1 = function () { $("#samplegrid1").jqxGrid( { width: 670, source: dataAdapter, showfilterrow: false, filterable: false, groupable: true, groups: ['productname'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var data2 = generatedata(100); var source2 = { localdata: data2, datatype: "array" }; var dataAdapter2 = new $.jqx.dataAdapter(source2); $('#updateSecond').click(function() { dataAdapter2.dataBind(); }); var init2 = function () { $("#samplegrid2").jqxGrid( { width: 670, source: dataAdapter2, showfilterrow: false, filterable: false, groupable: true, groups: ['available'], selectionmode: 'singlecell', columns: [ { text: 'Name', columntype: 'textbox', datafield: 'name', width: 120 }, { text: 'Product', filtertype: 'checkedlist', datafield: 'productname', width: 160 }, { text: 'Available', datafield: 'available', columntype: 'checkbox', filtertype: 'bool', width: 67 }, { text: 'Ship Date', datafield: 'date', filtertype: 'date', width: 180, cellsalign: 'right', cellsformat: 'd' }, { text: 'Qty.', datafield: 'quantity', filtertype: 'number', width: 50, cellsalign: 'right' }, { text: 'Price', datafield: 'price', filtertype: 'number', cellsalign: 'right', cellsformat: 'c2' } ] }); }; var initTabsPlease = function (which) { switch (which) { case 0: init1(); break; case 1: init2(); break; } }; $('#tabs').jqxTabs({ width: '90%', height: 200, position: 'top', initTabContent: initTabsPlease }); }); function generatedata(rowscount) { // prepare the data var data = new Array(); if (rowscount == undefined) rowscount = 100; var firstNames = [ "Andrew", "Nancy", "Shelley", "Regina", "Yoshi", "Antoni", "Mayumi", "Ian", "Peter", "Lars", "Petra", "Martin", "Sven", "Elio", "Beate", "Cheryl", "Michael", "Guylene" ]; var lastNames = [ "Fuller", "Davolio", "Burke", "Murphy", "Nagase", "Saavedra", "Ohno", "Devling", "Wilson", "Peterson", "Winkler", "Bein", "Petersen", "Rossi", "Vileid", "Saylor", "Bjorn", "Nodier" ]; var productNames = [ "Black Tea", "Green Tea", "Caffe Espresso", "Doubleshot Espresso", "Caffe Latte", "White Chocolate Mocha", "Caramel Latte", "Caffe Americano", "Cappuccino", "Espresso Truffle", "Espresso con Panna", "Peppermint Mocha Twist" ]; var priceValues = [ "2.25", "1.5", "3.0", "3.3", "4.5", "3.6", "3.8", "2.5", "5.0", "1.75", "3.25", "4.0" ]; for (var i = 0; i < rowscount; i++) { var row = {}; var productindex = Math.floor(Math.random() * productNames.length); var price = parseFloat(priceValues[productindex]); var quantity = 1 + Math.round(Math.random() * 10); row["id"] = i; row["available"] = productindex % 2 == 0; row["firstname"] = firstNames[Math.floor(Math.random() * firstNames.length)]; row["lastname"] = lastNames[Math.floor(Math.random() * lastNames.length)]; row["name"] = row["firstname"] + " " + row["lastname"]; row["productname"] = productNames[productindex]; row["price"] = price; row["quantity"] = quantity; row["total"] = price * quantity; var date = new Date(); date.setFullYear(2012, Math.floor(Math.random() * 11), Math.floor(Math.random() * 27)); date.setHours(0, 0, 0, 0); row["date"] = date; data[i] = row; } return data; } </script></head> <body class='default'> <div> <button title="Update First" value="Update First" id="updateFirst">Update First</button> <button title="Update Second" value="Update Second" id="updateSecond">Update Second</button> </div> <div id="tabs"> <ul> <li>by name</li> <li>by available</li> </ul> <div id="samplegrid1"> </div> <div id="samplegrid2"> </div> </div> </body></html>
September 26, 2012 at 8:53 am Any way to force a grouped grid to redraw when used inside tabs? #8500Hi Stuart,
A redraw must occur only when the tab is selected. Otherwise, the Grid’s layout will use incorrect values for width and height – 0 for DIV tags with display: none. If you want to explicitly refresh the Grid, use its ‘render’ method.
Best Regards,
Peter StoevjQWidgets Team
http://www.jqwidgets.comSeptember 27, 2012 at 11:03 am Any way to force a grouped grid to redraw when used inside tabs? #8590Thanks
A small section like:
$(‘#tabs’).bind(‘selected’, function (event) {
var selectedTab = event.args.item;
if (selectedTab == 0) {
$(“#samplegrid1”).jqxGrid(‘render’);
} else {
$(“#samplegrid2”).jqxGrid(‘render’);
}
});Seems to solve my problem even when the async data in the real app
Thanks 🙂
Stuart
-
AuthorPosts
You must be logged in to reply to this topic.