I'm having a problem with jqGrid. I have a table with many columns. When I change the window or If open the web app in a mobile device, It should show only 4 or 5 columns in the grid table instead of many columns or else It should allow scrolling within the grid. So how to reduce the number of columns in the JQGrid on the window resize event?.
I have tried like following and the resize event is working fine but look&feel is not good due to more columns in the grid and no scroll bar.
My Html,
<table id="list2"></table>
My jqGrid code,
$("#list2").jqGrid({
url: '/Project/GridData',
datatype: "json",
mtype: 'POST',
colNames: ['edit', 'view','id','Project_Name','Project_Name2','Project_Nam3','Project_Number','Project_Manager', 'Business_Unit', 'Project_Admin_Name', 'Remarks', 'Is_Active', 'Created_Date','Modified_Date'],
colModel: [
{ name: 'edit', index: 'edit', width: 55 },
{ name: 'view', index: 'view', width: 55 },
{ name: 'id', index: 'id', width: 55, hidden: true },
{ name: 'Project_Name', index: 'Project_Name', width: 140 },
{ name: 'Project_Name2', index: 'Project_Name2', width: 140 },
{ name: 'Project_Name3', index: 'Project_Name3', width: 140 },
{ name: 'Project_Number', index: 'Project_Number', width: 140 },
{ name: 'Project_Manager', index: 'Project_Manager', width: 140 },
{ name: 'Business_Unit', index: 'Business_Unit', width: 140 },
{ name: 'Project_Admin_Name', index: 'Project_Admin_Name', width: 140, align: "right" },
{ name: 'Remarks', index: 'Remarks', width: 180, align: "right" },
{ name: 'Is_Active', index: 'Is_Active', width: 100, align: "right" },
{ name: 'Created_Date', index: 'Created_Date', width: 150, sortable: false },
{ name: 'Modified_Date', index: 'Modified_Date', width: 150, sortable: false }
],
rowNum: 10,
rowList: [10, 20, 30,50,100,500,1000],
//pager: '#pager2',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
loadonce: true,
ignoreCase: true,
viewrecords: true,
pagepos: 'left',
forceFit: true,
shrinkToFit: false, // to enable the scroll bar in the responsive mode
height: 500,
width:1600,
altRows:true,
altclass:'myAltRowClass'
});
My Script,
var $grid = $("#ProjectSearchGrid"),
newWidth = $grid.closest(".ui-jqgrid").parent().width();
$grid.jqGrid("setGridWidth", newWidth, true); // change the grid size based on parent div size
$grid.jqGrid('setColProp','ProjectName',{width:100}); //change the column size for consistent look in the mobile device
Please include always in your questions the information about the version of jqGrid, which you use (or which you can use), and the fork of jqGrid (free jqGrid, commercial Guriddo jqGrid JS or an old jqGrid in version <=4.7).
If you use free jqGrid fork, then you can just add properties like classes: "hidden-xs", labelClasses: "hidden-xs" or classes: "hidden-xs hidden-sm", labelClasses: "hidden-xs hidden-sm" in the corresponding columns. See the demo from the old answer for more details. If you don't use Bootstrap CSS, you can add the definition of hidden-** classes manually:
#media (max-width: 767px) {
.hidden-xs {
display: none !important;
}
}
#media (min-width: 768px) and (max-width: 991px) {
.hidden-sm {
display: none !important;
}
}
#media (min-width: 992px) and (max-width: 1199px) {
.hidden-md {
display: none !important;
}
}
#media (min-width: 1200px) {
.hidden-lg {
display: none !important;
}
}
If you use an old version of jqGrid and you really can't upgrade to free jqGrid or Guriddo then you can try to use
$(window).bind("resize", function () {
// your resize handler
}).triggerHandler("resize");
and to call hideCol or showCol to hide/show the column on resizing. If you would need to follow the way, I'd recommend you to cache the list of hidden/visible columns to call hideCol or showCol only if the changes are really required. To detect the current resolution you can use window.matchMedia (see here) or to get the width of some outer div of the grid (outer div of <table id="list2"></table>).
UPDATED: I created the demo https://jsfiddle.net/OlegKi/n6g78two/, which uses jqGrid 4.6 and which demonstrates how to use window.matchMedia to hide/show some columns on resizing the grid. The demo hides the last column "ComboDuration" if the the width of view ports is 767 pixels wide or less. It uses the following code:
function hideOrShowColumns (e) {
if (e.matches) {
// we have view ports of 767 pixels wide or less
$grid.jqGrid("hideCol", "ComboDuration");
} else {
$grid.jqGrid("showCol", "ComboDuration");
}
}
var mql = window.matchMedia('(max-width: 767px)');
hideOrShowColumns(mql);
mql.addListener(function (e) {
hideOrShowColumns(e);
});
$(window).bind("resize", function () {
$grid.jqGrid("setGridWidth", $grid.closest(".my-container").width());
}).triggerHandler("resize");
You can use the methods: showCol and hideCol to hide/show columns on condition.
Note that these method accepts array as parameter to show and hide more columns at once. Docs can be found here.
By example you can do this
var $grid = $("#ProjectSearchGrid"),
$grid.jqGrid("hideCol", ["Project_Name2", "Project_Name3"]); // hide these cols before resizing
newWidth = $grid.closest(".ui-jqgrid").parent().width();
$grid.jqGrid("setGridWidth", newWidth, true);
Additionally to this if you use Guriddo jqGrid you can hide some columns when the grid loads in mobile device using the function isMobile .
By example to do this for column Project_name2 you can do
colModel: [
...
{ name: 'Project_Name2', index: 'Project_Name2', width: 140, hidden: $.jgrid.isMobile() },
Related
I know we can set the columns width on a datatable via the columns.width option. But now I want to change that option on the xhr event.
Based on the ajax response I get from the server I want to hide/show a column and adjust the other columns width accordingly (they are all fixed size). Is there any way to achieve that via API?
I looked around all docs but seems it's not possible to achieve.
You cannot change settings once the dataTable is initalised. But if you are using column.width and you have turned autoWidth off, then the width of each column is easy to change. Here is an example :
var table = $('#example').DataTable({
autoWidth: false,
ajax: {
url: 'https://api.myjson.com/bins/avxod'
},
columns: [
{ data: 'name', width: 50 },
{ data: 'position', width: 50 },
{ data: 'salary', width: 50 },
{ data: 'office', width: 50}
]
})
$('#example').on('xhr.dt', function() {
$('#example thead th:eq(1)').width('400');
})
demo -> http://jsfiddle.net/cc7x6h64/
It works because column.width is injected into each <th> as style="width: xxx;"
I'm creating a web application and I want a panel to be perfectly in the center of it's parent panel. I was going through ExtJS5's Kitchen Sink to find layout examples and I found this one.
It places the panel perfectly in the middle, it doesn't cheat using hbox or vbox then setting the pack and align properties to center and middle.
Here is the code he used:
Ext.define('KitchenSink.view.layout.Center', {
extend: 'Ext.container.Container',
requires: [
'Ext.layout.container.Center'
],
xtype: 'layout-center',
width: 500,
height: 400,
layout: 'center',
items: {
title: 'Centered Panel: 75% of container width and 95% height',
border: true,
layout: 'center',
scrollable: true,
width: '75%',
height: '95%',
bodyPadding: '20 0',
items: [
{
title: 'Inner Centered Panel',
html: 'Fixed 300px wide and full height. The container panel will also autoscroll if narrower than 300px.',
width: 300,
height: '100%',
frame: true,
bodyPadding: '10 20'
}
]
}
});
And here is how it looks like:
The reason I prefer this is because the width and height of one the first inner panel is purely percent based. If I tried this using hbox or vbox, I would need to set the width or height to a fixed number.
I'm using Sencha Architect and for some reason, I can't find the layout type center for my panel, container, and viewport elements. I've also included the Ext.layout.container.Center in my requires but still no dice.
Does anyone know how to implement this Kitchen Sink example in Sencha Architect?
This is a bug https://www.sencha.com/forum/showthread.php?293050
But you can easily overcome any such problems using process config function in SA.
Select your class where you want to edit special configs and click on add processCofnig
Next in the generated function you can edit the configs in any way you need.
processMyContainer: function(config) {
config.layout = "center";
}
The only disadvantage of using process config is that you will not see the settings set by it in the SA design view - but when you preview the app you will see it.
This is my final code for the class:
Ext.define('MyApp.view.MyContainer', {
extend: 'Ext.container.Container',
alias: 'widget.mycontainer',
requires: [
'MyApp.view.MyContainerViewModel',
'Ext.panel.Panel'
],
viewModel: {
type: 'mycontainer'
},
height: 800,
width: 600,
initConfig: function(instanceConfig) {
var me = this,
config = {
items: [
me.processMainPAnel({
xtype: 'panel',
height: '95%',
width: '75%',
bodyPadding: '20 0',
title: 'Centered Panel: 75% of container width and 95% height',
items: [
{
xtype: 'panel',
height: '100%',
html: 'Fixed 300px wide and full height. The container panel will also autoscroll if narrower than 300px.',
width: 300,
bodyPadding: '10 20',
title: 'Inner Centered Panel'
}
]
})
]
};
me.processMyContainer(config);
if (instanceConfig) {
me.getConfigurator().merge(me, config, instanceConfig);
}
return me.callParent([config]);
},
processMainPAnel: function(config) {
config.layout = "center";
return config;
},
processMyContainer: function(config) {
config.layout = "center";
}
});
This is the result in the browser:
I am using Extjs where I am handling multiple minimized windows. When I click on the minimize button I am aligning the window to bottom left corner. But in case of multiple windows, the minimized windows are getting overlapped on one another at the bottom left corner. They are not aligned horizontally. How can I arrange the minimized windows horizontally at bottom of the screen.
Below is my sample code.
Ext.onReady(function () {
Ext.create('Ext.window.Window', {
height: 300,
width: 300,
minimizable: true,
title: 'first win',
listeners: {
"minimize": function (window, opts) {
window.collapse();
window.setWidth(150);
window.alignTo(Ext.getBody(), 'bl-bl')
}
}
}).show();
Ext.create('Ext.window.Window', {
height: 300,
width: 300,
minimizable: true,
title: 'second win',
listeners: {
"minimize": function (window, opts) {
window.collapse();
window.setWidth(150);
window.alignTo(Ext.getBody(), 'bl-bl')
}
}
}).show();
Ext.create('Ext.window.Window', {
height: 300,
width: 300,
minimizable: true,
title: 'third win',
listeners: {
"minimize": function (window, opts) {
window.collapse();
window.setWidth(150);
window.alignTo(Ext.getBody(), 'bl-bl')
}
}
}).show();
});
How about creating an array to keep track of the minimized window. This will help you to know whether to align to the viewport or to another minimized window.
Here is a Sencha fiddle of my tab panel setup. Buttons are dynamically added to a vbox tabs container that is part of an hbox layout setup. The tabs container's width is determined by the flex property.
I've tried setting every button's width: '100%', but upon looking at the Sencha docs on button.width, I find that width takes an integer value representing pixels. I've tried setting the width in style, but I've only succeeded in making the button's width be the width of the screen.
Help and an explanation of the underlying CSS concepts would be greatly appreciated
You're looking for the stretchmax option.
var locationCameraList=[];
Ext.application({
name : 'Fiddle',
launch : function() {
var buttonArr = [];
for (i = 0; i < locationCameraList.length; ++i) {
var tabName = locationCameraList[i].location,
index = i;
var tab = {
xtype: 'button',
cls: 'tab'+index,
text: tabName,
scale: 'medium'
};
buttonArr.push(tab);
console.log(i)
}
var forms = {
xtype: 'container',
flex: 4,
layout: 'fit',
align: 'stretch',
html: 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'
};
Ext.create('Ext.window.Window', {
title: 'Foo',
layout: 'hbox',
items:[{
xtype: 'container',
items: buttonArr,
flex: 1,
layout: {
type: 'vbox',
align: 'stretchmax'
},
autoScroll: true,
height: 200
}, forms]
}).show();
}
});
I am developing a portal as in http://dev.sencha.com/deploy/ext-4.0.7-gpl/examples/portal/portal.html . The good thing about this example is that the height and width are readjusted at run time if you play with height and width of browser. Now i have a panel (just like what's in the graph for the chart), but the difference is that i have got two charts to display in that panel so i can't use layout:'fill' . The problem is that i have to define width and height of both charts in points. Due to which the charts don't resize when the panel is resized. How can i make them to get height and width in percentage relative to its parent ?? and for the record height and width 'auto' jsut wont render the graph.
Your help is appreciated
Ext.define("Ext.app.ChartPortlet",{extend:"Ext.panel.Panel",alias:"widget.chartportlet",requires:["Ext.data.JsonStore","Ext.chart.theme.Base","Ext.chart.series.Series","Ext.chart.series.Line","Ext.chart.axis.Numeric"],
generateData:function(){var b=[{name:"x",djia:10000,sp500:1100}],a;for(a=1;a<50;a++) {b.push({name:"x"+a,sp500:b[a-1].sp500+ ((Math.floor(Math.random()*2)%2)?-1:1)*Math.floor(Math.random()*7),djia:b[a-1].djia+ ((Math.floor(Math.random()*2)%2)?-1:1)*Math.floor(Math.random()*7)})}return b}
,initComponent:function()
{Ext.apply(this,{layout: {
type: 'vbox',
align: 'stretch'
}
,width:600,height:300,items:
[{xtype:"chart",animate:false,shadow:false,store:Ext.create("Ext.data.JsonStore",
{fields:["name","sp500","djia"],data:this.generateData()}),legend: {position:"bottom"},axes:[{type:"Numeric",position:"left",fields:["djia"],
title:"Dow Jones Average",label:{font:"11px Arial"}}, {type:"Numeric",position:"right",grid:false,fields:["sp500"],title:"S&P 500",label: {font:"11px Arial"}}],
series:[{type:"line",lineWidth:1,showMarkers:false,fill:true,axis: ["left","bottom"],xField:"name",yField:"djia",style:{"stroke-width":1}}, {type:"line",lineWidth:1,showMarkers:false,
axis:["right","bottom"],xField:"name",yField:"sp500",style:{"stroke-width":1}}]}]
});this.callParent(arguments)}});
Use a box layout:
Ext.onReady(function(){
Ext.create('Ext.container.Container', {
width: 300,
height: 300,
renderTo: document.body,
layout: {
type: 'hbox',
align: 'stretch'
},
items: [{
flex: 1,
title: 'Some panel'
}, {
flex: 1,
title: 'Other panel'
}]
})
});