Как обновить значения ZK Grid из jQuery

У меня есть три Tabs и в каждой вкладке у меня есть Grid,

Данные для каждого Grid исходит из базы данных, поэтому я использую rowRenderer заселять сетки. Следующий код является общим для всех трех гридов:

<grid id="myGrid1" width="950px" sizedByContent="true" rowRenderer="com.example.renderer.MyRowRenderer">

Ряды построены из Doublebox объекты. Данные заполнены успешно.

Эта проблема:

Мне нужно обработать несколько ячеек на стороне клиента. Редактирование выполняется с помощью щелчка мышью на определенной ячейке и ввода значения.

В качестве примера предположим, что пользователь редактирует первую ячейку в первой строке, и значение должно распространяться на все остальные ячейки в той же строке и во всех трех сетках (так же как и две сетки, которые пользователь в настоящее время не видит, потому что они в tabpanes). я использую jQuery чтобы сделать это распространение значения, и он работает хорошо.

Я передаю JQuery следующим образом:

doublebox.setWidgetListener(Events.ON_CHANGING, jQuerySelectors);
doublebox.setWidgetListener(Events.ON_CHANGE, jQuerySelectors);

Это позволяет изменить значение в 1 ячейке, и изменение мгновенно (визуально) видно во всех других ячейках, отфильтрованных селекторами jQuery.

Проблема в том, что значение визуально распределяется по всем ячейкам, но когда я пытаюсь сохранить Grid данные возвращаются в базу данных, фоновые значения старые. Я предполагаю что ZK-Grid компонент не знает, что jQuery изменил все значения ячеек. Тем не менее, если я вручную нажимаю на ячейку, которая уже имеет значение NEW (введите / оставляю / изменяю фокус), когда я сохраняю сетку, значение NEW будет правильным в этой конкретной ячейке. Может быть, это подсказка, как я могу решить это.

Код того, как я извлекаю Grid ценности:

Grid tGrid = (Grid) event.getTarget().getFellow("myGrid1");
ListModel model = tGrid.getModel();
MyCustomRow tRow = (MyCustomRow)model.getElementAt(i); 

Модель для моего Grid это List из MyCustomRow:

myGrid1.setModel(new ListModelList(List<MyCustomRow> populatedList));

У меня есть пара предположений, но все, что я пробовал, не сработало. Я имею в виду, что jQuery события и ZK-Events разные и, вероятно, изолированные в разных контекстах. (Хотя я пытался запускать события из jQuery и так далее..)

У вас есть какие-нибудь предложения? В целом мой подход верен или есть другой способ сделать это? Спасибо за ваше время заранее!

2 ответа

Решение

Ваша проблема именно то, что вы ожидаете.
Zk имеет свою собственную систему событий и не заботится о вашем JQ,
потому что это JQ и ZK не соблюдают DOM.

Пути решения вашей проблемы.

  1. Используйте "ZK-Way":
    Просто слушайте на стороне сервера и проверяйте вещи там.
    Я не уверен, если не выбран Tabs
    обновляются, но я уверен, что вы могли бы обновить Grid
    компоненты на событие выбора из Tab,

  2. Запустите zk-событие для себя:
    Все, что вам нужно знать, написано в ZK Doc.
    В основном вы собираете свои данные на стороне клиента, отправляете
    Event на сервер через zAu.send() извлечь
    данные из объекта JSON на сервере и обновите свой Grids

Я бы предпочел первый, потому что это меньше работы и не должно быть
заметная разница в трафике.

Я публикую решение, которое мы придумали:

Это javascript, прикрепленный к каждому Doublebox в Z-Grid

//getting the value of the clicked cell
var currVal = jq(this).val(); 

//getting the next cell (on the right of the clicked cell)
objCells = jq(this).parents('td').next().find('.z-doublebox');

// if there's a next cell (returned array has length) - set the value and
// fire ZK onChange Event
if (objCells.length) {
    zk.Widget.$(jq(objCells).attr('id')).setValue(currVal);
    zk.Widget.$(jq(objCells).attr('id')).fireOnChange();
} else {  //otherwise we assume this is the last cell of the current tab
    //So we get the current row, because we want to edit the cells in the same row in the next tabs
    var currRow = jq(this).parents('tr').prevAll().length;

    //finding the next cell, on the same row in the hidden tab and applying the same logic
    objCellsHiddenTabs = jq(this).parents('.z-tabpanel').next().find('.z-row:eq(' + currRow + ')').find('.z-doublebox');
    if (objCellsHiddenTabs.length) {
        zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).setValue(currVal);
        zk.Widget.$(jq(objCellsHiddenTabs).attr('id')).fireOnChange();
    }
}

Код Java в классе RowRenderer выглядит примерно так:

... 
if (someBean != null) {

      binder.bindBean("tBean", someBean);

      Doublebox box = new Doublebox();
      setDefaultStyle(box);
      row.appendChild(box);
      binder.addBinding(box, "value", "tBean.someSetter");
 ...

 private void setDefaultStyle(Doublebox box) {
    box.setFormat("#.00");
    box.setConstraint("no negative,no empty");
    box.setWidth("50px");

    String customJS = ""; //the JS above

    //this is used to visually see that you're editing multiple cells at once
    String customJSNoFireOnChange = "jq(this).parents('td').nextAll().find('.z-doublebox').val(jq(this).val());";
    box.setWidgetListener(Events.ON_CHANGING, customJSNoFireOnChange);
    box.setWidgetListener(Events.ON_CHANGE, customJS);

}

Интересно отметить, что ZK оптимизирует эти события fireOnChange и отправляет только 1 ajax-запрос на сервер, содержащий обновления в необходимые ячейки.

Другие вопросы по тегам