| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Проблема с h:dataTable и h:selectOneMenu |
| Автор: TopaZ 27.2.2009, 21:54 |
| Здравствуйте! Помогите пожалуйста с такой проблемой: я создаю dataTable для заполнения таблицы БД, в dataTable в каждой строке должно быть по 3 selectOneMenu, причем каждый из них должен содержать в себе список элементов соответствующий выбранному до этого selectOneMenu (т.е. сначала нужно выбрать например в одном selectOneMenu страну, в другом область, в третьем город и соответственно не должно быть ситуации что в США есть Харьковская область в которой есть город Лондон). В каждой строке помимо комбобоксов будут еще и другие колонки, но они в рассмотрении не учавствуют. Далее нужно заполнить таким образом несколько строк и сохранить сразу все в БД, ну или сначала скажем в ArrayList<TableRowEntry> Вопросы: 1) как осуществить зависимость selectOneMenu один от другого (я пробовал для каждого прописать свойство onchange="submit()", но это не привело к немедленной записи выбранного значения в бин, и соответственно я не могу определить, что выдать в остальные комбо-боксы. При этом сабмит происходит только после выбора всех трех комбобоксов). Пробовал еще подключить в комбо-боксы a4j:support из библиотеки RichFaces и установить reRender, но отдельный комбо-бокс перерендерить не получилось(ошибка). 2)как сохранять сразу все непустые строки? 3)как добавлять в таблицу пустую строку для заполнения по началу заполнения последней незаполненной (т.е изначально при загрузке страницы например будет выдаваться 5 пустых строк, а при заполнении всех, т.е. при начале заполнения 5-й должна отрисоваться 6-я и т.д. ) Может кто-нибудь поделится примером таблицы с подобной функциональностью? Спасибо. |
| Автор: TopaZ 27.2.2009, 22:39 | ||||
| У каждого проекта есть категории работ, а у каждой категории - соответственно виды работ(активити) Пока что во все комбо-боксы выдаются все записи из соответствующих таблиц БД. Вот код страницы:
А вот ошибка:
|
| Автор: Jamon 28.2.2009, 23:04 |
| Хм,я бы попробовал юзать контрол от richfaces - rich:inplaceSelect, к нему можно привязать actionListener в джава бине. Соответственно, когда делается выбор первого бокса, кидается это событие, и в бине ты можешь заполнить коллекции, к которым будешь подвязывать остальные боксы, и плюс сюда же reRender на них. НО. у меня подобная штука не работает(. Т.е. не кидается это событие... и учти, что только inplaceSelect умеет работать c SelectItem'ом, для которого заданы как value, так и label. Обычный рич комбобокс только один параметр тянет (это ему огромные минус, вообще не понятно почему нельзя было сделать поддержку того и того) |
| Автор: TopaZ 1.3.2009, 02:18 | ||
| Jamon, частично получилось, используя rich:inplaceSelect, но в целом такое решение похоже не подойдет: 1) inplaceSelect(и его actionListener) у меня заработал корректно только в опере, ни в IE, ни в Firefox, ни в Safari, ни в Google Chrome actionListenerне работает. 2) для того чтобы заработало в опере, нужно добавить аттрибут showControls="true", но при этом после выбора появляются две кнопочки (сохранить и отменить) возле контрола inplaceSelect. Listener срабатывает только когда нажимаешь на кнопочку сохранить- в общем что-попало получается Вот код:
Может есть еще какие-нибудь варианты реализации? |
| Автор: Jamon 4.3.2009, 15:40 | ||
Появилась идея, можно юзать a4j:support:
смысл такой - к обычному jsf тэгу мы прикручиываем ajax функциональность, и теперь при бросании компонентом указанного js события должен вызываться listener (этим не ограничивается, можно так же настроить reRender). Это все исходя из их доков. Но опять же проблема - у меня, пока что, не заработало( попробуй - может получится |
| Автор: TopaZ 4.3.2009, 17:52 |
| Jamon я в самом начале поста показывал, что использовал этот элемент, но все дело даже не в том, что не посылается событие (оно в итоге посылается), а в том, что по всей видимости при reRendere таблицы "теряется" объект, который содержит в себе listEntry, т.е. таблица попросту не получает объект, котрый надо перерендерить (ну или что-то в этом роде). Похоже все дело кроется именно в том как правильно работать в данном случае с таблицой h:dataTable. Возможно там нужно использовать какую-нибудь специфическую модель данных или как-то биндить и отлавливать все действия, которые происходят внутри таблицы... Пытался найти какую-нить доку по dataTable, но толкового ничего не нашел... |
| Автор: TopaZ 7.3.2009, 14:20 |
| Ура! Основную проблему решил. Как только доделаю этот кусок, сразу выложу здесь решение. Остался только вопрос по автоматическому добавлению пустых строк в таблицу. |
| Автор: Jamon 9.3.2009, 16:07 |
| Выложи пока решение основной проблемы, плиз=) |
| Автор: TopaZ 11.3.2009, 00:01 | ||||||
| Значит так. Все дело заключалось в том, что нужно было использовать DataModel (в моем случае ListDataModel). При работе c h:dataTable данные заворачиваются в модель данных. Таким образом далее чтобы получить все строки таблицы можно использовать метод getWrappedData(), а для получения одной строки используется метод getRowData(). Таким образом класс, представляющий одну строку в таблице имеет вид:
Теперь класс в котором у меня содержатся листенеры и основная работа стаблицей:
Где-то так. Вообще-то вписывать запросы к БД в этот класс не стоило, но для ускорения написания работоспособного приложения пока что будет так, а потом можно будет и разделить на уровни DAO и бизнес логики. Теперь сама страница:
Вданном примере не показано сохранение таблицы в список или в БД, но думаю понятно как это сделать (на примере листенеров). Остается вопрос как сделать автоматическое добавление пустой строки по заполнению имеющихся. Как это делается, с помощью JavaScript или может еще как-то? |