Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
473 views
in Technique[技术] by (71.8m points)

jqgrid - Inline Edit on Enter using multiselect, multibox and scroll:1

How to start inline edit if Enter is pressed in jqGrid and multiselect: true option is also used? If multiselct is present, jqGrid bindKeys function does not have any effect.

To verify this testcase below can be used (based on sample provided in Oleg comment).

Steps to reproduce:

  1. Save code below to html file and open it in IE 9
  2. Click in grid and press enter

Observed:

  1. Message box does not appear
  2. Also up and down arrow move whole grid

Expected:

  1. Enter press should cause message box to appear
  2. up and down arrow should change current row in grid

How to get expected behaviour ?

<!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>

UPDATE: added multiboxonly: true to testcase do demontrate previous row not unselected issue

Update

Added multikey: "ctrlKey" to testcase. In this case bindKeys proposed in Oleg answer stops working

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The code which you posted should work. Probably you use it on the wrong place.

The only thing which you should take in the consideration that after the end of the row editing the focus is lost and you can't use arrows to move th the next row. You should use aftersavefunc parameter of the editRow method to restore the grid focus:

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

The demo is the small modification of the demo from the answer. You can use keyboard to move the row selection and enter to start inline editing and to save the row.

UPDATED: I ask you always to append your original question with additional information instead of full rewriting of the question. Your original question don't contained anything about the usage of multiselect: true. This case (multiselect: false) and my first demo could be interesting for other users. So the general practice is to append the original question with "UPDATED:" part or just ask a new question. Currently if somebody will read your question and my answer he/she will wonder: "what a queer answer? Probably the answer not carefully read the question.".

Now about your current problem in case of multiselect: true. How you know jqGrid 4.0.0 is the first version which has support of keyboard navigation in the grid and treegrid and which has bindKeys method. The solution is far from be perfect. Many actions can't be done with the keyboard. For example the buttons in the navigation toolbar ("Add", "Edit", "Delete" etc) could be not clicked with respect of keyboard. To use keyboard navigation in the jqGrid many places of jqGrid code are extended with the setting of tabindex attribute. For example in the line the selected row (<tr> element) receive the attribute tabindex="0", but the line works only in case of multiselect: false. In the line of bindKeys code will be search (and not found) the attribute tabindex="0". So the current implementation of bindKeys don't work in the multiselect: true mode.

As I wrote before the full support of multiselect: true mode can be implemented only with many changes in the jqGrid code. As a workaround I could suggest the following: we can overwrite the code of bindKeys method only with the changed implementation.

The corresponding demo you can find here. The JavaScript code form the demo is:

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

and

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

I repeat one more time that I find the code which I posted not perfect. One should make visible which line have focus and make much more things. I wanted only to show which kind of changes and where should be done to allow keyboard navigation for the musliselect grids.

Edit

If multikey:"ctrlKey" is added bindKeys. Code in answer does not work. Also using setFocus in answer code causes focus to jump to another row after editing, so this should removed. There is no way to set focus after editing to current row, mouse clik is always required, jqGrid does not support inline edit using keyboard only.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...