Как я могу получить замороженные столбцы jqgrid для работы с переносом слов на - PullRequest
10 голосов
/ 31 декабря 2011

Я использую последнюю версию jqgrid 4.3.1 и пытаюсь использовать замороженные столбцы.

Проблема в том, что я переопределил css по умолчанию для поддержки переноса слов (решение css можно увидеть в этом вопросе ) в jqgrid, и я думаю, что это причина того, что замороженные столбцы не выравниваются правильно с обычными столбцами. Высота замороженных рядов не совпадает с высотой остальной части сетки. Вот скриншот ... замороженные столбцы выделены красным цветом (ПРИМЕЧАНИЕ: я вычеркнул содержимое, если оно не является общедоступным сайтом:

В любом случае, есть ли в jqgrid строки 100 строк со строкой, завернутой в слова?

enter image description here

ПРИМЕЧАНИЕ: после попытки решения Олега ниже, оно работает в Firefox, но в IE8 я не вижу горизонтальную полосу прокрутки (см. Рис.)

Firefox:

enter image description here

IE: (обратите внимание, горизонтальная полоса прокрутки отсутствует)

enter image description here

Примечание:

Чтобы помочь ответить на вопрос Олега, вот дамп моей установки 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 < rules.length; i++) {
                rule = rules[i];
                op = rule.op;  // the code name of the operation
                iOp = $.inArray(op, arOps);
                if (iOp >= 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");
        }
    });

}

Ответы [ 6 ]

14 голосов
/ 07 января 2012

Реализация замороженных столбцов в jqGrid основана на создании двух дополнительных div с абсолютной позицией над стандартной сеткой. Если высота всех заголовков столбцов и всех строк тела сетки одинакова, замороженные столбцы работают хорошо, но в случае переменной высоты (использование height: auto CSS) можно получить следующие результаты (см. первое демо) ):

enter image description here

Первый div, так называемый fhDiv, который я пометил желтым цветом, содержит копию заголовка столбца (hDiv), где удаляются последние не замороженные столбцы. Точно так же второй div, так называемый fbDiv, который я пометил красным цветом, содержит копию тела сетки (bDiv), где удаляются последние не замороженные столбцы. Вы можете прочитать здесь подробнее о стандартных элементах сетки.

В демонстрации я использовал перенос символов в заголовках столбцов, который я описал в ответе , и перенос слов, описанный, например, здесь .

Высота каждой строки fhDiv или fbDiv будет рассчитываться независимо от высоты незамерзающих столбцов. Таким образом, высота строк может быть меньше требуемой.

Трудно предложить идеальное решение проблемы, но, похоже, я нашел достаточно хороший прагматичный путь. Идея состоит в том, чтобы установить высоту каждой строки из fhDiv и fbDiv в явном виде на основе размера соответствующей строки в основных погружениях hDiv и bDiv. Поэтому я расширил код функции fixPositionsOfFrozenDivs, описанной в ответа , на следующее:

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

Я вызвал метод внутри resizeStop и loadComplete обратных вызовов. В случае использования метода gridResize необходимо добавить дополнительные исправления внутри обработчика stop .

Полный список моих предложений вы можете увидеть на демонстрации , которая фиксирует результаты первой демонстрации на следующих:

enter image description here

ОБНОВЛЕНО : Ответ содержит обновленную версию демоверсии: эта .

2 голосов
/ 04 января 2012

Так что это функция, которая будет изменять размер столбцов.

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

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

И init

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

Не хорошо, но этоработает.Когда я пытался установить его с помощью метода setParams, есть некоторая ошибка, контекст меняется, поэтому лучше сделать это при инициализации jqGrid.Если вам нужно настроить свою функциональность, просто используйте метод apply для обновления в своей функции и сохраните этот контекст.

Другое дело в высоте и обвале границы, я действительно не знаю, как решить эту проблемулучше:)

и пример со статическими данными.

1 голос
/ 01 февраля 2013

Я не смог заставить работать решение Олега, но я сделал что-то на основе его работы, которая работает для меня. Не уверен, что что-то пропустил, но так как это работает для меня, я решил поделиться:

Мне также пришлось добавить строку в мой файл 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");
     });
 };
1 голос
/ 07 января 2012

попробуйте это:

qgrid tr.jqgrow td {

white-space: nowrap !important;

}
1 голос
/ 03 января 2012

Предполагая, что это CSS, который вы использовали (по вашей ссылке):

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

Вы должны быть в состоянии избавиться от полосы прокрутки с помощью (обратите внимание, селектор .ui-jqgrid tr.jqgrow не .ui-jqgrid tr.jqgrow td):

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

height: auto; - это то, что заставляет строки быть короче.Попробуйте удалить это из вашего CSS полностью.Если это не сработает, вы также можете установить для всех элементов <td> одинаковую высоту или для всех элементов значение auto (оба не проверены, поскольку вы не отправляли код).

0 голосов
/ 03 января 2012

Я посмотрел на нее и понял, почему возникла эта проблема.

Когда замороженные столбцы показывают на самом деле, есть некоторое дублирование таблиц, но только замороженные столбцы и если вы устанавливаете пустое пространство в нормальное состояниеи где-то в сетке появляется столбец не равной высоты, в не замороженной области он начинает не соответствовать по высоте.

Дублирование таблиц сделано для того, чтобы не пересчитывать параметры таблиц в js, поэтому существует некоторая проблема, заключающаяся в том, что если вам нужно это свойство css, вам следует установить события gridComplete и resizeStop (или любого другого, который будет изменять столбцыwidth), чтобы функционировать так:

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

Это не testetd, я написал это здесь, но некоторые исправления и должны работать нормально, у меня нет настройки jqGrid сейчас.

Веселитесь:)

Кстати, это ужасное решение, если вам нужно увидеть много строк, и было бы неплохо установить задачу выдачи на github

...