Andrus
Andrus

Reputation: 27931

How to add toggle button from jqgrid toolbar to autogenerated context menu

Toggle button in jqgrid top toolbar is defined using Oleg answer as

var autoedit;
$("#grid_toppager_left table.navtable tbody tr").append(
    '<td class="ui-pg-button ui-corner-all" >' +
        '<div class="ui-pg-div my-nav-checkbox">' +
        '<input tabindex="-1" type="checkbox" id="AutoEdit" '+(autoedit ? 'checked ' : '')+'/>' +
        '<label title="Toggle autoedit" for="AutoEdit">this text is ignored in toolbar</label></div></td>'
);
$("#AutoEdit").button({
    text: false,
    icons: {primary: "ui-icon-star"}
}).click(function () {
    autoedit = $(this).is(':checked');
});

Answer from how to add standard textbox command to jqgrid context menu is used to autogenerate context menu for grid from toolbar.

In generated context menu for this item only text "this text is ignored in toolbar" appears and selecting it does nothing.

How to make it work or remove this item from context menu?

Upvotes: 2

Views: 5411

Answers (1)

Oleg
Oleg

Reputation: 221997

Look at the demo or the same demo with another themes: this and this.

enter image description here

enter image description here

enter image description here

First of all I modified the code of the jquery.contextmenu.js to support jQuery UI Themes. Then I modified the code more, to be able to create context menu more dynamically. In the modified version of jquery.contextmenu.js one can crate menu and the bindings not only in the onContextMenu, but also in onShowMenu. Inside of onContextMenu one can create just the empty menu

<div id="myMenu"><ul></ul></div>

It is important only if one use dynamically switching of the icons of the text of buttons from the navigator bar.

You can download the modified version of the file here.

In the demo I used the last modification of the code from the answer, so the standard context menu can be still used in the grid on selected text or in the enabled input/textarea fields. The context menu of the browser will be displayed in the case:

enter image description here

I modified the code of createContexMenuFromNavigatorButtons function from the answer to the following:

var getSelectedText = function () {
        var text = '';
        if (window.getSelection) {
            text = window.getSelection();
        } else if (document.getSelection) {
            text = document.getSelection();
        } else if (document.selection) {
            text = document.selection.createRange().text;
        }
        return typeof (text) === 'string' ? text : text.toString();
    },
    createContexMenuFromNavigatorButtons = function (grid, pager) {
        var menuId = 'menu_' + grid[0].id, menuUl = $('<ul>'),
            menuDiv = $('<div>').attr('id', menuId);

        menuUl.appendTo(menuDiv);
        menuDiv.appendTo('body');

        grid.contextMenu(menuId, {
            bindings: {}, // the bindings will be created in the onShowMenu
            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() === '') {
                    i = $.inArray(rowId, p.selarrrow);
                    if (p.selrow !== rowId && i < 0) {
                        // prevent the row from be unselected
                        // the implementation is for "multiselect:false" which we use,
                        // but one can easy modify the code for "multiselect:true"
                        grid.jqGrid('setSelection', rowId);
                    } else if (p.multiselect) {
                        // Edit will edit FIRST selected row.
                        // rowId is allready selected, but can be not the last selected.
                        // Se we swap rowId with the first element of the array p.selarrrow
                        lastSelId = p.selarrrow[p.selarrrow.length - 1];
                        if (i !== p.selarrrow.length - 1) {
                            p.selarrrow[p.selarrrow.length - 1] = rowId;
                            p.selarrrow[i] = lastSelId;
                            p.selrow = rowId;
                        }
                    }
                    return true;
                } else {
                    return false; // no contex menu
                }
            },
            onShowMenu: function (e, $menu) {
                var options = this, $menuUl = $menu.find('ul:first').empty();

                $('table.navtable .ui-pg-button', pager).each(function () {
                    var $spanIcon, text, $td, id, $li, $a, button,
                        $div = $(this).children('div.ui-pg-div:first'),
                        gridId = grid[0].id;

                    if ($div.length === 1) {
                        text = $div.text();
                        $td = $div.parent();
                        if (text === '') {
                            text = $td.attr('title');
                        }
                        if (this.id !== '' && text !== '') {
                            id = 'menuitem_' + this.id;
                            if (id.length > gridId.length + 2) {
                                id = id.substr(0, id.length - gridId.length - 1);
                            }
                        } else {
                            // for custom buttons
                            id = $.jgrid.randId();
                        }
                        $li = $('<li>').attr('id', id);
                        $spanIcon = $div.children('span.ui-icon');
                        if ($spanIcon.length > 0) {
                            // standard navGrid button or button added by navButtonAdd
                            $li.append($('<a>')
                                .text(text)
                                .prepend($spanIcon.clone().css({
                                    float: 'left',
                                    marginRight: '0.5em'
                                })));
                            $menuUl.append($li);
                            options.bindings[id] = (function ($button) {
                                return function () { $button.click(); };
                            }($div));
                        } else {
                            button = $div.children("input").data("button");
                            if (button !== undefined) {
                                $a = $('<a>')
                                    .text(button.options.label)
                                    .prepend(
                                        $('<label>').addClass("ui-corner-all").css({
                                            float: 'left',
                                            width: '16px',
                                            borderWidth: '0px',
                                            marginRight: '0.5em'//'4px'
                                        }).append(
                                            $('<span>').addClass("ui-button-icon-primary ui-icon " +
                                                button.options.icons.primary)
                                                .css({
                                                    float: 'left',
                                                    marginRight: '0.5em'
                                                })
                                        )
                                    );
                                $li.append($a);
                                if (button.type === "checkbox" && button.element.is(':checked')) {
                                    $a.find('label:first').addClass("ui-state-active");
                                }
                                $menuUl.append($li);
                                options.bindings[id] = (function ($button, isCheckbox) {
                                    if (isCheckbox) {
                                        return function () {
                                            if ($button.is(':checked')) {
                                                $button.siblings('label').removeClass("ui-state-active");
                                            } else {
                                                $button.siblings('label').addClass("ui-state-active");
                                            }
                                            $button.click();
                                            $button.button("refresh"); // needed for IE7-IE8
                                    };
                                    } else {
                                        return function () { $button.click(); };
                                    }
                                }(button.element, button.type === "checkbox"));
                            }
                        }
                    }
                });
                return $menu;
            }
        });
    },
    autoedit = false;

and fill the check-button in the navigator bar with the code which is changed only a little:

$("#pager_left table.navtable tbody tr").append(
    '<td class="ui-pg-button ui-corner-all">' +
        '<div class="ui-pg-div my-nav-checkbox">' +
        '<input tabindex="-1" type="checkbox" id="AutoEdit" />' +
        '<label title="Checkx caption which should appear as button tooltip"' +
        ' for="AutoEdit">Autoedit</label></div></td>'
);
$("#AutoEdit").button({
    text: false,
    icons: {primary: "ui-icon-mail-closed"}
}).click(function () {
    var iconClass, $this = $(this);
    if (!autoedit) { // $this.is(':checked')) {
        autoedit = true;
        iconClass = "ui-icon-mail-open";
    } else {
        autoedit = false;
        iconClass = "ui-icon-mail-closed";
    }
    $this.button("option", {icons: {primary: iconClass}});
});
createContexMenuFromNavigatorButtons($grid, '#pager');

UPDATED: One more demo which support buttons added by new inlineNav method you can find here. Additionally I included in the demo the function normalizePagers which I use to improve the look of the pager:

enter image description here

How you can see the contextmenu includes only enabled buttons from the navigator bar.

Upvotes: 6

Related Questions