I am using the latest jqgrid 4.3.1 and i am trying to use frozen columns.
The issue is that i have overridden the default css to support word wrap (css solution ca
The implementation of frozen columns in jqGrid are based on creating of two additional divs with absolute position over the standard grid. If the height of all column headers and all rows of the grid's body are the same the frozen columns works good, but in case of variable height (usage of height: auto
CSS) one have the following results (see the first demo):
The first div, so named fhDiv
, which I marked with yellow color contains the copy of the column header (the hDiv
) where the last non-frozen columns are removed. In the same way the second div, so named fbDiv
, which I marked with red color contains the copy of the grid body (the bDiv
) where the last non-frozen columns are removed. You can read here more about the standard grid elements.
In the demo I used character wrapping in the column headers which I described in the answer and the word wrapping described for example here.
The height of every row of the fhDiv
or fbDiv
will be calculated independent from the height of non-frozen columns. So the height of the rows can be less as required.
It is difficult to suggest perfect solution of the problem, but it seems that I found good enough pragmatical way. The idea is to set the height of every row from the fhDiv
and fbDiv
explicitly based on the size of the corresponding row in the main dives hDiv
and bDiv
. So I extended the code of fixPositionsOfFrozenDivs
function described in the answer to the following:
var fixPositionsOfFrozenDivs = function () {
var $rows;
if (typeof this.grid.fbDiv !== "undefined") {
$rows = $('>div>table.ui-jqgrid-btable>tbody>tr', this.grid.bDiv);
$('>table.ui-jqgrid-btable>tbody>tr', this.grid.fbDiv).each(function (i) {
var rowHight = $($rows[i]).height(), rowHightFrozen = $(this).height();
if ($(this).hasClass("jqgrow")) {
$(this).height(rowHight);
rowHightFrozen = $(this).height();
if (rowHight !== rowHightFrozen) {
$(this).height(rowHight + (rowHight - rowHightFrozen));
}
}
});
$(this.grid.fbDiv).height(this.grid.bDiv.clientHeight);
$(this.grid.fbDiv).css($(this.grid.bDiv).position());
}
if (typeof this.grid.fhDiv !== "undefined") {
$rows = $('>div>table.ui-jqgrid-htable>thead>tr', this.grid.hDiv);
$('>table.ui-jqgrid-htable>thead>tr', this.grid.fhDiv).each(function (i) {
var rowHight = $($rows[i]).height(), rowHightFrozen = $(this).height();
$(this).height(rowHight);
rowHightFrozen = $(this).height();
if (rowHight !== rowHightFrozen) {
$(this).height(rowHight + (rowHight - rowHightFrozen));
}
});
$(this.grid.fhDiv).height(this.grid.hDiv.clientHeight);
$(this.grid.fhDiv).css($(this.grid.hDiv).position());
}
};
I called the method inside of resizeStop
and loadComplete
callbacks. In case of usage of gridResize method one need include additional fixes inside of stop handler.
The full my suggestions you can see on the demo which fixs the results from the first demo to the following:
UPDATED: The answer contains updated version of the demo: this one.
So this is the function that will resize a columns.
function updateSize(){
//getting all lines in two tables by they id
var lines = $("tr", this),
flines = $("tr", "#"+$(this).attr("id")+"_frozen" );
//setting in all frozen lines height equel to grid
flines.each(function(i, item){
//i%2 check because of border collapse
$(item).height( $(lines[i]).innerHeight() - (i%2?1:0) );
});
}
CSS rule
.ui-jqgrid tr.jqgrow td{
height: auto;
white-space: normal;
}
And the init
jQuery("#gfrc1").jqGrid({
//options
'loadComplete': updateSize,
'resizeStop': updateSize
});
//Frozen Columns init
jQuery("#gfrc1").jqGrid('setFrozenColumns');
Not good but it works. There a bit buggy thing when i tried to set it with setParams method, context is changing so better to do it on init of jqGrid. If you will need to set you functionality just use apply to updateSize method in your function and save this context.
The other thing is in height and border-collapse, i don't know really how to solve that problem better :)
And example with static data.
Assuming this is the CSS you used (from your link):
.ui-jqgrid tr.jqgrow td {
white-space: normal !important;
height:auto;
vertical-align:text-top;
padding-top:2px;
}
You should be able to get rid of the scrollbar with (note the selector is .ui-jqgrid tr.jqgrow
not .ui-jqgrid tr.jqgrow td
):
.ui-jqgrid tr.jqgrow {
overflow: hidden;
}
The height: auto;
is what's causing the rows to be shorter. Try removing that from your CSS entirely. If that doesn't work you can also either set all <td>
elements to the same height or all to auto
(both untested, since you didn't post code).
I wasn't able to get Oleg's solution to work, but I made something based on his work that is working for me. Not sure if I missed something, but since this is working for me I thought I'd share:
I also had to add a line to my CSS file
.frozen-div{overflow:hidden;}
var fixPositionsOfFrozenDivs = function () {
var originalRowHeightArray = new Array();
var gridId = $(this).attr("id");
$("#" + gridId).find("tr").each(function () {
originalRowHeightArray.push($(this).find("td").first().height() + 1);
});
$rows = $('>div>table.ui-jqgrid-btable>tbody>tr', this.grid.bDiv);
$rows.each(function (i) {
var rowHight = $($rows[i]).height(), rowHightFrozen = $(this).height();
$(this).height(originalRowHeightArray[i] + "px");
});
};
I`ve looked at it and get why is this problem appeared.
When frozen columns is showing actually there is some duplicating of tables, but only the frozen cols and if you setting white-space to normal, and somewhere in grid appears not equal height column in not frozen area it's starting to missmatch in height.
The duplicating of tables done to do not recalculate params of tables in js, so there is some problem that if you need this css property than you should set your gridComplete and resizeStop events (or anyone else that will change cols width) to function like this:
function onChangeGrid(){
var frozen = $("#grid_frozen tr", this),
rows = $("#grid tr", this);
frozen.each(function(i, item){
var fEl = $(item),
h = $(rows[i]).height();
if( fEl.height() < h ){
fEl.height(h);
} else {
fEl.css("height", "auto");
}
});
}
$("#my_grid").jqGrid({
gridComplete: onChangeGrid,
resizeStop: onChangeGrid
});
It's not testetd i wrote it here but some fixes and should work fine, i havent jqGrid setup now.
Have fun :)
By the way, it's terrible fix if you need to see a lot of rows, and it would be nice to set issue task on github
try this:
qgrid tr.jqgrow td {
white-space: nowrap !important;
}