且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何将标准文本框命令添加到jqgrid上下文菜单

更新时间:2023-12-06 08:34:22

要在上下文菜单中执行诸如复制",粘贴"等命令并不容易,因此我决定从新演示中,仅当页面不包含任何内容时,才会显示上下文菜单选定的文本.

第一个问题是jquery.contextmenu.js的原始代码包含以下代码片段:

$(this).bind('contextmenu', function(e) {
  // Check if onContextMenu() defined
  var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
  if (bShowContext) display(index, this, e, options);
  return false;
});

因此,contextmenu处理程序始终返回false并阻止创建标准上下文菜单.我将代码修复为以下内容(您可以下载完整的修改后的代码此处我修改了

onContextMenu: function (e) {
    var rowId = $(e.target).closest("tr.jqgrow").attr("id"), p = grid[0].p, i,
        lastSelId;

    if (rowId && getSelectedText() === '') {
        ...
        return true;
    } else {
        return false; // no contex menu
    }
}

仅在未选择任何文本的情况下使用getSelectedText()并创建上下文菜单.结果,只有在未选择任何文本的情况下,您才会看到自定义上下文菜单;如果存在文本选择,则将看到标准的上下文菜单(取决于Web浏览器):

已更新:我使用此处所有修复程序已经在 github 上的jqGrid的主要代码中,并已包含在jqGrid 4.3中

更新3 :如果要为所有启用的标准上下文菜单 <input type="text" ...><input type="textarea" ...><textarea ...>元素,则只需修改一下onContextMenu回调内部的代码.例如

onContextMenu: function (e) {
    var p = grid[0].p, i, lastSelId,
        $target = $(e.target),
        rowId = $target.closest("tr.jqgrow").attr("id"),
        isInput = $target.is(':text:enabled') ||
        $target.is('input[type=textarea]:enabled') ||
        $target.is('textarea:enabled');
    if (rowId && !isInput && getSelectedText() === '') {
        ...

另请参阅演示,其中通过双击.

If context menu is added to jqGrid using Custom values to Context Menu Items in JQgrid and text filed inline editing is used, textbox standard context menu is not available, it is replace with jqGrid context menu.

How to add standard textbox context menu commands ( Undo, Cut, Copy, Paste, Delete, Select all ) to jqGrid conext menu or how to show standard context menu for textbox inline editing?

Update

On inline edit, if standard menu is opened by right clicking on yellow background or in autocomplete box and after that standard browser context menu is opened, custom menu is not closed, two menus appear.

How to fix this ?

It's not easy to implement in context menu commands like "Copy", "Paste", ... so I decide to modify my demo from the answer on your previous question. In the new demo the context menu appears only if the page contains no selected text.

The first problem is that the original code of the jquery.contextmenu.js contains the following code fragment:

$(this).bind('contextmenu', function(e) {
  // Check if onContextMenu() defined
  var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
  if (bShowContext) display(index, this, e, options);
  return false;
});

So the contextmenu handler return always false and prevent creating of the standard context menu. I fix the code to the following (you can download full modified code here):

$(this).bind('contextmenu', function(e) {
  // Check if onContextMenu() defined
  var bShowContext = (!!hash[index].onContextMenu) ? hash[index].onContextMenu(e) : true;
  currentTarget = e.target;
  if (bShowContext) {
    display(index, this, e, options);
    return false;
  }
});

The code of createContexMenuFromNavigatorButtons functions described here I modified

onContextMenu: function (e) {
    var rowId = $(e.target).closest("tr.jqgrow").attr("id"), p = grid[0].p, i,
        lastSelId;

    if (rowId && getSelectedText() === '') {
        ...
        return true;
    } else {
        return false; // no contex menu
    }
}

to use getSelectedText() and to create the context menu only if no text is selected. As the result you will be see your custom context menu only if no text is selected and see the standard context menu (which depend on web browser) if the text selection exist:

UPDATED: I modified my bug report about jquery.contextmenu.js with additional information based on the answer. I hope that the changes will be soon in the main code of jquery.contextmenu.js included in the plugins subdirectory.

UPDATED 2: How you can see here all the fixes are already in the main code of jqGrid on the github and in included in the jqGrid 4.3.

UPDATED 3: If you want to have the standard context menu for all enabled <input type="text" ...>, <input type="textarea" ...> and <textarea ...> elements you should just modify a little the code inside of onContextMenu callback. For example

onContextMenu: function (e) {
    var p = grid[0].p, i, lastSelId,
        $target = $(e.target),
        rowId = $target.closest("tr.jqgrow").attr("id"),
        isInput = $target.is(':text:enabled') ||
        $target.is('input[type=textarea]:enabled') ||
        $target.is('textarea:enabled');
    if (rowId && !isInput && getSelectedText() === '') {
        ...

see one more demo where inline editing will be activate by double-click.