jqGrid реализация пользовательской ячейки: интеграция raty-plugin - jqgrid


1

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

Во-первых, я работал с форматированием. В formatter я определил свой элемент 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, я еще не определил рейтинг. Хммм.

  •  15
  •  1
  • 8 фев 2020 2020-02-08 08:05:12

1 ответ

3

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

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

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

ОБНОВЛЕНО: Проведя время для написания комментариев и после того, как вы разместили свой код, я изменил код, чтобы показать, как можно интегрировать плагин-плагин. Поскольку результаты демо, которая выглядит 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 в моем примере кода).

  • 8 фев 2020 2020-02-08 08:05:12