Extjs Grid Width Calculated Wrong - javascript

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).

Related

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.

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

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.

How to keep an icon in the correct position? (right of field and field re-positions)

In general, I am trying to have an icon which stays to the right of a field. I need it to work in Firefox, Chrome, IE11 and IE8
JS Fiddle: http://jsfiddle.net/e8f6N/3/
There is a fieldset which can be expanded or collapsed. When the fieldset changes, the fields below it move up or down to compensate for the movement. When this happens, Firefox is unique in that the icons do not move with the field's body.
I find that if I use relative positioning rather than absolute, the icon will move with the field like it should. However, then there is some white space being put below each field, which I do not want.
Advice is appreciated in the following questions:
A way for firefox to move the icon with the rest of the field?
A way to use relative positioning and not have the extra space being
inserted below the field?
Alternatively, a better way to skin this cat?
Code used in fiddle:
Ext.onReady(function () {
Ext.QuickTips.init();
var fieldSet = Ext.create('Ext.form.FieldSet', {
title: 'Simple Collapsible Fieldset',
collapsible: true,
items: [{
xtype: 'label',
text: 'Watch the icon and collapse this fieldset'
}]
});
var textBoxWithInfoIcon = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example',
listeners: {
afterrender: function (me) {
var icon = me.getEl().down('.x-form-item-body').createChild({
cls: 'x-form-info-icon',
tag: 'img',
src: 'broken',
width: 16,
height: 18,
'data-qtip': 'an example textfield to simulate this icon which does not move',
'data-qtitle': 'Field Information'
});
var xPosition = 130;
var yPosition = 0;
icon.alignTo(me.getEl(), 'tl-tr', [xPosition, yPosition]);
}
}
});
var textBox = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example'
});
var textBoxWithInfoIcon2 = Ext.create('Ext.form.field.Text', {
fieldLabel: 'Example',
listeners: {
afterrender: function (me) {
var icon = me.getEl().down('.x-form-item-body').createChild({
cls: 'x-form-info-icon',
tag: 'img',
src: 'broken',
width: 16,
height: 18,
'data-qtip': 'an example textfield to simulate this icon which does not move',
'data-qtitle': 'Field Information'
});
var xPosition = 130;
var yPosition = 0;
icon.alignTo(me.getEl(), 'tl-tr', [xPosition, yPosition]);
}
}
});
var panel = Ext.create('Ext.panel.Panel', {
title: 'Title',
frame: true,
width: 400,
height: 200,
items: [fieldSet, textBoxWithInfoIcon, textBox, textBoxWithInfoIcon2],
renderTo: document.body
});
});
p.s. There are a lot of questions with similar titles, yet as far as I've found they don't have to deal with a collapsing fieldset and just use absolute positioning in their css.
EDIT
More details after working with it for a while: After trying to add an info icon to a field's body, the input of the field is at the same level as the icon, but the input is set to take up 100% of the width. I am not sure where/how I can change this.
Absolute positioning of the injected icons is not the best solution for the info icons after fields.
Much better would be to add a after the input field parent . That would solve everything: Input would get shorter to make space for the icon, no need to calculate and set position of the icon, no problems with collapsible fieldset as of now.
I think you need this plugin: Form Field Icon Plugin

Ext Panel not resizing on accordian expand

I have a panel with an accordian layout containing multiple (max. 10) property grids.
This works fine when there are a couple of property grid items and there is space in the panel to expand them. However if the panel is full of collapsed grids then they cannot be expanded. Manually increasing the height of the panel allows them to be expanded.
autoScroll is enabled. If I set autoHeight true the panel sizes to fit all items collapsed but wont resize to expand one.
Hopefully someone can tell me what I am doing wrong.
I am working with Ext 3.4.0 due to compatibility with GeoExt.
Thanks
Tom
Example showing 2 property grids expanding correctly
http://s9.postimg.org/ex4e6nxwv/working.jpg)
Example showing 10 property grids that wont expand
http://s13.postimg.org/r06ylu2h3/not.jpg
Code for creating panel and propertygrids:
items.push({
xtype: "propertygrid",
title: title,
source: feature.attributes,
sorting: false
});
if (items.length > 0) {
new GeoExt.Popup({
title: "Feature Info - (" + items.length + " Results)" + maxFeatures,
width: 400,
height: 300,
layout: "accordion",
autoScroll: true,
map: Map,
location: evt.xy,
items: items
}).show();
}
I'm not sure if there is a way to get it to do what you want as it is without eliminating the height parameter alltogether which will obviously mean it will be taller.
If you want to keep it at that height, you can just throw it inside another panel:
var expandos = Ext.create('Ext.panel.Panel', {
width: 300,
title: 'Accordion with ' + grids.length + ' panels',
layout: 'accordion',
resizable: true,
items: grids
});
Ext.create('Ext.panel.Panel', {
renderTo: 'center_div',
height:400,
width:315,
autoScroll: true,
items:expandos
});
http://jsfiddle.net/SFMpd/2/

Categories

Resources