jqgrid + MVC: как открыть диалог внутри jqgrid?Какими методами вы предлагаете открыть диалог? - PullRequest
3 голосов
/ 25 февраля 2012

Я использую MVC 4 + EF 4.1 с jqgrid. Я новичок в HTML и Javascript, и я безуспешно пытаюсь открыть пользовательский диалог редактирования jquery внутри jqgrid. Если у вас есть лучшие методы для реализации моего желаемого поведения, они будут приветствоваться.

У меня есть следующий скрипт диалога jquery, прикрепленный к классу = 'openDialog', который уже отлично работает для других целей :

  $.ajaxSetup({ cache: false });

$(document).ready(function () {
    $(".openDialog").live("click", function (e) {
        e.preventDefault();

        $("<div></div>")
            .addClass("dialog")
            .attr("id", $(this).attr("data-dialog-id"))
            .appendTo("body")
            .dialog({
                height: $(this).attr("data-dialog-alt"),
                width: $(this).attr("data-dialog-larg"),
                autoResize: $(this).attr("data-dialog-autosize"),
                position: 'top',
                title: $(this).attr("data-dialog-title"),
                close: function () { $(this).remove() },
                modal: true,
                buttons: { "Ok": function () { $(this).dialog("close"); } }
            })
            .load(this.href);
    });

    $(".close").live("click", function (e) {
        e.preventDefault();
        $(this).closest(".dialog").dialog("close");
    });
});

Это то, что я пытаюсь сделать. Это всего лишь тест с событием двойного щелчка, если он сработает, я помещу код в определенную кнопку.

jqgrid

    ..........
    { name: 'act', index: 'act', width: 75, sortable: false, search: false }
        ],
        ondblClickRow: function (id) {
            if (id != null) {
               // here I would like to launch the open dialog with a similar code: 
               // "<a class='openDialog' data-dialog-id='myEditDlg' data-dialog-autosize='false' data-dialog-alt='580' data-dialog-larg='740' data-dialog-title='test dialog' href='/mycontroller/EditDlg/myid'>test</a>"
            }
        },
        pager: '#jqpager',
       ....

БОЛЬШЕ ДЕТАЛЕЙ

По сути, теперь я использую пользовательский форматер, где я ставлю привязку в виде кнопки для каждой нужной мне кнопки / действия ; например:

         .....
         gridComplete: function () {
            applyZebra("mygrid");
            var ids = grid.jqGrid('getDataIDs');
            var rows = grid.jqGrid('getRowData');
            for (var i = 0; i < ids.length; i++) {

                var row = rows[i];
                var t = row['myrow'];
                var cl = ids[i];

                tst = '<a class="mybuttonclass openDialog" data-dialog-id="tckDetDlg" data-dialog-autosize="false" data-dialog-alt="580" data-dialog-larg="740" data-dialog-title="test dialog" href="/mycontrolller/testDlg/' + t + '"></a>';

                $("#jqTicketgrid").jqGrid('setRowData', ids[i], { act: tst });
            }
        },
        .....

Где mybuttonclass стилизует якоря как кнопки ...

Большое спасибо за вашу помощь! С наилучшими пожеланиями

1 Ответ

2 голосов
/ 25 февраля 2012

Я не уверен, что правильно понимаю ваши требования.Я бы порекомендовал вам использовать jQuery.jqGrid.dynamicLink.js, который я описал в ответе и который вы можете загрузить с здесь или последнюю версию с здесь (и загрузить здесь ).Использование formatter: 'dynamicLink' очень просто, и вы можете реализовать практически каждую ссылку внутри jqGrid.Вы можете использовать onClick callback, который создаст нужный вам диалог.

Еще одно замечание к вашему коду.При каждом нажатии вы создаете <div>, который представляет диалоговое окно, и помещаете его в <body> страницы.Событие close только скрывает div, но не удаляет его из тела.Итак, первая проблема: ваша страница будет длиннее и длиннее при каждом клике.Вторая проблема - это возможность получить дубликаты идентификаторов, которые не разрешены в HTML, и если вы добавляете разные элементы с одинаковым идентификатором, вы можете получить много очень странных эффектов.Поэтому вы должны быть очень осторожны при использовании атрибута data-dialog-id из вашего текущего кода.

ОБНОВЛЕНО : Я хотел бы прокомментировать код из gridComplete, который вы опубликовали.Это не эффективно, и вы можете использовать собственный форматер, чтобы получить более понятный и эффективный код.Вы не опубликовали полный код jqGrid, который вы используете, но я полагаю, что у вас есть по крайней мере два столбца в colModel: 'act' и 'myrow'.Вы не можете поместить в столбец 'act' элементы <a>, имеющие href, которые построены на основе значения из столбца 'myrow'.

Что делает текущий код.1) Сетка будет построена и размещена на странице с пустым 'act' столбцом.Затем внутри gridComplete вы делаете следующее: a) вызываете getDataIDs, который проходит через полную сетку и собирает идентификаторы из каждой строки в массиве ids.б) вызвать getRowData, который проходит через полную сетку и собрать все данные из всех столбцов в объектах и ​​поместить объекты в массив rows.c) получить содержимое столбца myrow, построить <a> и поместить его в 'act' column * в каждом ряду сетки.Кроме того, следует понимать, что изменение одного элемента на странице следует за веб-браузером, для которого необходимо пересчитать положение каждого элемента на странице.

Поэтому для повышения производительности страницы вам следуетПрежде всего уменьшите модификации элементов на странице.Наиболее эффективный способ переписать код и получить те же результаты - использовать custom formatter .В вашем случае вы можете просто включить в 'act' из colModel дополнительное свойство:

{ name: 'act', index: 'act', width: 75, sortable: false, search: false,
    formatter: function (cellvalue, options, rowObject) {
        return '<a class="mybuttonclass openDialog" data-dialog-id="tckDetDlg" data-dialog-autosize="false" data-dialog-alt="580" data-dialog-larg="740" data-dialog-title="test dialog" href="/mycontrolller/testDlg/' +
            rowObject.myrow + '"></a>';
    }}

Вы должны дополнительно убедиться, что вы используете опцию gridview: true jqGrid.Модифицированный код сделает следующее.Во время построения HTML-фрагмента тела сетки полный HTML-фрагмент будет построен в виде одной строки, и будет помещен на HTML-страницу за одну операцию .В данный момент веб-браузер пересчитает положение других элементов на странице, и все будет сделано.Таким образом, код будет таким же, он будет короче, его легче читать, и он будет работать намного эффективнее, особенно в случае множества строк сетки.

Если вы используете форматер dynamicLink, который я предложилВы, прежде чем код может быть следующим:

{ name: 'act', index: 'act', width: 75, sortable: false, search: false,
    formatter: 'dynamicLink', formatoptions: {
        onClick: function (rowid, iRow, iCol, cellValue, e) {
            var myrow = $(this).jqGrid('getCell', rowid, 'myrow');
            $("<div>", {id: "tckDetDlg"})
                .addClass("dialog")
                .appendTo("body")
                .dialog({
                    height: 580,
                    width: 740,
                    autoResize: false,
                    position: 'top',
                    title: 'test dialog',
                    close: function () { $(this).remove() },
                    modal: true,
                    buttons: { "Ok": function () { $(this).dialog("close"); } }
                })
                .load('/mycontrolller/testDlg/' + myrow);
        }
    }}

Приведенный выше код будет понятным для чтения и понимания на мой взгляд.Код из onClick будет таким же, как вы могли бы использовать внутри ondblClickRow.В обоих случаях вам нужно знать только rowid.Таким образом, вы можете поместить код onClick в функцию вместо использования анонимной функции и вызвать функцию в обоих случаях:

// first define the callback function which we will use later
var myClickHandle = function (rowid) {
        var myrow = $(this).jqGrid('getCell', rowid, 'myrow');
        $("<div>", {id: "tckDetDlg"})
            .addClass("dialog")
            .appendTo("body")
            .dialog({
                height: 580,
                width: 740,
                autoResize: false,
                position: 'top',
                title: 'test dialog',
                close: function () { $(this).remove() },
                modal: true,
                buttons: { "Ok": function () { $(this).dialog("close"); } }
            })
            .load('/mycontrolller/testDlg/' + myrow);
    };

...
// define the grid
$("#jqTicketgrid").jqGrid({
    ...
    colModel: [
        ...
        { name: 'act', index: 'act', width: 75, sortable: false, search: false,
            formatter: 'dynamicLink', formatoptions: { onClick: myClickHandle } }
        ...
    ],
    ondblClickRow: function (rowid) {
        myClickHandle.call(this, rowid);
    }
...