UI-Grid does not take 100% width on page load - javascript

I am using ui-grid to showing data in table. when i load the page and leave for few second and then click on the tab (which containing ui-grid), the ui-grid css break. it does not show width of ui-grid 100% of container.but when i load page and just click on tab (containg ui-grid). ui-grid is showing perfect, i mean width of that is 100% of container. I don't know what is the problem.this is the code, i am working on :
Js:
$scope.gridOptions= {
enableFiltering: true,
enableGridMenu : true,
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 50,
// rowHeight: 35,
// infiniteScrollRowsFromEnd: 50,
// infiniteScrollUp: true,
infiniteScrollDown: true,
columnDefs : [
{ displayName:"Attribute",field: 'attributeId',filter: {placeholder: 'Search Attribute'},width:'10%'},
{ displayName:"Section",field: 'sectionRef.attributeSectionId' ,filter: {placeholder: 'Search Section'}},
{ displayName:"Type",field: 'types',filter: { placeholder: 'Search Types'} }
]
}
Html:
<div class="grid m-b-20" ui-grid="gridOptions" ui-grid-move-columns ui-grid-edit ui-grid-resize-columns ui-grid-pinning ui-grid-selection ui-grid-grouping ui-grid-infinite-scroll>
</div>
Note: ui-grid is inside Angular bootstrap Tab
and here is the snapshot of collapse grid :

Are you using an animation on page load - perhaps a tab or a modal? If so, then the usual workaround is the one we use in the modal tutorial: http://ui-grid.info/docs/#/tutorial/110_grid_in_modal
The problem is that the grid isn't responsive, it gets it's size on render. If you haven't given a fixed size it gets it from the container size. If your container is being animated at the time, the size may not be the real size.

$timeout(function () {
$scope.gridApi.core.handleWindowResize();
}, 500);
$scope.gridApi.core.refresh();
This did the job for me.

use $scope.gridApi.core.handleWindowResize(); this method in interval time to solve this problem
onRegisterApi: function(gridApi) {
$scope.gridApi = gridApi;
$scope.mySelectedRows = $scope.gridApi.selection.getSelectedRows();
//$scope.gridApi.grid.registerRowsProcessor($scope.singleFilter);
gridApi.selection.on.rowSelectionChanged($scope, function(row) {
$scope.selectedUser = row.entity.dev_id;
console.log(row);
console.log(row.grid.selection.lastSelectedRow.isSelected);
/*$http.get('./api/ioni_developers/' + $scope.selectedUser).then(function(response) {
if(row.grid.selection.lastSelectedRow.isSelected === true){
$scope.data.dev_id = response.data.dev_id;
$scope.data.dev_name = response.data.dev_name;
$scope.data.dev_email = response.data.dev_email;
$scope.selected = false;
}else{
$scope.data.dev_id = '';
$scope.data.dev_name = '';
$scope.data.dev_email = '';
$scope.selected = true;
}
})*/
});
$scope.selected = true;
$interval( function() {
$scope.gridApi.core.handleWindowResize();
}, 500, 10);
}

The workaround for this is adding the width and rowHeight
for row and cell. As I indicated this is a workaround and I am sure there must other ways of doing this but this a quick fix and should get you what you at least going :)
$scope.gridOptions={
//set the row height to a fixed length
rowHeight: 80,
enableFiltering: true,
enableGridMenu : true,
enableRowSelection: true,
enableSelectAll: true,
selectionRowHeaderWidth: 50,
infiniteScrollDown: true,
columnDefs : [
{ displayName:"Attribute",field: 'attributeId',filter: {placeholder: 'Search Attribute'},width:100},
{ displayName:"Section",field: 'sectionRef.attributeSectionId' ,filter: {placeholder: 'Search Section'}, width:100},
{ displayName:"Type",field: 'types',filter: { placeholder: 'Search Types'} , width:100}
]}

With the suggested polling approach, the function is called after a specified wait, so each width change occurs suddenly. This results in substantial judder when the user quickly changes the table size.
A much better approach is to bind a resize handler to call a resize function when the viewport changes
angular.element($window).bind('resize', () => {
this.updateTableWidth();
});
My project uses a sidebar, so I account for the sidebar width or padding width (if sidebar is open or not), then just set a variable bound to an ng-style on my table wrapper
private updateTableWidth() {
let width = this.$window.innerWidth;
let modifier = (width >= 1280) ? this.sidebarWidth : this.paddingWidth;
this.tableWidth = (width - modifier) + 'px';
}
<div ng-style="{'width': ctrl.tableWidth}">
<div ui-grid></div> <!-- Whatever your grid is -->
</div>

This is what worked for me like a charm!
Add say ng-style="windowResize" to the ui grid markup in HTML template, and on $scope.windowResize, add width: 100% within onRegisterApi function within the scope.
So, basically onRegisterApi() is the default function from ui-grid that triggers when grid is actually drawn, and so basically we are conditionally adding width 100% to grid and making it responsive for all viewports.

Remove ui-grid-resize-columns from your HTML div tags.

Related

unnecessary horizontal scroll bar coming inspite of using sizeColumnsToFit in ag-grid

I have upgraded my ag-grid version from 7.2.0 to v14.2.0. When I use sizeColumnsToFit() api with onGridReady or onGridSizeChanged event, it works but it keeps unnecessary horizontal scroll, may be due to wrong calculation of grid width.
This issue(?) can be seen at official example for ag-grid as well here,
https://www.ag-grid.com/javascript-grid-responsiveness/#example-example1
With the previous version, this works completely fine without any horizontal scroll.
When I manually call $scope.gridOptions.api.sizeColumnsToFit(), then it removes the horizontal scroll.
Here is my gridOptions:
$scope.ag_grid_options = {
headerHeight: 50,
rowHeight: 50,
//rowModelType: 'virtual',
rowModelType: 'infinite',
rowBuffer: 0,
cacheOverflowSize: 1,
infiniteInitialRowCount: 1,
cacheBlockSize: 50,
paginationPageSize: 50,
//virtualPaging: true,
enableServerSideSorting: true,
enableSorting: false,
enableColResize: true,
angularCompileRows: true,
onGridSizeChanged: function (param) {
$scope.ag_grid_options.api.doLayout();
$scope.ag_grid_options.api.sizeColumnsToFit();
},
columnDefs: grid_column_definitions
};
I know I can use property suppressHorizontalScroll= true. But I do not want to use this because with it, scroll will not appear when user will resize the column manually.
I ran into the same/similar issue. The root problem was that I resized my columns before a vertical scrollbar was added. To get around this, resize AFTER adding the rows. Even then it may not work without a timeout
this.http.get('someEndPoint').subscribe(rows => {
this.rowData = rows;
setTimeout(()=>{params.api.sizeColumnsToFit()}, 50);
});
This may be a different symptom than what the OP saw, but could be useful for others.
It's no a bug, its a feature. A scrollbar appears if the total width count of all columns is bigger than your wrapper. You should change minWidth / maxWidth property of headerFields and you will be fine.
var columnDefs = [
{headerName: 'Athlete', field: 'athlete', minWidth: 150},
{headerName: 'Age', field: 'age', minWidth: 50},
{headerName: 'Country', field: 'country', minWidth: 120},
{headerName: 'Year', field: 'year', minWidth: 90},
{headerName: 'Date', field: 'date', minWidth: 110}
];
Side note:
If the grid data is changed due to scope changes or not initial defined you need to recall sizeColumnsToFit() in a new diggest circle like setTimeout(() => {this.gridApi.sizeColumnsToFit();});.
the best solution for me is calling api.sizeColumnsToFit() on modelUpdated event
no need to setTimeout and set width
the example code:
<ag-grid-angular
[defaultColDef]="defaultColumnDefs"
[columnDefs]="columnDefs"
[rowData]="data"
(gridReady)="onGridReady($event)"
(modelUpdated)="onModelUpdated()"
>
</ag-grid-angular>
in onModelUpdated() should call api.sizeColumnsToFit
private gridApi;
onGridReady(params): void {
this.gridApi = params.api;
}
onModelUpdated(): void {
this.sizeToFit();
}
sizeToFit(): void {
this.gridApi.sizeColumnsToFit();
}
A bit late, but for those who is looking for completely disable the horizontal scroll or adjust the horizontal scroll's height (even setting them to 0). You have to also set the scrollbarWidth.
gridOptions: {
suppressHorizontalScroll: true,
scrollbarWidth: 0
}
You can take a look at AgGrid's source code on how they deal with horizontal scroll here:
https://github.com/ag-grid/ag-grid/blob/996ffcdcb828ffa3448d57fa919feb9eb465df15/community-modules/core/src/ts/gridPanel/gridPanel.ts#L889
Another possible solution, just presented to me by a collegue:
Within the column defs you can set the width for each column by calculating the the client width, and then dividing it by the number of columns:
width: (document.documentElement.clientWidth - 40) / (this.numColumns)
In this case, 40 is the sum of the padding on either side of the grid (20 left + 20 right).
This issue remains in v22 and the above solutions didn't seem ideal. The best fix I found was to call sizeColumnsToFit in the onModelUpdated event handler. See https://github.com/ag-grid/ag-grid/issues/2310.
for large scroll appearing in scrollbar, we need to make use of onGridReady event on the grid, which gives gridApi as parameter in callback function and make use of sizeColumnsToFit function to keep the resizing work.
If the scroll length is small, it is appearing because of the width introduced for the vertical sidebar (due to the change in vertical height of the grid).
My Solution:
Locate the element's selector which is causing vertical scrollbar to appear.
It will have overflow/overflow-y to "auto/scroll". Making it to overflow/overflow-y to "overlay" will resolve your problem.
This worked for me everywhere.
This approach is for Angular 2+, use sizeColumnsToFit() inside firstDataRendered event instead of gridReady or gridSizeChanged event it will remove the horizontal scrollbar.
<ag-grid-angular
[defaultColDef]="defaultColumnDefs"
[columnDefs]="columnDefs"
[rowData]="data"
(gridReady)="onGridReady($event)"
(firstDataRendered)="onFirstDataRendered($event)">
</ag-grid-angular>
private gridApi;
onGridReady(params): void {
this.gridApi = params.api;
}
onFirstDataRendered(): void {
this.gridApi.sizeColumnsToFit();
}

Make row expanded element ie extjs grid and chart resizable on window resize

I have used rowExpander plugin in extjs grid on expand of each row 1 property grid with details of row selected and chart is rendered in the div of rowBodyTpl. I want to resize both the elements on window(browser) resize.
`
My parent grid is like this with rowexpander
var grid = Ext.create('Ext.app.CustomizedGridPanelv2', {
width: '100%',
overflowY: 'auto',
flex: 1,
store: this.gridStore,
plugins: [{
pluginId: 'expander',
ptype: 'rowexpander',
expandOnDblClick: false,
expandOnEnter: false,
rowBodyTpl: '<div id="{someId}' + this.id + '"></div>'
}],
viewConfig: {
stripeRows: true,
deferEmptyText: false,
emptyText: " No detailsfound."
},
columns: [{ columns needed}] });
On expand i create a panel and render to the div
grid.getView().addListener('expandbody', function(_rowNode, _rec, _expandedHTML) {
var panel = Ext.create('myPanel', {
srcPanel: me,
srcRecord: _rec,
srcDiv: _rec.get('someId') + me.id
});
panel.render(_rec.get('someId') + me.id);
grid.doLayout();
});
My panel will contain property grid and chart which are the items of extjs panel
`
my parent grid get resized on window resize but the expanded elements get truncated. Is there any way to resize them with browser. Thanks.
I think you can add resize event listener for parent component (grid in your case):
listeners: {
resize: function (grid) {
var plugin = grid.findPlugin('rowexpander');
if (plugin && plugin.recordsExpanded) {
for (var id in plugin.recordsExpanded) {
grid.getEl().down('.my_row_body#' + id).setWidth('100%');
}
}
}
}
But actually row body resize with grid out of the box, check this fiddle.
Also you can check this question.
If your issue relates to browser window resize, not just grid resize I think you can add resize event listener for entire window (not sure its good solution btw):
window.addEventListener('resize', function () {
myView.doLayout();
}, true);

Vertical scrollbar taking last column width

I am using free jqgrid 4.14. I am having a problem with the vertical scrollbar in the tree grid.
I have defined a height for the tree grid. Now when the grids loads and I try to expand it this happens.
But as soon as I am resizing the window the scrollbar width is not taken from last column width instead it has it own. See
So, I thought of making load vertical scrollbar at start
.ui-jqgrid .ui-jqgrid-bdiv { overflow-y: scroll }
but then also it is taking width from the column.
I am loading grid with these settings -
datatype: "jsonstring",
datastr: grid_data,
colNames: scopes.grid_header_column_value[grid_id],
colModel: scopes.gridcolumns[grid_id],
height: height,
viewrecords: is_pager_enable,
multiSort: true,
ignoreCase: true,
grouping: is_group_enable,
headertitles:true,
sortorder: sort_order,
sortable: false,
pager: "#" + pager_id,
treeGrid: true,
treeGridModel: 'adjacency',
treedatatype: "jsonstring",
ExpandColumn: 'name'
Also, I am applying these properties -
$("#" + grid_id).closest('.ui-jqgrid-bdiv').width($("#" + grid_id).closest('.ui-jqgrid-bdiv').width() + 1);
$(".ui-jqgrid-sortable").css('white-space', 'normal');
$(".ui-jqgrid-sortable").css('height', 'auto');
$(".ui-jqgrid tr.jqgrow td").css('white-space', 'normal');
$(".ui-jqgrid tr.jqgrow td").css('height', 'auto');
$("div.ui-jqgrid-sdiv").after($("div.ui-jqgrid-bdiv"));
I am also using jqGridAfterLoadComplete event so that on loading also it performs the same operation which it should perform in resizing from here
So, how can force the vertical scrollbar to take width from outside of grid.
Update: Added image after the solution
Here is the image which specifies exactly what I want.
Here the scrollbar is not needed but still, it is initialized as empty without taking column width
Problem while resizing:
I am using jquery event when the window is resized so to resize the jqgrid according to the screen but here the problem is if I resize the window to smaller screen and expand the tree grid, scrollbar comes.
The code is for resizing is like this -
$(window).bind('resize', function () {
resizeGrid.call($('#' + grid_id));
});
resizeGrid = function () {
var newWidth = $(this).closest(".ui-jqgrid").parent().width();
$(this).jqGrid("setGridWidth", newWidth, true);
};
Like this -
here the scrollbar have extra space and it is coming outside the given space.
Also, now if I resize window to full size and collapse all the rows the empty is there for the scrollbar.
It looks like this -
Try to add the callback treeGridAfterExpandRow with the following code:
treeGridAfterExpandRow: function () {
this.fixScrollOffsetAndhBoxPadding();
}
I'm not sure that I exactly understand, which behavior you need to have. Probably the usage of two callbacks treeGridAfterExpandRow and treeGridAfterCollapseRow
treeGridAfterExpandRow: normalizeWidth,
treeGridAfterCollapseRow: normalizeWidth
with normalizeWidth defined as
var normalizeWidth = function () {
var $self = $(this), p = $self.jqGrid("getGridParam");
this.fixScrollOffsetAndhBoxPadding();
if (!p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%")) {
$self.jqGrid("setGridWidth", p.tblwidth + p.scrollOffset, false);
}
};
will more close to your requirements. The above code extend the width of the TreeGrid to the width of the scroll bar if the vertical scroll bar will be visible.

Callback for scroll event in Kendo UI grid

I have 2 tables rendered with kendo grid, these are scrollable. I have code which needs to be executed whenever the scroll happens in any of the table.
I've tried
jQuery("#grid").kendoGrid({
dataSource : dataSource,
columns : [{
field : 'name',
title : 'Name',
width : '160px'
}, {
field : 'dataTypeId.name',
title : 'Type',
width : '70px'
}],
height : 270,
scrollable : true,
AfterScroll: function() {
console.log("scrolled");
},
rowTemplate : kendo.template(jQuery("#custom-input-grid-rows").html()),
}).data("kendoGrid");
I tried to put some callbacks like onScroll, AfterScroll but they did not work for me.
How do I get a callback when scrolling happens in the kendo grid?
Hi got the same question today, and fixed it this way:
Attach the jQuery event .scroll() right after your Kendo Grid was initialized like:
$('#GridName .k-grid-content').scroll(function () {
alert('I am scrolling ...');
});
The above didn't work for me either, but led me along the correct lines. The k-virtual-scrollable-wrap class handles the the scrollable part of the grid (eg when you have frozen columns enabled), so try this code instead:
$('.k-virtual-scrollable-wrap').scroll(function () {
console.log("I am scrolling");
});

Extjs Grid Width Calculated Wrong

I am trying to create a Extjs Grid with no vertical and horizontal scroll bars. it means that the grid should expand to infinity in both direction.
here is my code:
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.util.*',
'Ext.state.*'
]);
Ext.onReady(function() {
Ext.QuickTips.init();
// setup the state provider, all state information will be saved to a cookie
//Ext.state.Manager.setProvider(Ext.create('Ext.state.CookieProvider'));
var cols = 50;
var colsData = [];
var fields = [];
for(var i=1;i<cols;i++){
colsData.push(
{
text : 'COLUMN - ' + i,
//flex : 1,
width : 120,
sortable : true,
dataIndex: 'COL'+i
});
fields.push(
{name: 'COL'+i, type: 'int'}
);
}
var myData = [];
//create data
for(var i=1;i<500; i++){
var subData = [];
for(var j=1;j<cols; j++){
subData.push(Math.floor((Math.random()*10000)+1));
}
myData.push(subData);
}
function change(val) {
return val;
}
// create the data store
var store = Ext.create('Ext.data.ArrayStore', {
fields: fields,
data: myData
});
// create the Grid
var grid = Ext.create('Ext.grid.Panel', {
store: store,
stateful: true,
//stateId: 'stateGrid',
autoHeight: true,
autoWidth: true,
autoScroll: false,
//containerScroll: false,
columns: colsData,
//height: 100,
//width: 600,
title: 'Array Grid',
renderTo: 'grid-example',
viewConfig: {
//stripeRows: false,
//forceFit: false
}
});
});
i'm rendering my grid to a div element so practically i don't use any layout or etc.
<div id="grid-example" class="myDiv"></div>
and the styles:
<style type="text/css">
body{
overflow: visible;
}
.myDiv{
display: block;
/*float: left;*/
overflow: visible;
}
</style>
Here is my browser's screen shot that shows the vertical scroll bar [just like I expected].
THE PROBLEM IS
There is NO horizontal scroll bar and part of columns just cut off from page and there is no way to see the data they are presenting.
i can see that extjs tries to calculate the height and the width for the grids. in case of height it's correct but for width it's not, the calculated width is equals to my browser's width, not to the sum of columns which are in the grid.
I appreciate any suggestion or words from your side, thank you.
any one can help me with that?
I solved this problem by registering a numbers of listeners on viewConfig.viewready, grid.columnresize and etc. So we calculate the total width of columns each time we render a grid or resize/change a visibility of a column. consequently, I expand the grid to the calculated size. something like:
var grid = Ext.create('Ext.grid.Panel', {
store: store,
stateful: true,
autoHeight: true,
columns: colsData,
title: 'Array Grid',
renderTo: 'grid-example',
viewConfig: {
listeners: {
viewready:function(){
var totalWidth = 0;
Ext.each(grid.columns, function(column, index) {
if (column.isHidden() == false)
totalWidth += column.width;
});
//console.log("Width: " + totalWidth);
grid.setWidth(totalWidth);
}
}
}
,listeners: {
columnresize: function(){
grid.viewConfig.listeners.viewready();
},
columnhide: function(){
grid.viewConfig.listeners.viewready();
},
columnshow: function(){
grid.viewConfig.listeners.viewready();
}
}
});
});
Perhaps you are loking for autoScroll? Don't know what kind of behaviour you want from the question.
The question remains, do you want the grid to have scrollbars, or do you want the div to have scrollbars, or do you want the browser to have scrollbars?
The div is a block level element in HTML. It will automatically fill the browser's width, no more, no less in your example. ExtJS will then fill that div with the grid, making the grid as large as the browser's window, no more. Since you do not allow the grid to have scrollbars, the excess columns are cut off.
If you want the grid to have scrollbars, use autoScroll set to true.
If you want the div to scroll instead, set overflow: auto instead of visible on .myDiv. You would have to specify width on the grid itself too, and make it as wide as the width of the columns.
I recommend letting ExtJS handle the scrollbar as ExtJS can use more efficient rendering if you let it (only render columns and rows that are actually visible).

Categories

Resources