jqGrid реализация пользовательской ячейки: интеграция raty-плагина - PullRequest
1 голос
/ 30 января 2011

Я уже несколько дней работаю, на первый взгляд, над простой задачей - реализовать собственную ячейку. Задача следующая: создать пользовательскую ячейку с элементом div с идентификатором (например, "mydiv"), затем вызвать функцию для этого div, например $('#mydiv').raty({start: cellvaue, readonly:true}), а затем 3-ю подзадачу - в режиме редактирования (editGridRow) Я должен изменить параметр raty-function на readonly:false, так как должно быть возможно изменить значение.

Во-первых, я работал с форматером. В форматере я определил свой элемент div, а с вызовом afterInsertRow моя функция $ ('# mydiv'). Raty ({start: cellvalue, readonly: true}). Для обзора это работало отлично. Но в модальном диалоге редактирования editGridRow всегда вводился текст ввода формы, который мне здесь не нужен. Мне нужен здесь только мой элемент div. Если я правильно понимаю, средство форматирования только изменяет значения, но по-прежнему отображает входной текст формы.

Затем я переключился на edittype: custom, но это не помогло, потому что эти функции вызываются впервые только в editGridRow.

Я уверен, что эта проблема разрешима, вопрос только в том, как.

Спасибо за любые советы.

UPDATE Благодаря Олегу я сейчас очень близок к оперативной реализации этой задачи. Здесь я опишу свое решение (основываясь на советах Олега или, по крайней мере, на моей интерпретации его советов). JqGrid определяется с помощью datatype: "json". Пользовательская ячейка определяется как:

name:'ranking', editable:true, edittype:'custom',formatter:ratingFormatter, 
editoptions:{custom_element:ratingFormatter, custom_value:ratingValue}

Указанные функции определены следующим образом:

function ratingFormatter(cellvalue, options, rowObject) {return '<div class="rnk"></div>';}; 

function ratingValue(elem, operation, value) {return $('#ranking-score').val();};

Затем модальное диалоговое окно редактирования:

ondblClickRow: function(id) {
jQuery('#grid').jqGrid('editGridRow',id,
{closeOnEscape:true,width:400, 
savekey:[true,13],
recreateForm:true,beforeShowForm:initRating
});

Функция initRating:

function initRating() {$('#ranking').raty({path:'/img/'})};

И, наконец, событие loadComplete

 loadComplete: function (data) {
 var ids = jQuery("#grid").getDataIDs();
 for(var i=0;i<ids.length;i++){
 var rowid = ids[i];
 var ranking = data.rows[i].cell[6];
 $('#' + rowid +'> td > div.rnk').raty({path:'/img/',start:ranking,readOnly:true});
 $('#' + rowid).contextMenu('MenuJqGrid', eventsMenu);
 }
 }

Так много шагов для такой маленькой вещи, как плагин рейтинга. Невероятно. Последняя нерешенная проблема - получение текущей оценки в функцию initRating. Это означает, что если я перейду к editGridRow, у меня еще не определен рейтинг. Хммм.

1 Ответ

3 голосов
/ 30 января 2011

Об опции edittype:custom Я рекомендую прочитать это и старые ответы. Важно использовать настройку recreateForm:true, чтобы пользовательские функции редактирования custom_element и custom_value не вызывались один раз.

Вы не включили ни одного кода в свой вопрос. Ваше описание проблемы допускает различные толкования того, как вы реализовали то, что описали. Например, мне не ясно, как вы меняете параметр raty-функции на readonly:false. Используете ли вы beforeShowForm событие (см. этот в качестве примера) или используете dataInit свойство editoptions . В обоих случаях все должно работать при правильной реализации.

Еще одна вещь, которая не для меня. Почему вам нужно включить id="mydiv" в ячейку? Ваша реализация позволяет вставлять несколько идентификаторов с одинаковым именем? Это было бы ошибкой. Если вы можете найти ячейку на основе содержимого ячейки или строки, вы можете вызвать .raty({start: cellvaue, readonly:true}) внутри обработчика событий loadComplete, и вам не нужно вставлять дополнительный атрибут id в элемент <td>. Использование afterInsertRow делает сетку более медленной, потому что она вынуждает отображать сетку при добавлении каждой строки, а не только после того, как все строки будут вставлены в сетку (см. Параметр gridview:true).

ОБНОВЛЕНО: Потратив столько времени на написание комментариев, а также после того, как вы опубликовали свой код, я изменил код, чтобы показать, как можно интегрировать плагин raty. Как результат демо , которое выглядит как enter image description here
Я использовал встроенное редактирование вместо редактирования формы только потому, что редактирование формы не полностью поддерживает локальное редактирование, но я хотел сделать демонстрацию без каких-либо серверных компонентов.

Как и в вашем коде, я использовал двойной щелчок для редактирования строки. Вот основные фрагменты кода:

var lastSel;
var grid = $("#list");
var initRaty = function(rowid) {
    var ranking = grid.getCell(rowid,4); // the Ranking column has the index 4
    // because we use rownumbers:true the index of the Ranking column will be 1 higher
    $('#' + rowid +'> td:nth-child(5) > div').raty({
        path:'http://www.ok-soft-gmbh.com/jquery.raty/1.0.1/img/',
        start:ranking,
        readOnly:true
    });
};
grid.jqGrid({
    // ...
    colModel: [
        // other column definition
        { name:'Ranking', editable:true, width: 100, title: false,
          formatter: function(cellvalue, options, rowObject) {
              // insert div needed for the raty plugin
              // and insert a hidden span with the rating value
              return '<div></div><span style="display: none;">'+cellvalue+'</span>';
          }, unformat: function (cellvalue, options, cellobject) {
              // get rating value from the hidden span
              return cellobject.find("span").text();
          }, edittype:'custom', editoptions: {
              custom_element: function(value, options) {
                  var val = $(value);
                  var elem = $('<div id="'+options.id+'"/>');
                  setTimeout(function(){
                      elem.raty({
                          path:'http://www.ok-soft-gmbh.com/jquery.raty/1.0.1/img/',
                          start:(val.length>1? val[1].innerText: value)
                      });
                  }, 100);
                  return elem[0];
              },
              custom_value: function(elem) {
                  return elem.find("input").val();
              }
          }
        }
    ],
    editurl: 'clientArray',
    loadComplete: function (data) {
        var ids = grid.getDataIDs();
        for(var i=0;i<ids.length;i++){
            initRaty(ids[i]);
        }
    },
    ondblClickRow: function(id, ri, ci) {
        grid.jqGrid('editRow',id,true,null,null, 'clientArray', {}, initRaty);
    },
    onSelectRow: function(id) {
        if (id && id !== lastSel) {
            if (typeof lastSel !== "undefined") {
                grid.jqGrid('restoreRow',lastSel);
                var cell = $('#' + lastSel +'> td:nth-child(5)');
                var spans = cell.find('span');
                if (spans.length > 1) {
                    // if the lastSel row was not only selected, but also
                    // was in editing mode, get the hidden text with the ranking
                    var ranking = cell.find('span')[1].innerText;
                    cell.find('div').raty({
                        path:'http://www.ok-soft-gmbh.com/jquery.raty/1.0.1/img/',
                        start:ranking,
                        readOnly:true
                    });
                }
            }
            lastSel = id;
        }
    },
    // other jqGrid parameters
});

Если вы будете использовать редактирование формы и вызывать функцию editGridRow вместо editRow , вам нужно будет использовать опцию recreateForm:true и использовать afterComplete или afterSubmit для вызова initRaty с измененными значениями (точно так же, как я использую aftersavefunc параметр editRow в моем примере кода).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...