Inline Edit на Enter, используя множественный выбор, Multibox и прокрутки: 1 - PullRequest
3 голосов
/ 29 мая 2011

Как запустить встроенное редактирование, если в jqGrid нажата клавиша Enter и опция multiselect: true также используется?Если присутствует мультиселект, функция jqGrid bindKeys не оказывает никакого влияния.

Для проверки можно использовать приведенный ниже тестовый пример (на основе примера, предоставленного в комментарии Олега).

Шаги для воспроизведения:

  1. Сохраните приведенный ниже код в html-файл и откройте его в IE 9
  2. Щелкните по сетке и нажмите enter

Observed:

  1. Окно сообщения не появляется
  2. Также стрелки вверх и вниз перемещают всю сетку

Ожидается:

  1. При нажатии на кнопку должно появиться окно сообщения
  2. стрелки вверх и вниз должны изменить текущую строку в сетке

Как получить ожидаемое поведение?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title>http://stackoverflow.com/questions/5988767/highlight-error-cell-or-input-when-validation-fails-in-jqgrid</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/themes/redmond/jquery-ui.css" />
    <link rel="stylesheet" type="text/css" href="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.0.0/css/ui.jqgrid.css" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
    <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.0.0/js/i18n/grid.locale-en.js"></script>
    <script type="text/javascript">
        $.jgrid.no_legacy_api = true;
        $.jgrid.useJSON = true;
    </script>
    <script type="text/javascript" src="http://www.ok-soft-gmbh.com/jqGrid/jquery.jqGrid-4.0.0/js/jquery.jqGrid.min.js"></script>
    <script type="text/javascript">
        $(function () {
            var mydata = [
                    { id: "1", invdate: "2007-10-01", name: "test", note: "note", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" },
                    { id: "2", invdate: "2007-10-02", name: "test2", note: "note2", amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
                    { id: "3", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", closed: false, ship_via: "FE", total: "430.00" },
                    { id: "4", invdate: "2007-10-04", name: "test4", note: "note4", amount: "200.00", tax: "10.00", closed: true, ship_via: "TN", total: "210.00" },
                    { id: "5", invdate: "2007-10-31", name: "test5", note: "note5", amount: "300.00", tax: "20.00", closed: false, ship_via: "FE", total: "320.00" },
                    { id: "12", invdate: "2007-09-10", name: "test12", note: "note12", amount: "500.00", tax: "30.00", closed: false, ship_via: "FE", total: "530.00" }
                ];

            var grid = $("#grid");
            grid.jqGrid({
                datatype: 'local',
                data: mydata,
                colModel: [
                    { name: 'invdate', editable: true, width: 30 },
                    { name: 'name', editable: true, width: 271 }
                ],
                gridview: true,
                pager: '#pager',
                viewrecords: true,
                multikey: "ctrlKey",  // added July 6, 2011
                scroll:1,  // added July 6, 2011 todo: data should passed from URL
                multiselect: true,
                multiboxonly: true,
                editurl: 'clientArray'
            });

        $("#grid").jqGrid('bindKeys', {
            onEnter: function (rowid) {
                alert("You enter a row with id: " + rowid);
            }
        });
      });
    </script>
</head>
<body>
        <table id="grid"></table>
        <div id="pager"></div>
</body>
</html>

ОБНОВЛЕНИЕ: добавлено multiboxonly: true в тестовый сценарий, демонстрировать предыдущую строкуне выбрана проблема

Обновление

Добавлен мультиключ: "ctrlKey" в testcase.В этом случае предлагаемый bindKeys в Олеге ответ перестает работать

1 Ответ

5 голосов
/ 30 мая 2011

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

Единственное, что вы должны принять во внимание, что после окончания редактирования строки фокус теряется, и вы не можете использовать стрелки для перемещения следующей строки. Вы должны использовать параметр aftersavefunc метода editRow , чтобы восстановить фокус сетки:

var grid = $('#grid');
grid.jqGrid('editRow',rowid,true,null, null, null, {},function(){
    setTimeout(function(){
        grid.focus();
    },100);
});

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

ОБНОВЛЕНО : Я прошу вас всегда добавлять ваш первоначальный вопрос с дополнительной информацией вместо полного переписывания вопроса. Ваш оригинальный вопрос не содержал ничего об использовании multiselect: true. Этот случай (multiselect: false) и моя первая демоверсия могут заинтересовать других пользователей. Таким образом, общая практика состоит в том, чтобы добавить исходный вопрос с частью "ОБНОВЛЕНО:" или просто задать новый вопрос В настоящее время, если кто-то прочтет ваш вопрос и мой ответ, он / она спросит: «Что за странный ответ? Возможно, ответ не внимательно прочитан на вопрос».

Теперь о вашей текущей проблеме в случае multiselect: true. Как вы знаете, jqGrid 4.0.0 - это первая версия, в которой поддерживается клавиатурная навигация в сетке и древовидной сетке, а также метод bindKeys Решение далеко не идеальное. Многие действия не могут быть выполнены с помощью клавиатуры. Например, кнопки на панели инструментов навигации («Добавить», «Редактировать», «Удалить» и т. Д.) Нельзя нажимать по отношению к клавиатуре. Чтобы использовать навигацию с помощью клавиатуры в jqGrid, многие места кода jqGrid расширены настройкой атрибута tabindex. Например, в строке выбранная строка (элемент <tr>) получает атрибут tabindex="0", но строка работает только в случае multiselect: false. В строка из bindKeys кода будет искать (и не найден) атрибут tabindex="0". Таким образом, текущая реализация bindKeys не работает в режиме multiselect: true.

Как я уже писал ранее, полная поддержка режима multiselect: true может быть реализована только со многими изменениями в коде jqGrid. В качестве обходного пути я мог бы предложить следующее: мы можем перезаписать код метода bindKeys только с измененной реализацией.

Соответствующую демонстрацию вы можете найти здесь . Код JavaScript в демонстрационной форме:

$.extend($.fn.jqGrid,{
    bindKeys : function( settings ){
       'use strict';
        var o = $.extend({
            onEnter: null,
            onSpace: null,
            onLeftKey: null,
            onRightKey: null,
            scrollingRows : true
        },settings || {});
        return this.each(function(){
            var $t = this;
            if( !$('body').is('[role]') ){$('body').attr('role','application');}
            $t.p.scrollrows = o.scrollingRows;
            $($t).keydown(function(event){
                var target = $($t).find('tr[tabindex=0]')[0], id, mind, r,
                expanded = $t.p.treeReader.expanded_field;
                if (!target && $t.p.selrow !== null) {
                    target = $t.rows.namedItem($t.p.selrow);
                }
                //check for arrow keys
                if(target) {
                    mind = $t.p._index[target.id];
                    if(event.keyCode === 37 || event.keyCode === 38 || event.keyCode === 39 || event.keyCode === 40){
                        // up key
                        if(event.keyCode === 38 ){
                            r = target.previousSibling;
                            id = "";
                            if(r) {
                                if($(r).is(":hidden")) {
                                    while(r) {
                                        r = r.previousSibling;
                                        if(!$(r).is(":hidden") && $(r).hasClass('jqgrow')) {id = r.id;break;}
                                    }
                                } else {
                                    id = r.id;
                                }
                            }
                            if ($.inArray(id,$t.p.selarrrow) === -1) {
                                $($t).jqGrid('setSelection', id);
                            } else {
                                $t.p.selrow = id;
                            }
                        }
                        //if key is down arrow
                        if(event.keyCode === 40){
                            r = target.nextSibling;
                            id ="";
                            if(r) {
                                if($(r).is(":hidden")) {
                                    while(r) {
                                        r = r.nextSibling;
                                        if(!$(r).is(":hidden") && $(r).hasClass('jqgrow') ) {id = r.id;break;}
                                    }
                                } else {
                                    id = r.id;
                                }
                            }
                            if ($.inArray(id,$t.p.selarrrow) === -1) {
                                $($t).jqGrid('setSelection', id);
                            } else {
                                $t.p.selrow = id;
                            }
                        }
                        // left
                        if(event.keyCode === 37 ){
                            if($t.p.treeGrid && $t.p.data[mind][expanded]) {
                                $(target).find("div.treeclick").trigger('click');
                            }
                            if($.isFunction(o.onLeftKey)) {
                                o.onLeftKey.call($t, $t.p.selrow);
                        }
                        }
                        // right
                        if(event.keyCode === 39 ){
                            if($t.p.treeGrid && !$t.p.data[mind][expanded]) {
                                $(target).find("div.treeclick").trigger('click');
                            }
                            if($.isFunction(o.onRightKey)) {
                                o.onRightKey.call($t, $t.p.selrow);
                        }
                        }
                        return false;
                    }
                    //check if enter was pressed on a grid or treegrid node
                    else if( event.keyCode === 13 ){
                        if($.isFunction(o.onEnter)) {
                            o.onEnter.call($t, $t.p.selrow);
                        }
                        return false;
                    } else if(event.keyCode === 32) {
                        if($.isFunction(o.onSpace)) {
                            o.onSpace.call($t, $t.p.selrow);
                        }
                        return false;
                    }
                }
            });
        });
    }
});

и

var grid = $("#list");
...

grid.jqGrid('bindKeys', {
    onEnter: function(rowid) {
        //alert("You enter a row with id: " + rowid);
        editingRowId = rowid; // probably cab be replaced to grid[0].p.selrow
        // we use aftersavefunc to restore focus
        grid.jqGrid('editRow',rowid,true,null, null, null, {},function(){
            setTimeout(function(){
                grid.focus();
            },100);
        });
    },
    onSpace: function(rowid) {
        grid.jqGrid('setSelection', rowid);
    }
});

// select one row at the begining and set the focus
grid.jqGrid('setSelection',"1");
grid.focus();

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

Редактировать

Если multikey: "ctrlKey" добавлен bindKeys. Код в ответ не работает. Также использование setFocus в коде ответа заставляет фокус перейти к другой строке после редактирования, поэтому его следует удалить. После редактирования текущей строки невозможно установить фокус, всегда требуется щелчок мышью, jqGrid не поддерживает встроенное редактирование только с клавиатуры.

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