jQGrid列选择器模态覆盖层

5

看一下这个示例,注意点击搜索按钮会弹出一个带有暗色遮罩的模态表单。现在请注意,点击列选择器按钮会弹出一个模态表单,但没有遮罩层。

我的问题是:如何让暗色遮罩出现在我的列选择器弹出窗口后面?

3个回答

18

目前有columnChooseroption未经记录:

$(this).jqGrid('columnChooser', {modal: true});

这个演示可以展示这一点。人们可以根据$.jgrid.col设置columnChooser的默认参数:

$.extend(true, $.jgrid.col, {
    modal: true
});

最近我发布了建议,希望扩展columnChooser的一些功能,但目前jqGrid代码中只有一部分。尽管如此,在新版本中将可以使用新的dialog_opts选项设置更多jQuery UI Dialog选项。例如,以下用法将成为可能。

$(this).jqGrid('columnChooser', {
    dialog_opts: {
        modal: true,
        minWidth: 470,
        show: 'blind',
        hide: 'explode'
    }
});

如果您想使用我建议的全部功能,您只需要覆盖标准的columnChooser实现即可。可以通过包含以下代码来实现:

$.jgrid.extend({
    columnChooser : function(opts) {
        var self = this;
        if($("#colchooser_"+$.jgrid.jqID(self[0].p.id)).length ) { return; }
        var selector = $('<div id="colchooser_'+self[0].p.id+'" style="position:relative;overflow:hidden"><div><select multiple="multiple"></select></div></div>');
        var select = $('select', selector);

        function insert(perm,i,v) {
            if(i>=0){
                var a = perm.slice();
                var b = a.splice(i,Math.max(perm.length-i,i));
                if(i>perm.length) { i = perm.length; }
                a[i] = v;
                return a.concat(b);
            }
        }
        opts = $.extend({
            "width" : 420,
            "height" : 240,
            "classname" : null,
            "done" : function(perm) { if (perm) { self.jqGrid("remapColumns", perm, true); } },
            /* msel is either the name of a ui widget class that
               extends a multiselect, or a function that supports
               creating a multiselect object (with no argument,
               or when passed an object), and destroying it (when
               passed the string "destroy"). */
            "msel" : "multiselect",
            /* "msel_opts" : {}, */

            /* dlog is either the name of a ui widget class that 
               behaves in a dialog-like way, or a function, that
               supports creating a dialog (when passed dlog_opts)
               or destroying a dialog (when passed the string
               "destroy")
               */
            "dlog" : "dialog",

            /* dlog_opts is either an option object to be passed 
               to "dlog", or (more likely) a function that creates
               the options object.
               The default produces a suitable options object for
               ui.dialog */
            "dlog_opts" : function(opts) {
                var buttons = {};
                buttons[opts.bSubmit] = function() {
                    opts.apply_perm();
                    opts.cleanup(false);
                };
                buttons[opts.bCancel] = function() {
                    opts.cleanup(true);
                };
                return $.extend(true, {
                    "buttons": buttons,
                    "close": function() {
                        opts.cleanup(true);
                    },
                    "modal" : opts.modal ? opts.modal : false,
                    "resizable": opts.resizable ? opts.resizable : true,
                    "width": opts.width+20,
                    resize: function (e, ui) {
                        var $container = $(this).find('>div>div.ui-multiselect'),
                            containerWidth = $container.width(),
                            containerHeight = $container.height(),
                            $selectedContainer = $container.find('>div.selected'),
                            $availableContainer = $container.find('>div.available'),
                            $selectedActions = $selectedContainer.find('>div.actions'),
                            $availableActions = $availableContainer.find('>div.actions'),
                            $selectedList = $selectedContainer.find('>ul.connected-list'),
                            $availableList = $availableContainer.find('>ul.connected-list'),
                            dividerLocation = opts.msel_opts.dividerLocation || $.ui.multiselect.defaults.dividerLocation;

                        $container.width(containerWidth); // to fix width like 398.96px                     
                        $availableContainer.width(Math.floor(containerWidth*(1-dividerLocation)));
                        $selectedContainer.width(containerWidth - $availableContainer.outerWidth() - ($.browser.webkit ? 1: 0));

                        $availableContainer.height(containerHeight);
                        $selectedContainer.height(containerHeight);
                        $selectedList.height(Math.max(containerHeight-$selectedActions.outerHeight()-1,1));
                        $availableList.height(Math.max(containerHeight-$availableActions.outerHeight()-1,1));
                    }
                }, opts.dialog_opts || {});
            },
            /* Function to get the permutation array, and pass it to the
               "done" function */
            "apply_perm" : function() {
                $('option',select).each(function(i) {
                    if (this.selected) {
                        self.jqGrid("showCol", colModel[this.value].name);
                    } else {
                        self.jqGrid("hideCol", colModel[this.value].name);
                    }
                });

                var perm = [];
                //fixedCols.slice(0);
                $('option:selected',select).each(function() { perm.push(parseInt(this.value,10)); });
                $.each(perm, function() { delete colMap[colModel[parseInt(this,10)].name]; });
                $.each(colMap, function() {
                    var ti = parseInt(this,10);
                    perm = insert(perm,ti,ti);
                });
                if (opts.done) {
                    opts.done.call(self, perm);
                }
            },
            /* Function to cleanup the dialog, and select. Also calls the
               done function with no permutation (to indicate that the
               columnChooser was aborted */
            "cleanup" : function(calldone) {
                call(opts.dlog, selector, 'destroy');
                call(opts.msel, select, 'destroy');
                selector.remove();
                if (calldone && opts.done) {
                    opts.done.call(self);
                }
            },
            "msel_opts" : {}
        }, $.jgrid.col, opts || {});
        if($.ui) {
            if ($.ui.multiselect ) {
                if(opts.msel == "multiselect") {
                    if(!$.jgrid._multiselect) {
                        // should be in language file
                        alert("Multiselect plugin loaded after jqGrid. Please load the plugin before the jqGrid!");
                        return;
                    }
                    opts.msel_opts = $.extend($.ui.multiselect.defaults,opts.msel_opts);
                }
            }
        }
        if (opts.caption) {
            selector.attr("title", opts.caption);
        }
        if (opts.classname) {
            selector.addClass(opts.classname);
            select.addClass(opts.classname);
        }
        if (opts.width) {
            $(">div",selector).css({"width": opts.width,"margin":"0 auto"});
            select.css("width", opts.width);
        }
        if (opts.height) {
            $(">div",selector).css("height", opts.height);
            select.css("height", opts.height - 10);
        }
        var colModel = self.jqGrid("getGridParam", "colModel");
        var colNames = self.jqGrid("getGridParam", "colNames");
        var colMap = {}, fixedCols = [];

        select.empty();
        $.each(colModel, function(i) {
            colMap[this.name] = i;
            if (this.hidedlg) {
                if (!this.hidden) {
                    fixedCols.push(i);
                }
                return;
            }

            select.append("<option value='"+i+"' "+
                          (this.hidden?"":"selected='selected'")+">"+colNames[i]+"</option>");
        });
        function call(fn, obj) {
            if (!fn) { return; }
            if (typeof fn == 'string') {
                if ($.fn[fn]) {
                    $.fn[fn].apply(obj, $.makeArray(arguments).slice(2));
                }
            } else if ($.isFunction(fn)) {
                fn.apply(obj, $.makeArray(arguments).slice(2));
            }
        }

        var dopts = $.isFunction(opts.dlog_opts) ? opts.dlog_opts.call(self, opts) : opts.dlog_opts;
        call(opts.dlog, selector, dopts);
        var mopts = $.isFunction(opts.msel_opts) ? opts.msel_opts.call(self, opts) : opts.msel_opts;
        call(opts.msel, select, mopts);
        // fix height of elements of the multiselect widget
        var resizeSel = "#colchooser_"+$.jgrid.jqID(self[0].p.id),
            $container = $(resizeSel + '>div>div.ui-multiselect'),
            $selectedContainer = $(resizeSel + '>div>div.ui-multiselect>div.selected'),
            $availableContainer = $(resizeSel + '>div>div.ui-multiselect>div.available'),
            containerHeight,
            $selectedActions = $selectedContainer.find('>div.actions'),
            $availableActions = $availableContainer.find('>div.actions'),
            $selectedList = $selectedContainer.find('>ul.connected-list'),
            $availableList = $availableContainer.find('>ul.connected-list');
        $container.height($container.parent().height()); // increase the container height
        containerHeight = $container.height();
        $selectedContainer.height(containerHeight);
        $availableContainer.height(containerHeight);
        $selectedList.height(Math.max(containerHeight-$selectedActions.outerHeight()-1,1));
        $availableList.height(Math.max(containerHeight-$availableActions.outerHeight()-1,1));
        // extend the list of components which will be also-resized
        selector.data('dialog').uiDialog.resizable("option", "alsoResize",
            resizeSel + ',' + resizeSel +'>div' + ',' + resizeSel + '>div>div.ui-multiselect');
    }
});

如果您继续使用原始的最小化版本jquery.jqGrid.min.js,那么使用的代码只需是$(this).jqGrid('columnChooser');。与所有默认设置一起,它将是这样的:

$.extend(true, $.ui.multiselect, {
    locale: {
        addAll: 'Make all visible',
        removeAll: 'Hidde All',
        itemsCount: 'Avlialble Columns'
    }
});
$.extend(true, $.jgrid.col, {
    width: 450,
    modal: true,
    msel_opts: {dividerLocation: 0.5},
    dialog_opts: {
        minWidth: 470,
        show: 'blind',
        hide: 'explode'
    }
});
$grid.jqGrid('navButtonAdd', '#pager', {
    caption: "",
    buttonicon: "ui-icon-calculator",
    title: "Choose columns",
    onClickButton: function () {
        $(this).jqGrid('columnChooser');
    }
});

演示展示了这种方法。变化的主要优点是真正可调整大小的列选择器:

enter image description here

更新:Free jqGrid是我从2014年末开始开发的jqGrid分支,其中当然包含了修改过的columnChooser代码。


@Oleg是静态对象(我认为它是静态的)。$.jgrid.col在哪里有文档记录?我想为colchooser添加翻译,因此有这个问题。 - Harshit

2
在移动设备上尝试运行代码时,我遇到了以下错误。
Result of expression 'selector.data('dialog').uiDialog' [undefined] is not an object.

错误指向以下代码行。
selector.data('dialog').uiDialog.resizable("option", "alsoResize", resizeSel + ',' + resizeSel +'>div' + ',' + resizeSel + '>div>div.ui-multiselect');

当我检查代码时,我发现数据对象中没有任何称为uiDialog的东西。

我也遇到了同样的问题,还有其他一些问题。最初发现是脚本顺序问题(即我在单独的文件中添加了columnChooser - 必须在jqgrid脚本包含之后)。然后卡在了这个错误上 - 无法修复它,但在注释掉那些行之后,一切似乎都正常工作了!奇怪。 - Hemant Tank

1

我刚刚查看了代码,尝试添加这行:

jqModal : true,

转换为这段代码:

$grid.jqGrid('navButtonAdd', '#pager', {
            caption: "",
            buttonicon: "ui-icon-calculator",
            title: "Choose columns",
            onClickButton: function () {
....

就像这样:

$grid.jqGrid('navButtonAdd', '#pager', {
            caption: "",
            buttonicon: "ui-icon-calculator",
            title: "Choose columns",
            jqModal : true,
            onClickButton: function () {
....

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接