empty object in controller from thymeleaf form - model-view-controller

I have a table showing testResults using thymeleaf template -
<tr th:each="testResult,iterationStatus : ${testResults}">
<td th:text="${iterationStatus.count}">1</td>
<td th:text="${testResult.name}">DOMAIN</td>
<td th:text="${testResult.length}">PROCESS</td>
<td>
<form ACTION="#" th:action="#{/deleteName}" th:object="${testResult}" method="POST">
<input type="hidden" th:field="*{name}"/>
<input type="hidden" th:field="*{length}"/>
<button type="submit">submit</button>
</form>
</td>
</tr>
name and length are showing fine in the html, but when i submit the form, controller gets name and length as empty values.
What i am doing wrong in assigning the values....
below is controller method that gets invoked -
#RequestMapping(method= RequestMethod.POST, value = "/deleteName")
public String deleteName(#Valid #ModelAttribute("testResult") TestResult testResult, BindingResult bindingResult, Model model, HttpServletRequest request) {
System.out.println(testResult.toString());
return "/";
}
output once i submit the form -
TestResult [name=, length=, xyz=null]

I couldn't get th:field to work inside a th:object, like you're doing here. However, if I stop using th:field, and use th:value instead, the form submits successfully.
<tr th:each="testResult : ${testResults}">
<td th:text="${testResult.name}">DOMAIN</td>
<td th:text="${testResult.length}">PROCESS</td>
<td>
<form ACTION="#" th:action="#{/deleteName}" method="POST">
<input type="hidden" name="name" th:value="${testResult.name}"/>
<input type="hidden" name="length" th:value="${testResult.length}"/>
<button type="submit">submit</button>
</form>
</td>
</tr>

Related

Spring MVC editable table (Thymeleaf)

I have 2 entities - Invoice and InvoiceProduct. Invoice class has a field List of InvoiceProduct because Invoice has #OneToMany mapping on InvoiceProduct.
I want to send the List of InvoiceProduct to Thymeleaf with with editable fields with a Submit button. When I click on Submit button, the new edited List should be returned to the controller. However, I am able to send the list to the view, but when I send the edited list to controller, it is being passed as 'null'.
update-invoice.html:
<form action="#" th:action="#{/api/invoice/saveInvoice}" th:object="${invoice}" method="POST">
<table class="table table-bordered table-striped">
<thead class="thead-dark">
<tr>
<th>PID</th>
<th>Quantity</th>
<th>Unit Price</th>
</tr>
</thead>
<tbody>
<tr th:each="temp : ${invoice?.invoiceProducts}" >
<td><input name="invoiceProducts[${tempStat.index}].productId" th:value="${temp.productId}"/></td>
<td><input name="invoiceProducts[${tempStat.index}].quantity" th:value="${temp.quantity}"/></td>
<td><input name="invoiceProducts[${tempStat.index}].price" th:value="${temp.price}"/></td>
</tr>
</tbody>
</table>
<button type="submit" class="btn btn-info col-2">Submit</button>
</form>
InvoiceController:
#PostMapping("/saveInvoice")
public String postInvoice(#ModelAttribute("invoice") Invoice invoice) {
logger.info("invoice products " + invoice.getInvoiceProducts());
return "dummy";
}
What else do I need to add so that my update-invoice.html passes the list to my controller ?
You can try something like below as an example for thymleaf:-
<form method="post" th:action="#{/users/}" th:object="${userInfo}" class="col card p-3 mb-5">
<div class="form-group">
<label for="firstName">First Name</label>
<input id="firstName" placeholder="Enter First Name" required type="text" th:field="*{firstName}"
class="form-control"/>
</div>
<div class="form-group">
<label for="lastName">Last Name</label>
<input id="lastName" placeholder="Enter Last Name" required type="text" th:field="*{lastName}"
class="form-control"/>
</div>
<div class="form-group">
<label for="role">Role</label>
<select id="role" required th:field="*{role}" class="form-control ">
<option value="" hidden>Select a role</option>
<option th:each="role : ${T(com.springhow.examples.springboot.thymeleaf.domain.entities.Role).values()}"
th:value="${role}"
th:text="${role}">
</option>
</select>
</div>
<input type="submit" class="btn btn-primary" value="Create User">
</form>
and into Controller:-
#RequestMapping(value = "/", method = RequestMethod.POST)
public String createUser(Model model, #ModelAttribute UserInfo userInfo) {
UserInfo user = userService.createUser(userInfo);
return "redirect:/users/";
}

Thymeleaf : How to edit a field?

In my class Test I have a list of Versions like this :
Test Class:
#OneToMany(fetch = FetchType.LAZY, mappedBy = "idTest")
private List<Versions> version;
In thymeleaf I code this to display the list of version
<tr th:each ="test : ${testList}">
<td th:each="p : ${test.version}" th:text="${p.getVersions().version}" > </td>
</tr>
This work for me.
Now I would edit it (Version field), my code :
<form class="form-horizontal" th:object="${update}" th:action="#{/update}" method="post">
<div class="col-sm-10">
<th:block th:each="p : ${version}" >
<input type="text" class="form-control" th:field="*{p.getVersions().version}"/>
</th:block>
</div>
</form>
It display only the label Version, and it doesn't show the version input
Have you any idea ?
Thanks.
It seeems you're not iterating the object correctly. Try this:
<tr th:each ="test : ${testList}">
<form class="form-horizontal" th:object="${update}" th:action="#{/update}" method="post">
<div class="col-sm-10">
<th:block th:each="p : ${test.version}" >
<input type="text" class="form-control" th:field="*{p.getVersions().version}"/>
</th:block>
</div>
</form>
</tr>

how to handle dynamically created forms laravel 5.4

I want to know how to fetch name of checkboxes from dynamically created form. First I am displaying each records of data in a separate form then If records need to be deleted we will be able to delete. I am able to give different name as somename+id. But how do I know which name is going in the controller. As It is not clear that which name is going in the controller, I am not able to delete the record. I am doing it in laravel 5.4. Here is my code -
#if (isset($allcolors))
#foreach ($allcolors as $color)
<tr>
<form method="post" action="/delete">
{{csrf_field()}}
<input type="hidden" name="_method" value="DELETE">
<td>
<span class=""><input type="checkbox" name="deletecolor[{{$color->id}}]" value="{{$color->id}}"></span>
</td>
<td>
<div style="background:{{$color->web_color}}">a</div>
</td>
<td>{{$color->color_name}}</td>
<td>
<button type="submit" class="btn btn-danger">
Delete
</button>
</td>
</form>
</tr>
#endforeach
#endif
then on form submission I want to fetch which I am doing like this -
public function destroy(Request $request)
{
//
$id = $request->input('deletecolor');
$affected = DB::update("DELETE FROM vehicle_color where id = ?", [$id]);
//echo $affected==1?"Successfully Deleted":"Delete Fail";
}
I see you have $color->id. Why not delete them based on that?
#if (isset($allcolors))
#foreach ($allcolors as $color)
<tr>
<form method="post" action="/delete">
{{csrf_field()}}
<input type="hidden" name="_method" value="DELETE">
<td><span class=""><input type="checkbox" name="deletecolor[{{ $color->id }}]" value="{{$color->id}}"></span></td>
<td><div style="background:{{$color->web_color}}">a</div></td>
<td>{{$color->color_name}}</td>
<td><button type="submit" class="btn btn-danger" data-toggle="modal" data-target="#colorDelPopup">Delete</button></td>
</form>
</tr>
#endforeach
#endif
And in your controller:
public function destroy(Request $request)
{
$ids = $request->input('deletecolor');
// Instead of raw SQL, you can use the query builder to make your life a bit easier
$affected = DB::table('vehicle_color')->whereIn('id', $ids)->delete();
//echo $affected==1?"Successfully Deleted":"Delete Fail";
}
This should do the trick.

DOJO CRUD Spring MVC

Is there any reference available for DOJO UI with Spring MVC for CRUD operations
DOJO form submit yields ResponseMethod.POST not supported when using RequestMapping annotation on Spring Controller?
Providing partial snippet for better understanding
Annotated Spring Controller code(partial):
#RequestMapping(
value = "/create",
headers="Accept=application/json",
method=RequestMethod.POST)
public #ResponseBody Map<String, ? extends Object> create(#RequestParam() Object data)
throws Exception {
//Request processing
}
Dojo Code(partial):
dojo.rawXhrPost({
postData: dojo.formToJson("contactFormDialog"),
handleAs: 'json',
headers: { "Content-Type": "application/json"},
load:testLoadfunction,
error:testError
});
Form code:
<form id="contactFormDialog" action="create.action" method="post">
<table>
<tr>
<td><label for="loc">Name: </label></td>
<td><input dojotype="dijit.form.TextBox" type="text"
name="name" id="name"></td>
</tr>
<tr>
<td><label for="date">Phone: </label></td>
<td><input dojotype="dijit.form.NumberTextBox" type="text"
name="phone" id="phone"></td>
</tr>
</table>
<div class="dijitDialogPaneActionBar">
<button dojotype="dijit.form.Button" id="submit" type="submit"
label="Submit" onClick="testFormAction"></button>
<button dojotype="dijit.form.Button" id="cancel" type="button"
onClick="alert('no');">Cancel
</button>
</div>
</form>

Disable submit button on freemarker/spring form until file chosen

How do I disable the submit button until the user has chosen a file?
I have a form on my page:
<table>
<form method="post" enctype="multipart/form-data" id="messageupload">
<#spring.bind "messageUploadCommand.*"/>
<tr>
<td><#spring.formInput 'messageUploadCommand.multipartFile' '' 'file' /></td>
<td><button type="submit" id="searchButton">Upload</button></td>
<td><#spring.formSingleSelect
'messageUploadCommand.messageFormat',
messageFormats, '' />
<#spring.showErrors '<br>', 'error' /> </td>
</tr>
</form>
</table>
If the user submits the form before choosing a file I get
freemarker.template.TemplateException: Error executing macro: formSingleSelect required parameter: options is not specified.
at freemarker.core.Macro$Context.sanityCheck(Macro.java:211)
at freemarker.core.Macro$Context.runMacro(Macro.java:169)
at freemarker.core.Environment.visit(Environment.java:603)
at freemarker.core.UnifiedCall.accept(UnifiedCall.java:106)
at freemarker.core.Environment.visit(Environment.java:210)
at freemarker.core.MixedContent.accept(MixedContent.java:92)
at freemarker.core.Environment.visit(Environment.java:210)
at freemarker.core.Environment.process(Environment.java:190)
at freemarker.template.Template.process(Template.java:237)
at ...
This is how I did it:
<table>
<form method="post" enctype="multipart/form-data" id="messageupload">
<#spring.bind "messageUploadCommand.*"/>
<tr>
<#assign onChangeScript = "document.getElementById('uploadButton').disabled = (value.length=0); ">
<td><#spring.formInput 'messageUploadCommand.multipartFile' 'onchange=\"${onChangeScript}\"' 'file' /></td>
<td><button type="submit" disabled="true"
id="searchButton">Upload</button></td>
<td><#spring.formSingleSelect
'messageUploadCommand.messageFormat',
messageFormats, '' />
<#spring.showErrors '<br>', 'error' /> </td>
</tr>
</form>
</table>
I added the file-chooser onchange script via a Freemarker variable, and disabled the button by default. The onchange script tests for the length of the value, i.e. the filename, being zero.

Resources