jqGrid, встроенный в пользовательский элемент управления

У меня есть простой пользовательский элемент управления, который использует jqGrid. управление такое же, как в следующем коде:

Разметка:

<div id="grid_container" runat="server">
    <table id="umlt_grid" runat="server"></table>
    <div id="umlt_grid_pager" runat="server"></div>
</div>
<div id="umlt_dialog" title="Umlt" style="display: none;" runat="server"></div>

Скрипт (внутри файла ascx)

<script type="text/javascript" language="javascript">
    $(document).ready(function () {
        //Initialize controls
        var dialogID = $('#<%=umlt_dialog.ClientID %>');
        var dlg = $(dialogID);
        dlg.dialog({ autoOpen: false, modal: true, stack: true, resizable: false, position: 'center', width: 380, height: 260 });
        //Load the Grid
        var gridID = '#<%=umlt_grid.ClientID %>';
        var pagerID = '#<%=umlt_grid_pager.ClientID %>';
        var containerID = '#<%=grid_container.ClientID %>'
        var gridWidth = GetAvailableSpaceBody( $(containerID).width() );
        loadUmltGrid(gridID, pagerID, dlg, gridWidth);
    });
</script>

Функция loadUmltGrid определена в специальном файле js, который загружается через главную страницу. Вот:

function loadUmltGrid(gridID, pagerID, dialog, gridWidth) {
    var grid = $(gridID);
    var pager = $(pagerID);
    grid.jqGrid({
        url: GetBaseWSUrl() + 'UmltService.asmx/ListUmlts',
        colNames: ['Code', 'Description', 'Note'],
        colModel: [
                    { name: 'Code', index: 'Code', width: 120, template: colTextTemplate },
                    { name: 'Description', index: 'Description', width: 220, template: colTextTemplate },
                    { name: 'Notes', index: 'Notes', width: 300, template: colTextTemplate }
                ],
        jsonReader: {
            id: "UmltID"
        },
        pager: pager,
        sortname: 'Code',
        sortorder: "asc",
        height: '300',
        gridview: true,
        width: gridWidth,
        autowidth: false,
        shrinkToFit: true
    }).jqGrid('navGrid', pagerID,
        { add: true, addtitle: 'Add UMLT',
            edit: true, edittitle: 'Edit UMLT',
            del: true, deltitle: 'Delete UMLT',
            refresh: true, refreshtitle: 'Refresh data',
            search: true, searchtitle: 'Advanced search filters',
            addfunc: function () {
                loadUmltDialog(GetBaseWSUrl() + 'UmltService.asmx/NewUmlt', "", dialog);
            },
            editfunc: function () {
                var rowId = grid.jqGrid('getGridParam', 'selrow');
                loadUmltDialog(GetBaseWSUrl() + 'UmltService.asmx/EditUmlt', rowId, dialog);
            }
        },
        { /*default settings for edit*/ },
        { /*default settings for add*/ },
        { mtype: "post", reloadAfterSubmit: false,
            url: GetBaseWSUrl() + 'UmltService.asmx/DeleteUmlt',
            resize: false, serializeDelData: function (postdata) { return JSON.stringify({ umltID: postdata.id }); },
            afterSubmit: function (data, postdata) {
                var result = $.parseJSON(data.responseText);
                if (result.d.StatusResult === "OK") {
                    showInfoMessage(result.d.StatusResult, result.d.StatusDescription);
                } else {
                    showErrorMessage("Error", result.d.StatusDescription);
                }
                return [true, ''];
            }
        },
        { closeOnEscape: true, multipleSearch: true, closeAfterSearch: true }, {}
    ).jqGrid('navSeparatorAdd', pagerID, {}).jqGrid('navButtonAdd', pagerID, {
        caption: "", buttonicon: "ui-icon-extlink", position: "last", title: "Export to Excel",
        onClickButton: function () {
            window.open(GetCurrentSiteUrl() + '/_layouts/ExportExcel.aspx?View=UMLT');
        }
    });
}

Мне нужно использовать этот пользовательский элемент управления внутри веб-части (SharePoint) и внутри другого элемента управления, поэтому я просто добавил в свой проект веб-часть-оболочку и включил элемент управления внутри другой.

Кажется, все работает для веб-части, как видно из следующего снимка экрана Пользовательский элемент управления, завернутый в веб-часть

но когда я использую его внутри другого пользовательского элемента управления, у меня возникают две странные проблемы:

  1. Пользовательская кнопка «Экспорт», добавленная на панель инструментов, дублируется.
  2. пейджер (страница n из m) показан выровненным по левому краю

Вы можете увидеть это поведение на следующем снимке экрана Пользовательский элемент управления внутри другого пользовательского элемента управления

Любое предложение?


person Lorenzo    schedule 08.08.2011    source источник


Ответы (1)


Вы не включили код основной функции loadUmltGrid, которая определяет вашу сетку. Поэтому я пытаюсь просто предположить.

Обычно настраиваемые кнопки на панели инструментов навигатора создаются с учетом navButtonAdd. метод jqGrid. Стандартные кнопки появляются при вызове navGrid. Проблема с несколькими пользовательскими кнопками обычно возникает, если код, добавляющий кнопки, будет выполняться несколько раз. Вы можете просто вставить alert перед вызовом navButtonAdd, и я полагаю что вы увидите сообщение оповещения дважды. navGrid имеет внутренний контроль. Если метод будет вызван во второй раз для того же пейджера, он немедленно вернется. Чтобы не было дубликатов стандартных кнопок, соответствующий код запускается несколько раз.

Вторая проблема с положением пейджера обычно возникает, если вы используете небольшое значение параметра width jqGrid в начале, а затем увеличиваете ширину сетки относительно setGridWidth. Я рекомендую вам перед написанием любого кода, изменяющего положение средней части пейджера, увеличить начальное значение ширины сетки, которое вы используете при инициализации сетки.

person Oleg    schedule 08.08.2011
comment
Здравствуйте Олег, спасибо за ответ. Я отредактировал свой вопрос, включив в него основную функцию, создающую сетку. Что касается второй проблемы, вы правы: я меняю ширину сетки во время выполнения, потому что сетка включена в скрытый элемент управления, и поэтому в первый раз он имеет нулевую ширину. Знаете ли вы какой-либо другой способ добиться того же результата? - person Lorenzo; 08.08.2011
comment
@Lorenzo: Что ты имеешь в виду под первым? Когда второй раз? Если у вас есть скрытый контроль в начале, почему вам нужно вызвать loadUmltGrid? Только если какой-то родитель <div>, такой как div#grid_container, вы делаете видимым, вы должны вызвать функцию loadUmltGrid. Кстати, loadUmltGrid следует вызывать только один раз. Позже, после того, как сетка уже существует, вы должны вместо этого вызвать $('#umlt_grid').trigger('reloadGrid');. Если вы этого не сделаете, у вас будет, например, еще одна кнопка экспорта. - person Oleg; 08.08.2011
comment
Я просто вызываю один раз loadUmltGrid или, лучше сказать, я вообще его не вызываю, а вызывается при отображении пользовательского элемента управления. пользовательский элемент управления находится внутри скрытой панели, поэтому document.ready() вызывается автоматически при первом отображении элемента управления. Чтобы настроить это, я успешно вызываю setGridWidth, когда элемент управления становится видимым. - person Lorenzo; 08.08.2011
comment
@Lorenzo: Вы пытались вставить alert внутрь функции loadUmltGrid, как я предложил? Сколько раз вызывался метод: один раз или два? Если вы позвоните куда-нибудь setGridWidth, вы можете позвонить на место loadUmltGrid. Внутри document.ready() вы не должны вызывать loadUmltGrid в вашем случае. Поэтому я предлагаю не вызывать loadUmltGrid, пока сетка не станет видимой. - person Oleg; 08.08.2011
comment
Я последовал твоему предложению. Это не подходит для меня, потому что не позволяет мне иметь автономный пользовательский контроль. В любом случае теперь это работает. Спасибо за помощь.. - person Lorenzo; 09.08.2011
comment
@Lorenzo: Добро пожаловать! Я рад прочитать, что ваша проблема (по крайней мере, эта) решена и что я могу помочь вам здесь. - person Oleg; 09.08.2011