I'm trying to create a fragment for the multiselect field in my webapp. But I'm running into various issues with regards to passing in the field that should be bound to the select element. I figure I have a syntax error, but I'm not sure what it is.
For selectedField in my addUser.jsp file, I've tried ${selectedAdminAccess}
, *{selectedAdminAccess}
, ${userForm.selectedAdminAccess}
, etc.
And with those various combinations, in the forms.html file, I've tried ${selectField}
, *{selectField}
, and the preprocessor directive: ${__${selectField}__}
. Have I just missed the correct combination?
The error I'm getting is "Neither BindingResult nor plain target object for bean name 'X' available as request attribute". Where X is (for the preprocessor attempt) the fieldname entered in the addUser.jsp page, or "selectField" when not using the preprocessor attempt.
Here's what I've got.
Controller
@GetMapping(value={"/adduser"}
public ModelAndView getAddUserPage(Model model, @RequstParam(required = false) Long selectedUserId) {
ModelAndView mav = new ModelAndView("/addUser");
UserForm userForm = new UserForm();
mav.addObject("userForm", userForm);
return mav;
}
model UserForm
public class UserForm {
private List<Office> adminAccess = new ArrayList<>();
private List<String> selectedAdminAccess = new ArrayList<>();
// Getter/Setter
...
}
addUser.jsp
<form method="post" action="#" data-th-action="@{/addUser}" data-th-object="${userForm}">
<!-- other interesting page stuff -->
<div data-th-replace="fragments/forms.html :: multi-select(
id='adminSelect',
selectClass='office-target',
selectField='*{selectedAdminAccess}',
optionList='*{adminAccess}',
optionListValue='id',
optionListText='name',
size=8)"></div>
</form>
forms.html
<div data-th-fragment="multi-select(id, selectClass, selectField, optionList, optionListValue, optionListText, size)" >
<select id="${id}" class="mdb-select colorful-select md-form ${selectClass}" size="${size}" multiple
searchable data-th-field="${__${selectField}__}">
<option data-th-each="option : ${adminAccess}"
data-th-value="${option.__${optionListValue}__}"
data-th-text="${option.__${optionListText}__}"></option>
</select>
</div>
The ultimate goal here is to have an expression data-th-field="*{selectedAdminAccess}"
To accomplish this:
selectField
, you need to pass a string with value 'selectedAdminAccess'
.th:field
, use the preprocessing expression *{__${selectField}__}
.The HTML you provided looks like it has other problems... but I think your final HTML will look something like this:
<!-- page -->
<form method="post" action="#" data-th-action="@{/addUser}" data-th-object="${userForm}">
<!-- other interesting page stuff -->
<div data-th-replace="fragments/forms.html :: multi-select(
id='adminSelect',
selectClass='office-target',
selectField='selectedAdminAccess',
optionList=*{adminAccess},
optionListValue='id',
optionListText='name',
size=8
)" />
</form>
<!-- fragment -->
<div data-th-fragment="multi-select(id, selectClass, selectField, optionList, optionListValue, optionListText, size)" >
<select data-th-id="${id}"
data-th-class="|mdb-select colorful-select md-form ${selectClass}|"
data-th-size="${size}"
multiple
searchable
data-th-field="*{__${selectField}__}">
<option data-th-each="option : ${optionList}"
data-th-value="${option.optionListValue}"
data-th-text="${option.optionListText}" />
</select>
</div>