jqGrid: встроенное редактирование всей строки, но фокусировка на ячейке нажата, чтобы войти в режим редактирования. - PullRequest
1 голос
/ 17 июля 2011

Наше веб-приложение использует jqGrid для ввода данных, и данные редактируются в строках и строках.

Заказчик желает получить больше опыта, подобного Excel, чтобы при переключении строки на встроенное редактирование с помощью щелчка по ячейке эта ячейка получала фокус (в настоящее время первая ячейка в строке получает фокус).

Ответы [ 6 ]

1 голос
/ 19 августа 2014

Я столкнулся с той же проблемой. Очень расстраивает. Я изменил файл jquery.jqGrid.js, чтобы настроить фокусировку на ячейке, по которой щелкнули.

В моей функции editRow я добавил следующий код:

function editRow(id, row, col, z)
{
    grid.jqGrid("editRow", id, true, function ()
    {
        var f = $("input, select", z.target).focus();

        return f;
    });
}

Это создаст переменную f, которая в конечном итоге будет передана "oneditfunc" в $ .jgrid.extend

Проблема в функции setTimeout.

$("td:eq("+focus+") input",ind).focus();

, поскольку это выполняется с фокусом, установленным на первое редактируемое поле из функции .each выше. Это было бы отличным местом для передачи индекса фокуса, но это невозможно.

// End compatible
return this.each(function ()
{
    var $t = this, nm, tmp, editable, cnt = 0, focus = null, svr = {}, ind, cm, bfer;
...

Затем я добавил следующий код. (Строка с >>> неизменна. Она только там, чтобы помочь вам найти точку вставки в коде.)

    >>>     $($t).triggerHandler("jqGridInlineEditRow", [rowid, o]);


    if ($.isFunction(o.oneditfunc))
    {
        // modified to allow for setting focus on the 
        // field clicked on

        // sets a return value.  this was added to the original code.  if using
        // legacy code, should see no change as r will be undefined
        var r = o.oneditfunc.call($t, rowid);

        // if get a return value, this indicates you want to set focus
        if (r && r[0])
        {
            var focusIndex = focus;
            var i = 0;

            // look for the field name that was clicked on
            // cm, which is built above, has no index value associated
            // with it, so we must keep track of
            var focusField = $.grep(cm, function(c)
            {
                // find the field name which was clicked on
                if (c.name == r[0].name)
                    focusIndex = i;

                i++;

                return c.name == r[0].name;
            });

            // if the field is editable, then update focus index
            // which is defined above
            if (focusField[0].editable)
            {
                focus = focusIndex;
            }
        }
    }

Самое элегантное решение? Вероятно, нет, но он позволяет всему унаследованному коду работать и выяснять, на каком поле щелкнули, поэтому можно установить фокус

0 голосов
/ 06 января 2017

Я разместил этот ответ в другом вопросе, связанном со stackoverflow. Надеюсь, что это относится к вам.

Мне как-то удалось это сделать, прикрепив событие dblclick к каждому td таблицы. Я знаю, что это не лучший метод, но вы можете оптимизировать его так, как вам нравится, вы также можете игнорировать setTimeout, который использовался только для тестирования.

 $("#jqGrid").on("dblclick", "td", function (event) {   
                 //   setTimeout(function () {
                        console.log(this);
                        $(event.target).find("input,select").focus();                     
                  //  }, 0);
                });

Надеюсь, это поможет вам.

0 голосов
/ 16 июня 2015

Со своей стороны, я использовал ответы Джастина Этьера и Стива, чтобы придумать собственное решение (для jqGrid 4.4.3):

В источнике jqGrid я просто закомментирую следующую строку (это предотвращает получение первого ввода отредактированной строки для получения фокуса):

// commented out 
// $("td:eq("+focus+") input",ind).focus();

Затем я создаю глобальную переменную js, которая будет содержать источник щелчка по сетке:

var clickedCell;

И, наконец, установите эту переменную при нажатии на ячейку.

$('#myJqGrid td').on('click', function(e){ clickedCell = this; });

Чтобы иметь возможность прикрепить событие к ячейке таблицы, мы должны быть уверены, что сетка создана, поэтому это необходимо сделать в функции gridComplete jqGrid, например ::

$('#myJqGrid').jqGrid('setGridParam', {
    gridComplete: function(id){ 
                      $('#myJqGrid td').on('click', function(e){  clickedCell = this; });
                  }
});

И, наконец, при редактировании строки я извлекаю ячейку, по которой щелкнули (сохраненную в переменной "clickedCell"), и задаю фокус ввода или текстовой области внутри нее. Это должно быть сделано в функции "onSelectRow" jqGrid:

$('#myJqGrid').jqGrid('setGridParam', 
                          { 
                             onSelectRow : function(id) {
                                 ... 
                                 //switching the selected row to editmode
                                 $('#myJqGrid').jqGrid(
                                    'editRow', 
                                    id, 
                                    {
                                       keys: true,
                                       // when editing the row, give the focus to the input
                                       //or textarea within the last clicked cell
                                       oneditfunc: function() {
                                           $('input, textarea', clickedCell).focus();
                                    }
                                 );
                                 ...
                             }
                          }
                       });

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

0 голосов
/ 18 июля 2011

Это серьезный недостаток в jqGrid.Если сетка шире окна, вам также нужно прокрутить вправо, чтобы сделать видимой ячейку, на которую щелкнули.Для этого вы можете использовать код от http://www.trirand.com/blog/?page_id=393/help/inline-edit-problem-with-scrolling/

        if (rowID && rowID !== lastSelectedRow) {
           var scrollPosition = 0;
           scrollPosition = grid2.closest(".ui-jqgrid-bdiv").scrollLeft();
            grid2.jqGrid('restoreRow', lastSelectedRow);
            grid.jqGrid('editRow', rowID, true);
            lastSelectedRow = rowID;
            setTimeout(function(){ 
              grid2.closest(".ui-jqgrid-bdiv").scrollLeft(scrollPosition);
              },100); 
0 голосов
/ 18 июля 2011

Я согласен с Джастином, что jqGrid не имеет прямой поддержки поведения, которое вам нужно. Способ, который вы можете получить, который вам нужен, может быть более сложным, как один из вариантов jqGrid. Посмотрите на код из ответа . Я надеюсь, что это поможет вам.

0 голосов
/ 17 июля 2011

К сожалению, сетка может установить фокус только на первое редактируемое поле в строке.Вы можете увидеть это в исходном коде grid.inlinedit.js .Здесь он вычисляет индекс строки, на которую нужно установить фокус, перебирая их и находя первую:

if(cm[i].editable===true) {
    if(focus===null) { focus = i; }

, а затем устанавливает фокус:

$("td:eq("+focus+") input",ind).focus();

, котораявыбирает элемент по индексу, хранящемуся в переменной focus - для справки см. : eq selector документы.

Тем не менее, если вы склонны, вы можете редактировать этот разделкод для добавления вашей собственной логики для управления тем, какой элемент получает фокус ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...