У меня <h:selectOneMenu>. В зависимости от того, что выбрано, будет показан один из многих <div>, связанных с выбором, а остальные будут скрыты.
У каждого <div> есть несколько <h:inputText>, которые пишут в разные bean-компоненты @ViewScoped. Некоторые из этих <div> даже записывают одни и те же свойства в bean-компоненты.
Бывший.
<div>
<h:outputLabel for = "list" value = "Items"/>
<div>
<h:message for = "list"/>
<h:selectOneMenu id = "list" value = "#{bean.selectedItem}" >
<f:selectItem itemLabel = "Select one"></f:selectItem>
<f:selectItems value = "bean.someItemsList" />
</h:selectOneMenu>
</div>
</div>
<div id = "item1">
<!-- some other input fields -->
<div>
<h:message for = "item1input1"/>
<h:inputText id = "item3input1" value = "bean.thisIsTheSameProperty" />
</div>
</div>
<div id = "item2">
<!-- some other input fields -->
</div>
<div id = "item3">
<!-- some other input fields -->
<div>
<h:message for = "item3input1"/>
<h:inputText id = "item3input1" value = "bean.thisIsTheSameProperty" />
</div>
</div>
Проблема: когда я выбираю элемент, который будет отображать <div> (например, <div id = "item1">), а также есть еще один скрытый <div> (например, <div id = "item3">), который записывает те же свойства компонента (например, value = "bean.thisIsTheSameProperty"), и эти свойства аннотируются javax.validation.constraints.@NotNull, даже я даю значение этим полям ввода, когда я отправляю форму, я думаю, что JSF также запускает скрытый <div> (который обычно не имеет ввода).
Что я вижу во время отладки: когда форма будет отправлена, я вижу, что установщик bean-компонента будет вызываться дважды. В первый раз свойства bean-компонента будут установлены с правильным значением, которое я ввел, но во второй раз установщик будет вызываться с нулевыми значениями. Таким образом, проверка завершится ошибкой из-за @NotNull.
Я предполагаю, что JSF пытается установить значения bean-компонента дважды: один раз для полей ввода на показанном <div> и второй раз для скрытого <div> (поскольку они указывают на одни и те же свойства bean-компонента), но для скрытого bean-компонента нет входных данных. поля установлены (они пустые).
Я показываю/скрываю <div> с помощью jQuery в зависимости от элемента, выбранного из <h:selectOneMenu>.
Бывший.
$('#item1').show();
$('#item1').hide();
$('#item2').show();
$('#item2').hide();
$('#item3').show();
$('#item3').hide();
Есть ли способ заставить JSF вообще не учитывать скрытые <div>?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Кажется, вы предполагаете, что скрытые входные данные (скрытые через CSS) не отправляются на сервер. Это предположение неверно, и между прочим, это обычная HTML-вещь, а не JSF.
См., например. Остановить отправку поля ввода в форме
Но, тем не менее, это позволит манипулировать на стороне клиента с помощью инструмента разработчика браузера, чтобы «атаковать» ваше приложение. JSF, в отличие от всех разрекламированных фреймворков пользовательского интерфейса javascript, представляет собой полноценный Фреймворк MVC, который имеет встроенную защиту от манипулирование/вмешательство на стороне клиента и CSRF, XSS, для которой вам понадобятся функции, связанные с OWASP, в другом фреймворке. (Это и многое другое делает JSF (с PrimeFaces, OmniFaces и DeltaSpike) для меня по-прежнему отличной средой для быстрой разработки бизнес-приложений.)
Вам лучше использовать ajax для условно визуализировать тот или иной div, но вы не можете использовать «обновить» div, когда они определены так, как они у вас есть.
Смотрите также:
Что мне действительно нужно, так это скрытые входные данные (скрытые с помощью CSS или каким-либо другим способом), которые нельзя отправлять.
Затем используйте чистое «решение» html/javascript в первой ссылке в ответе, но, как вы можете видеть из голосов, то, что я предлагаю, является лучшим решением.
Ответ от @Kukeltje и комментарий от @drkunibar сработали для меня. Я его немного модифицировал.
Фактическое решение:
$('#myForm').submit(function() {
if ($('#list').find(':selected').val() === 'itemOption1') {
$('item3').remove();
} else if ($('#list').find(':selected').val() === 'itemOption3') {
$('item1').remove();
}
});
Я проверяю, какой вариант выбран. Если выбран вариант 1, то я удаляю div с iditem3 из DOM, иначе, если выбран вариант 3, я удаляю div с iditem1 из DOM.
Таким образом привязка bean.thisIsTheSameProperty передается только одна и значения не будут переопределены.
Спасибо.
Это то, что упоминается в ссылках в моем ответе. Если это то, что вам нужно, это относится к ни за что JSF и фактически является дубликатом stackoverflow.com/questions/3008035/…. и тогда нет необходимости добавлять его в качестве ответа. Но имейте в виду, это небезопасное решение.
Да, ваш ответ правильный. Спасибо! Но я не могу понять, как и почему это небезопасное решение. Мое решение не имеет ничего общего с CSRF-атаками. Ты видишь что-то, чего не вижу я? :)
В ответе также упоминается «подделка на стороне клиента». Не только CSRF и XSS
В моем случае пользователь может делать то, что хочет. Нет конфиденциальных данных или процессов, которые мне нужно защитить. В противном случае я бы разработал логику на стороне сервера. Но спасибо.
Ваша привязка bean.thisIsTheSameProperty была передана дважды, потому что у вас есть два поля ввода, которые связывают это свойство. Вы можете попробовать отключить поля ввода в скрытом <div>. Отключенные поля не переносятся.