jqGrid将焦点设置为单击的单元格并在IE和Firefox中实现datepicker [英] jqGrid set focus to clicked cell AND implement datepicker in IE and Firefox

查看:74
本文介绍了jqGrid将焦点设置为单击的单元格并在IE和Firefox中实现datepicker的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉(如果已回答).围绕这个问题有很多问题,但我无法完全理解.

我有一个jqGrid.第一个单元格附加有一个日期选择器(在编辑该单元格时会自动运行,而不是在初始网格定义中).

当我双击网格中间的一个单元格时,我希望它进入编辑模式,将焦点设置到该单击的单元格上,而不触发日期选择器(因为我没有双击它)

通过以下代码,我已经在 Firefox 中实现了我想要的功能.这是基于Olegs(和其他人)在该主题上的出色帖子.

但是,在 IE9 中,尽管它可以根据需要设置焦点,但它也会在第一个单元格中触发日期选择器.

我了解默认情况下,jqGrid会自动移动到第一个单元格,因此会触发datepicker(如果存在),无论我是否双击它.也许作为一种解决方法,我将需要在第一个位置创建一个小型的虚拟单元格,但首先,我想借此机会了解更多信息.

这是一些缩写的jqGrid代码,您将认识到Oleg和其他人的帖子中的点点滴滴.抱歉,目前我无法提供jqGrid的确切版本,足以说明我是2012年10月上旬下载的.

我只是说我不完全了解事件发生的顺序-乍看之下似乎已附加了日期选择器(?)之前无论如何.

顺便说一句,它在MVC ASP.Net项目中.我发现在MVC/ASP.Net中获得有用的网格控件的唯一方法是开始学习Javascript,这很有趣且具有讽刺意味.

$(document).ready(
    function () {
        var lastsel;
        $("#ts").jqGrid({
            //=============
            // Grid Setup
            url: 'Timesheet/GridData/',
            datatype: 'json',
            mtype: 'GET',
            colNames: ['Date', 'Customer', 'Project', 'Description', 'Hours', '$'],
            colModel: [
              { name: 'tsdate', index: 'tsdate', width: 80, editable: true },
              { name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/CustomerList'} },
              { name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'} },
              { name: 'Desc', index: 'Desc', width: 300, align: 'left', editable: true },
              { name: 'Hours', index: 'Hours', width: 50, align: 'left', editable: true },
              { name: 'Charge', index: 'Charge', edittype: 'checkbox', width: 18, align: 'center', editoptions: { value: "0:1" }, formatter: "checkbox", formatoptions: { disabled: false }, editable: true }
            ],
            //=============
            // Grid Events
            // when selecting, undo anything else
            onSelectRow: function (rowid, iRow, iCol, e) {
                if (rowid && rowid !== lastsel) {
                    $('#ts').jqGrid('restoreRow', lastsel);
                    lastsel = rowid;
                }
            },
            // double click to edit
            ondblClickRow: function (rowid, iRow, iCol, e) {
                // Go into edit mode (automatically moves focus to first field)
                $('#ts').jqGrid('editRow', rowid, true, onGridEdit);
                // Now set focus on selected field
                if (!e) e = window.event; // get browser independent object
                var element = e.target || e.srcElement
                $("input, select", element).focus();
            },
            postData:
                {
                    startDate: function () { return $('#startDate').val(); }
                }
        }); // END jQuery("#ts").jqGrid

        // This is called when the row is double clicked
        function onGridEdit(RowID) {
            // onGridEdit is attached as the 'edit function' in the call to .jqGrid('editRow' above
            // Attach the datepicker to the tsdate field. For some reason this needs to be in the edit function
            // And does not work in IE 9. In IE9 it fires the datepicker. In Firefox it only fires when the field
            // gets the focus
            $("#" + RowID + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
        }

    });           // END $(document).ready

解决方案,当比较Firefox和IE9之间的调试时,似乎Firefox事件是按顺序运行的,而IE9事件没有按顺序运行.

无论如何,Oleg建议的最终解决方案是将oneditfunc函数包装在setTimeout函数中:

            ondblClickRow: function (rowid, iRow, iCol, e) {
                if (!e) e = window.event; //evt evaluates to window.event or inexplicit e object, depending on which one is defined
                var element = e.target || e.srcElement

                // Go into edit mode (automatically moves focus to first field)
                $(this).jqGrid(
                    'editRow',
                    rowid,
                    {
                        keys: true,
                        oneditfunc: function (rowId) {
                            setTimeout(function () {
                                $("input, select", element).focus();
                                $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
                            }, 50);
                        }
                    }
                ); // end jqGrid call

            },  // end ondblClickRow event handler

我想解决焦点问题可以通过将jQuery.focus的调用移到oneditfunc回调内部来解决.如果您将回调实现为匿名函数(而不是onGridEdit),则实现起来将很容易:

ondblClickRow: function (rowid, iRow, iCol, e) {
    if (!e) e = window.event; // get browser independent object
    var element = e.target || e.srcElement;

    // Go into edit mode (automatically moves focus to first field)
    $(this).jqGrid('editRow', rowid, {
        keys: true,
        oneditfunc: function (rowId) {
            $("input, select", element).focus(); // Now set focus on selected field
            $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
        }
    });
}

如何看到我在回调函数中另外使用了$(this)而不是$('#ts').它使代码易于维护,并且速度很快.您可以在所有jqGrid回调中进行相同的更改(例如,在onSelectRow内部).此外,我更喜欢使用对象样式来调用 editRow .在我看来,这使代码更具可读性,因为人们使用的是命名参数.

Apologies if this has been answered already. There are a number of questions around this but I can't quite get what I'm after.

I have a jqGrid. The first cell has a datepicker attached (on the fly when the cell is edited, not in the initial grid definition).

When I double click on a cell in the middle of the grid, I want it to go into edit mode, sets focus to that clicked cell and not fire the datepicker (as I didn't double click in it)

With the code below I have achieved what I want in Firefox. This is based on Olegs (and others) excellent posts on the topic.

Howevever, in IE9, although it sets focus as required, it also fires the datepicker in the first cell.

I understand that by default the jqGrid automatically moves to the first cell, therefore firing the datepicker if it exists, regardless of whether I double clicked it. Maybe as a workaround I will need to create some kind of tiny dummy cell in the first position, but first I would like to take this opportunity to learn more.

Here is some abbreviated jqGrid code, you will recognise bits and pieces from Oleg and other peoples posts. Sorry I cannot give you the exact version of jqGrid at this point, suffice to say I downloaded it early October 2012.

I'll just say I don't fully understand the event order that is gong on - on first glance it appears that the datepicker is being attached(?) before the clicked field is getting focus anyway.

As an aside this is inside a MVC ASP.Net project. I find it amusing and ironic that the only way I can get a useful grid control in MVC / ASP.Net is to start learning Javascript.

$(document).ready(
    function () {
        var lastsel;
        $("#ts").jqGrid({
            //=============
            // Grid Setup
            url: 'Timesheet/GridData/',
            datatype: 'json',
            mtype: 'GET',
            colNames: ['Date', 'Customer', 'Project', 'Description', 'Hours', '$'],
            colModel: [
              { name: 'tsdate', index: 'tsdate', width: 80, editable: true },
              { name: 'Customer', index: 'Customer', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/CustomerList'} },
              { name: 'Project', index: 'Project', width: 250, align: 'left', editable: true, edittype: "select", editoptions: { dataUrl: 'Timesheet/ProjectList'} },
              { name: 'Desc', index: 'Desc', width: 300, align: 'left', editable: true },
              { name: 'Hours', index: 'Hours', width: 50, align: 'left', editable: true },
              { name: 'Charge', index: 'Charge', edittype: 'checkbox', width: 18, align: 'center', editoptions: { value: "0:1" }, formatter: "checkbox", formatoptions: { disabled: false }, editable: true }
            ],
            //=============
            // Grid Events
            // when selecting, undo anything else
            onSelectRow: function (rowid, iRow, iCol, e) {
                if (rowid && rowid !== lastsel) {
                    $('#ts').jqGrid('restoreRow', lastsel);
                    lastsel = rowid;
                }
            },
            // double click to edit
            ondblClickRow: function (rowid, iRow, iCol, e) {
                // Go into edit mode (automatically moves focus to first field)
                $('#ts').jqGrid('editRow', rowid, true, onGridEdit);
                // Now set focus on selected field
                if (!e) e = window.event; // get browser independent object
                var element = e.target || e.srcElement
                $("input, select", element).focus();
            },
            postData:
                {
                    startDate: function () { return $('#startDate').val(); }
                }
        }); // END jQuery("#ts").jqGrid

        // This is called when the row is double clicked
        function onGridEdit(RowID) {
            // onGridEdit is attached as the 'edit function' in the call to .jqGrid('editRow' above
            // Attach the datepicker to the tsdate field. For some reason this needs to be in the edit function
            // And does not work in IE 9. In IE9 it fires the datepicker. In Firefox it only fires when the field
            // gets the focus
            $("#" + RowID + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
        }

    });           // END $(document).ready

SOLUTION when comparing debugging between Firefox and IE9 it appeared that the firefox events ran sequentially and the the IE9 ones did not.

Regardless, the final solution as suggested by Oleg was to wrap the oneditfunc function in a setTimeout function:

            ondblClickRow: function (rowid, iRow, iCol, e) {
                if (!e) e = window.event; //evt evaluates to window.event or inexplicit e object, depending on which one is defined
                var element = e.target || e.srcElement

                // Go into edit mode (automatically moves focus to first field)
                $(this).jqGrid(
                    'editRow',
                    rowid,
                    {
                        keys: true,
                        oneditfunc: function (rowId) {
                            setTimeout(function () {
                                $("input, select", element).focus();
                                $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
                            }, 50);
                        }
                    }
                ); // end jqGrid call

            },  // end ondblClickRow event handler

解决方案

I suppose that the problem with focus can be solved by moving call of jQuery.focus inside of oneditfunc callback. If you would implement the callback as anonymous function (instead of onGridEdit) the implementation will be the mostly easy:

ondblClickRow: function (rowid, iRow, iCol, e) {
    if (!e) e = window.event; // get browser independent object
    var element = e.target || e.srcElement;

    // Go into edit mode (automatically moves focus to first field)
    $(this).jqGrid('editRow', rowid, {
        keys: true,
        oneditfunc: function (rowId) {
            $("input, select", element).focus(); // Now set focus on selected field
            $("#" + rowId + "_tsdate").datepicker({ dateFormat: 'yy-mm-dd' });
        }
    });
}

How you can see I used additionally $(this) instead of $('#ts') inside of callback functions. It make the code easy to maintain and a little bit quickly. The same changes you can make in all jqGrid callbacks (for example inside of onSelectRow). Moreover I prefer to use object style of calling editRow. It makes the code more readable in my opinion because one uses named parameters.

这篇关于jqGrid将焦点设置为单击的单元格并在IE和Firefox中实现datepicker的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆