¿Cómo puedo obtener columnas congeladas jqgrid para que funcionen con el ajuste de palabras en

Estoy usando el último jqgrid 4.3.1 y estoy tratando de usar columnas congeladas.

El problema es que he anulado el CSS predeterminado para admitir el ajuste de palabras (la solución css se puede ver en esta pregunta ) en jqgrid y creo que esa es la razón por la que las columnas congeladas no se alinean correctamente con las columnas normales. Las alturas de las filas congeladas no son las mismas que las alturas del rest de la cuadrícula. Aquí hay una captura de pantalla … las columnas congeladas se destacan en el cuadro rojo (NOTA: taché el contenido porque no es un sitio público:

¿Hay alguna forma de que las columnas congeladas se alineen con celdas envueltas por palabras en jqgrid?

enter image description here

NOTA: después de probar la solución de Oleg a continuación, funciona en Firefox pero en IE8 no veo la barra de desplazamiento horizontal (ver foto)

Firefox:

enter image description here

IE: (nótese que no hay barra de desplazamiento horizontal)

enter image description here

NOTA:

Para ayudar a responder la pregunta de Oleg, aquí hay un volcado de mi configuración jqgrid:

jQuery(gridSelector).jqGrid({ mtype: 'POST', toppager: true, url: siteRoot + controller + "/" + gridDataName + "?" + querystring, datatype: "json", colNames: names, colModel: model, shrinkToFit: false, imgpath: siteRoot + "Scripts/jqGrid431/themes/steel/images", rowNum: 20, rowList: [10, 20, 50, 999], altRows: true, altclass: "altRow", jsonReader: { root: "Rows", page: "Page", total: "Total", records: "Records", repeatitems: false, id: "Id" }, search: true, postData: (myfilter) ? { filters: JSON.stringify(myfilter)} : {}, //postData: { filters: JSON.stringify(myfilter) }, pager: pagerSelector, height: "auto", sortname: sortCol, viewrecords: true, sortorder: sortDirection, beforeRequest: function () { var grid = jQuery(gridSelector); if (gridprefs && gridprefs.filter) { grid.setPostDataItem('_search', true); for (var prop in gridprefs.filter) { var value = eval('gridprefs.filter.' + prop); if ('' + value != '') { grid.setPostDataItem(prop, value); } } grid.setPostDataItem('sidx', gridprefs.scol); grid.setPostDataItem('sord', gridprefs.sord); grid.setPostDataItem('page', gridprefs.page); grid.setPostDataItem('rows', gridprefs.rows); grid.jqGrid('setGridParam', { sortname: gridprefs.scol, sortorder: gridprefs.sord, page: gridprefs.page, rowNum: gridprefs.rows }); } }, loadComplete: function () { var newCapture = "", filters, rules, rule, op, i, iOp, postData = jQuery(gridSelector).jqGrid("getGridParam", "postData"), isFiltering = jQuery(gridSelector).jqGrid("getGridParam", "search"); if (isFiltering === true && typeof postData.filters !== "undefined") { filters = $.parseJSON(postData.filters); newCapture = "Filter: ["; rules = filters.rules; for (i = 0; i = 0 && typeof $.jgrid.search.odata[iOp] !== "undefined") { op = $.jgrid.search.odata[iOp]; } newCapture += rule.field + " " + op + " '" + rule.data + "'"; if (i + 1 !== rules.length) { newCapture += ", "; } } newCapture += "]"; } jQuery(gridSelector).jqGrid("setCaption", newCapture); fixPositionsOfFrozenDivs.call(this); $(gridSelector).supersleight({ shim: siteRoot + 'Content/Images/shim.gif' }); if (gridprefs && gridprefs.filter) { for (var prop in gridprefs.filter) { $('#gs_' + prop).val(eval('gridprefs.filter.' + prop)); } $(".ui-pg-selbox").val(gridprefs.rows); $(".ui-pg-input").val(gridprefs.page); } gridprefs = {}; }, editurl: siteRoot + controller + "/Update" + appendRoute, ondblClickRow: editable ? function (rowid) { jQuery(gridSelector).editGridRow(rowid, { width: 600 }); } : function (rowid) { } }); //$(gridSelector).jqGrid('navGrid', '#pager', { search: true, cloneToTop: true }); $(gridSelector).jqGrid('filterToolbar', { stringResult: true, searchOnEnter: true }); jQuery(gridSelector).jqGrid('bindKeys', {}); if (editable) { jQuery(gridSelector).navGrid(pagerSelector, { cloneToTop: true, refresh: false }, { height: 380, width: 500, reloadAfterSubmit: true, closeAfterEdit: true, url: siteRoot + controller + "/Update", zIndex: 1100 }, { height: 380, width: 500, reloadAfterSubmit: true, closeAfterAdd: true, url: siteRoot + controller + "/Add", zIndex: 1100 }, { reloadAfterSubmit: true, url: siteRoot + controller + "/Delete" }, { multipleSearch: true, beforeShowSearch: function($form) { $('#searchmodfbox_' + $(gridSelector)[0].id).width(560); } }); } else { jQuery(gridSelector).navGrid(pagerSelector, { cloneToTop: true, refresh: false, add: false, edit: false, del: false }, { }, { }, { }, { multipleSearch: true, beforeShowSearch: function($form) { $('#searchmodfbox_' + $(gridSelector)[0].id).width(560); } }); } myAddButton(gridSelector, { caption: "", title: "Reload Grid", buttonicon: 'ui-icon-refresh', onClickButton: function () { $(gridSelector).trigger("reloadGrid"); } }); } 

La implementación de columnas congeladas en jqGrid se basa en la creación de dos divs adicionales con posición absoluta sobre la grilla estándar. Si la altura de todos los encabezados de columna y todas las filas del cuerpo de la grilla son las mismas, las columnas congeladas funcionan bien, pero en caso de altura variable (uso de height: auto CSS height: auto ) uno tiene los siguientes resultados (vea la primera demostración ):

enter image description here

El primer div, llamado fhDiv , que fhDiv con color amarillo contiene la copia del encabezado de columna (el hDiv ) donde se hDiv las últimas columnas no congeladas. De la misma manera, el segundo div, llamado fbDiv , que fbDiv con color rojo contiene la copia del cuerpo de la grilla (el bDiv ) donde se bDiv las últimas columnas no congeladas. Puede leer más aquí sobre los elementos de grilla estándar.

En la demostración utilicé el ajuste de caracteres en los encabezados de las columnas que describí en la respuesta y en el ajuste de palabras que se describe, por ejemplo, aquí .

La altura de cada fila de fhDiv o fbDiv se calculará independientemente de la altura de las columnas no congeladas. Entonces, la altura de las filas puede ser menor según sea necesario.

Es difícil sugerir la solución perfecta del problema, pero parece que encontré una forma pragmática bastante buena. La idea es establecer el alto de cada fila de fhDiv y fbDiv explícitamente en función del tamaño de la fila correspondiente en las inmersiones principales hDiv y bDiv . Así que extendí el código de la función fixPositionsOfFrozenDivs que se describe en la respuesta a lo siguiente:

 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()); } }; 

Llamé al método dentro de resizeStop y loadComplete callbacks. En caso de utilizar el método gridResize , es necesario incluir soluciones adicionales dentro del controlador de detención .

Las sugerencias completas que puede ver en la demostración que corrige los resultados de la primera demostración son los siguientes:

enter image description here

ACTUALIZADO : la respuesta contiene la versión actualizada de la demostración: esta .

Entonces esta es la función que redimensionará las columnas.

 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) ); }); } 

Regla CSS

 .ui-jqgrid tr.jqgrow td{ height: auto; white-space: normal; } 

Y el init

 jQuery("#gfrc1").jqGrid({ //options 'loadComplete': updateSize, 'resizeStop': updateSize }); //Frozen Columns init jQuery("#gfrc1").jqGrid('setFrozenColumns'); 

No es bueno, pero funciona. Hay algo con errores cuando traté de configurarlo con el método setParams, el contexto está cambiando, así que mejor hacerlo en init de jqGrid. Si necesita establecer su funcionalidad simplemente use apply para actualizar el método de tamaño en su función y guarde este contexto.

La otra cosa es la altura y el colapso de la frontera, no sé realmente cómo resolver ese problema mejor 🙂

Y ejemplo con datos estáticos.

Suponiendo que este es el CSS que usaste (desde tu enlace):

 .ui-jqgrid tr.jqgrow td { white-space: normal !important; height:auto; vertical-align:text-top; padding-top:2px; } 

Debería poder deshacerse de la barra de desplazamiento con (observe que el selector es .ui-jqgrid tr.jqgrow not .ui-jqgrid tr.jqgrow td ):

 .ui-jqgrid tr.jqgrow { overflow: hidden; } 

La height: auto; es lo que está causando que las filas sean más cortas. Intenta eliminar eso de tu CSS por completo. Si eso no funciona, también puede establecer todos los elementos

a la misma altura o todos a auto (ambos no probados, ya que no publicó el código).

prueba esto:

 qgrid tr.jqgrow td { white-space: nowrap !important; } 

No pude lograr que la solución de Oleg funcionara, pero hice algo basado en su trabajo que está funcionando para mí. No estoy seguro si me perdí algo, pero como esto me funciona, pensé en compartir:

También tuve que agregar una línea a mi archivo CSS

 .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"); }); }; 

Lo he visto y entiendo por qué aparece este problema.

Cuando las columnas congeladas se muestran en realidad hay algunas duplicaciones de tablas, pero solo las columnas congeladas y si configura el espacio en blanco en normal, y en alguna parte de la cuadrícula aparece una columna no igual de altura en el área no congelada, está empezando a perder en altura.

La duplicación de tablas para no volver a calcular params de tablas en js, por lo que hay algún problema de que si necesita esta propiedad css, debe configurar sus eventos gridComplete y resizeStop (o cualquier otra persona que cambie el ancho de cols) para que funcione así :

 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 }); 

No es testetd lo escribí aquí pero algunas correcciones y debería funcionar bien, no tengo configuración jqGrid ahora.

Que te diviertas 🙂

Por cierto, es una solución terrible si necesitas ver muchas filas, y sería bueno establecer la tarea de problema en github