Как обновить значения 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.
Пути решения вашей проблемы.
Используйте "ZK-Way":
Просто слушайте на стороне сервера и проверяйте вещи там.
Я не уверен, если не выбранTabs
обновляются, но я уверен, что вы могли бы обновитьGrid
компоненты на событие выбора изTab
,Запустите 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-запрос на сервер, содержащий обновления в необходимые ячейки.