Spring MVC JSP Form not pre-populating (or just back) - spring

I am new to Spring MVC (and front end for that matter). I have a jsp with a form on. In my controller's GET method I add the command to the ModelMap. The page does some validation (greys out things when checkboxes clicked, etc). Then I go to the next page. The user is suppose to be able to click the back button (which is wired up in an tag - for graphics reasons apparently) and then make changes to their form. Except...the form is empty.
So my main question - what is the best way to go back (to my .do) and retain all the values in the form? There are some things that runs on my GET method...so this still needs to happen.
What I tried: I read somewhere that the command is suppose to pre-populate the form? So I allready have a command which I use to get the info....this is what I did (but it doesn't work). (I debugged and the command is populated with the values)
<form class="form-horizontal" commandName="myCommand" name="formdetail" id="formdetail" method="post">
Controller
#RequestMapping(method = RequestMethod.POST)
public View handleSubmit(#ModelAttribute MyCommand myCommand, BindingResult result, HttpServletRequest aHttpServletRequest){
WebUtils.setSessionAttribute(aHttpServletRequest, "goalDetailCommand", goalDetailCommand);
//Then do some redirecting
#RequestMapping(method = RequestMethod.GET)
public String show(ModelMap model, HttpServletRequest aHttpServletRequest, #ModelAttribute MyCommand myCommand) throws Exception {
myCommand = (MyCommand)WebUtils.getSessionAttribute(aHttpServletRequest, "myCommand");
model.addAttribute("myCommand", myCommand);
Thanks
EDIT:
I didn't have the path part in. Added it but still no luck. Is something else wrong?
<input type="text" class="amount input-medium" path= "amountToSave" id="amountToSave" name="amountToSave" placeholder="0000.00">

I debugged and the command is populated with the values
its working as expected, just reference the command object's values/fields in the form, if the command object has a getTitle for example do this :
<form:input path="title" maxlength="90" id="title"/>

Related

Create a fragment for a form in Thymeleaf (and spring)

First I created a form in a simple HTML with Thymeleaf and everything was fine. Then moved to step 2 and I relocated my form to a fragment. I called the fragment like this:
<div th:insert="~{address::form($(address)}"></div>
and the fragment (which is in address.html) is like this:
<form th:fragment="form(address)" action="#" th:action="#{/address}" th:object="${address}" method="post">
<label>Street<label><span><input type="text" th:field="*{street}"></span>
<label>County:</label>
<span>
<select th:field="*{county}">
<option th:each="s : ${countyList}" th:value="${s.value}" th:text="${s.text}"></option>
</select>
</span>
...
but this is not working and it's throwing:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'street' available as request attribute
Please help with how to move an entire form into a Thymeleaf fragment? Also please add ideas for combos, so I can get their list from the model bean. Thank you!
PS the controller looks like this for now (add and edit ) buti will work to make it 1 function instead:
#GetMapping(value="/address")
public String newAddress(AddressModel address, Model model) {
model.addAttribute("address", address);
model.addAttribute("countyList", countyService.listCombo());
...
return "index";
}
#GetMapping(value="/address/{id}")
public String editAddress(Model model, #PathVariable("id") Long id) {
AddressModel address = addressService.load(id);
model.addAttribute("address", address);
model.addAttribute("countyList", countyService.listCombo());
...
return "index";
}
In my case the problem was coming from an unexpected direction. I have put 2 fragments address::form (for creating the form) and address::list (for showing a list of addresses) in the same file and somehow, for some yet unknown reason these 2 fragments are not working fine when in the same file. And the error was not very helpful. But as soon as I put them in 2 separate files like this: addressForm::form and addressList::list everything was ok. Interesting that if I keep the fragments in the same file but swap the order in which they are defined I can render the page correctly but I still get the error in the logs. Strange things.

spring model binding with disabled input

sorry for a dumb question but i can't understand quite what happens, and if it is what i suspect.. well i am really at a loss.
i am using spring boot + thymeleaf + materialize css to show and validate a form.
now what i don't meet in many examples that i see is this case:
some form fields are pre-filled and should seem disabled to the client, showing their pre-filled values. this pre-filling takes place in the controller, while i handle some other request, and redirect to this view
i am binding a pojo to the form using th:object like this
<form id="register_form" action="#" th:action="#{/showform}" th:object="${userInfo}" method="post">
<div class="input-field">
<label th:text="#{label.surname}" for="surname"></label>
<input type="text" th:field="*{surname}" id="surname" th:attr="value=${userInfo.surname}" />
</div>
<div class="input-field">
<label th:text="#{label.name}" for="givenname"></label>
<input type="text" th:field="*{givenname}" id="givenname" th:attr="value=${userInfo.givenname}" disabled="disabled" />
</div></form>
and getting it in the POST handler of the controller like this:
#RequestMapping(value = {"/showform"}, method = RequestMethod.POST)
public ModelAndView submitFormPage(#ModelAttribute("userInfo") #Valid UserInfo userInfo,
BindingResult bindingResult, RedirectAttributes redir)
{
ModelAndView mview = new ModelAndView();
if (bindingResult.hasErrors())
{
// show form again with error messages
mview.addObject("userInfo", userInfo);
mview.setViewName("/showform");
}
else
{
// ...
}
return mview;
}
RedirectAttributes is there for some other reason. As you can see, there are two elements on a form, and first one is enabled, and the second disabled.
Their values are populated correctly with pre-filled values from the POJO i pass to the view via the ModelMap. i can also trace it in the GET handler.
but the ModelMap i get back from the view contains the aforementioned POJO with NULL values in place of the elements that are bound to the disabled controls. i would expect them to be populated by the contents of the value attribute, even though those controls are disabled. the enabled controls carry their values alright.
or is it just that disabled controls simply are not included in the postback? if this is the case, how would you suggest me to do it? some suggested adding an obscure CSS that would "fake" the behaviour of a disabled control. or have i missed something in the general wiring?
i think with horror of possible workarounds - but i must be doing something wrong.. th:attr was one of the workarounds i tried, but it doesn't seem to do the trick. i also tried using th:id and th:disabled but it didn't help either.
There is a misunderstanding here I think about the use of disabled.
A readonly element is just not editable, but gets sent when the
according form submits. a disabled element isn't editable and isn't
sent on submit. Another difference is that readonly elements can be
focused (and getting focused when "tabbing" through a form) while
disabled elements can't.
More detailed comparison
So to answer your question: you should opt for readonly if you want to bind your attributes to your pojo and still the user can't edit them.

Thymeleaf Modify and Post Current Object

I have a form and post data into controller via Thymeleaf:
<form action="lia.html" th:action="#{/lia}" th:object="${myRequest}" method="post">
At another place of my html page, if a user click a particular button, I want to modify that object and send it to same controller.
I have already that object which has been initialised. Button is not a part of any form. How can I send that object into a controller with Thymeleaf.
PS: I know that I can send it via Javascript or put such buttons into a form but I want to learn the Thymeleaf way.
I think the only similar approach to what you're looking for is using bind with Spring EL expressions.
Thanks to the advanced form-field binding capabilities in Spring MVC,
we can use complex Spring EL expressions to bind dynamic form fields
to our form-backing bean. This will allow us to create new Row objects
in our SeedStarter bean, and to add those rows’ fields to our form at
user request.
Take a look the next link, where is good example:
http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#dynamic-fields
The button
<button type="submit" name="removeRow"
th:value="${rowStat.index}" th:text="#{seedstarter.row.remove}">Remove row</button>
Request Mapping
#RequestMapping(value="/seedstartermng", params={"removeRow"})
public String removeRow(
final SeedStarter seedStarter, final BindingResult bindingResult,
final HttpServletRequest req) {
final Integer rowId = Integer.valueOf(req.getParameter("removeRow"));
seedStarter.getRows().remove(rowId.intValue());
return "seedstartermng";
}

is it possible to send the entire list of objects in a submit form with spring mvc?

I am trying to modify and send a list of objects using spring MVC.
I want , when I will click in the button that triggers the form submit, in the controller, capture all the list with the objects.
Unfortunately.. I have no idea how to do this.
So far I got this:
<#form:form modelAttribute="MyObject" method="post" action"somewhere">
<#display:table list=myList id="myObject">
<#display.column title="Name">
${myObject.name}
</#display>
<#display.column title="value">
HERE I SHOULD MODIFY EVERY OBJECT WITH AN INPUT, NOT SURE IF THIS WOULD WORK
<form:input path=${myObject.value} id="value" />
</#display>
</#display>
</#form:form>
And at my controller so far I have this:
#RequestMapping (value="myurl" method = Request.POST)
public void myMethod(#ModelAttribute Object myObjects){
So here Id like to get the entire list of objects, but myObjects is null.
}
Any idea how to do this?
Thanks

Pass a request parameter in Spring MVC 3

I just want to send the value of my dropdownlist with a requestparameter. In my case being
Kidscalcula_web/start.htm?klasid=myValueHere
I know a way of doing this but it sounds so irrational to use it for this. If I was bored I'd probably write some jQuery to do a post and send the parameter for instance.Now it really sounds like a very bad idea to manually make my requeststring, since Spring takes care of that. So how could I make a simple form that just sends my dropdownvalue to my controller?
It's just that I can't find something so trivial anywhere, and one of you can probably help me out quickly.I suppose the controller would be just as trivial as:
#RequestMapping(value = "post")
public String postIndex(#RequestParam("klasid") String klasid, HttpServletResponse response,
HttpServletRequest request) {
}
But I really can't find any examples on how to make a JSP to send me that value. Is this possible with the <form>taglib ?
The <form> taglib is generally used with form-backing command objects, rather than being bound to the controllers using individual #RequestParam arguments. This is why you won't see any documentation examples of that combination being used together.
For example, rather than having #RequestParam("klasid"), you'd have a command class with a field called klasid, and Spring would bind the whole lot together:
#RequestMapping(value = "post")
public String postIndex(#ModelAttribute MyCommandClass command) { /../ }
This makes sense when you consider that forms typically have multiple parameters, and it'd get cumbersome to declare them all using #RequestParam.
Having said that, you can still do it - any form controls will generate request parameters that #RequestParam can bind to, but if you choose to deviate from Spring MVC's form-backing command pattern, then it's quite awkward.
You don't even need a taglib to send this request. You can create a simpliest HTML form with method = "GET" (what is the default value of method):
<form action = "...">
<select name = "klasid">
<option value = "value1">Option 1</option>
<option value = "value2">Option 2</option>
<option value = "value3">Option 3</option>
</select>
<input type = "submit" />
</form>

Resources