How to validate movable(portable) application - spring

I'm having trouble with validating one movable app.
When I open the app and fill-up the data, I send this data to the controller. Then validate this data and if any error I wan to show this error on the app without close it. If no error, I proceed to the success page and close the app. So far I manage to create the app and to validate the data, but my problem is that I don't know how to redirect from the controller back to the add without close it and show this error.
My web application is using Spring.
Here is some of my code:
This is how I init my index page:
#RequestMapping(value="/index", method=RequestMethod.GET)
public ModelAndView initializeForm(ModelMap model){
ModelAndView result = new ModelAndView("index.jsp");
result.addObject("loginInfo", new LoginInfo());
return result;
}
This is what happen when submit the data from the movable app:
Here I wan when there is an error, to redirect to the same app without close it.
#RequestMapping(value="/welcome", method=RequestMethod.GET)
public String onSubmit(#ModelAttribute("loginInfo") #Valid LoginInfo logInfo,
BindingResult result, ModelMap model){
if(result.hasErrors()){
return "";//here I need to redirect to the movable app form.
}
return "redirect:login.htm";
}
Here is my jsp:
<form:form action="welcome" method="GET" id="mainLogForm" commandName="loginInfo">
<div id="loginForm" class="ui-widget-content" >
<table align="right" width="300" cellpadding="0">
<tr><td align="right"><input type="button" id="cancelButton" value="x" onclick="showHide('loginForm')"/></td></tr>
</table>
<table align="center" width="300" bgcolor="f8f8ff" border="1" cellspacing="0" cellpadding="5" >
<tr>
<td align="right" width="100">User:</td>
<td width="100"><form:input path="username" /></td>
<td width="100"><form:errors path="username" cssClass="error"/></td>
</tr>
<tr>
<td align="right" width="100">Password:</td>
<td width="100"><form:input path="password" type="password"/></td>
<td width="100"><form:errors path="password" cssClass="error"/></td>
</tr>
</table>
<br>
<input type="submit" id="logInButton" align="center" value="SignIn" onclick="submitForm()" />
</div>
</form:form>
Thanks in advice!

Related

Neither BindingResult nor plain target object for bean name 'user' available as request attribute error

I am new on spring. I am just trying to create my own CRUD OneToMany project. I have user and course table in my database. Course table has user_id foreign key references user(id).
When user successfully logged into the page, homePage.jsp comes and user courses are listed. When we click "Add Course" button in homePage.jsp, course-form.jsp file comes and we should add course.
The problem is, when I try to add course, I lost my user modelAttribute because in this time another attribute is on process with spring mvc.
When addedCourse form action performed these error occurs,
Cannot invoke "com.veg.entity.User.addCourse(com.veg.entity.Course)" because "user" is null
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
My Controller,
#PostMapping("/showFormForAdd")
public String showFormForAdd(#ModelAttribute("user") User theUser, Model theModel) {
Course theCourse = new Course();
theCourse.setUser(theUser);
theModel.addAttribute("course", theCourse);
theModel.addAttribute("user", theUser);
return "course-form";
}
#PostMapping("addedCourse")
public String addedCourse(#ModelAttribute("course") Course theCourse, Model theModel) {
User user = theCourse.getUser();
userService.save(user, theCourse);
theModel.addAttribute("user", user);
return "homePage";
}
homePage.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="showFormForAdd" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Add Course" class="add-course"/>
</form:form>
</span>
<table>
<tbody>
<tr>
<th>Course id</th>
<th>Course title</th>
</tr>
<c:forEach var="temp" items="${user.courses}">
<tr>
<td> ${temp.id} </td>
<td> ${temp.title} </td>
</tr>
</c:forEach>
</tbody>
</table>
course-form.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="loggedUser" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Back to Course List" class="add-course"/>
</form:form>
</span>
<!-- In the below I lost my user modelAttribute because I should use course attribute -->
<form:form action="addedCourse" modelAttribute="course" method="POST">
<table>
<tbody>
<tr>
<td> Title </td>
<td> <form:input path="title"/> </td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Course" class="add-course"/>
</td>
</tr>
</tbody>
</table>
</form:form>
I have #Transactional in my service, #Repository in my DAO and there is no problem with sessionFactory.

Spring: get input button id

I have this html template in thymeleaf.
<table id="listAllAccountantTable" th:cellspacing="0" class="table table-striped table-bordered" style="width:100%;">
<thead>
<tr>
<th>No. </th>
<th>Registered Date</th>
<th>Status</th>
<th>Name</th>
<th>Email</th>
<th>Contact No.</th>
<th>IC No.</th>
<th>IC attachment</th>
<th>Actions </th>
</tr>
<tr th:each="acc,iterationStatus : ${accountantListing}">
<td th:text="${iterationStatus.count}">1</td>
<td th:text="${acc.currentTimeStamp}"></td>
<td th:text="${acc.active}">1</td>
<td th:text="${acc.name}">Name</td>
<td th:text="${acc.email}">Email</td>
<td th:text="${acc.phoneNumber}">Contact No.</td>
<td th:text="${acc.icNumber}">IC No.</td>
<td th:text="${acc.id}"> To be fixed: upload IC image</td>
<td>
<form action="#" data-th-action="#{/accountantApplication}" method="post">
<button type="submit" name="action" th:id="${acc.id}"
value="Accept">Accept</button>
<button type="submit" name="action" th:id="${acc.id}"
value="Reject">Reject</button>
</form>
</td>
</tr>
My Spring controller is:
#RequestMapping(value="/accountantApplication", method=RequestMethod.POST, params="action=Accept")
public ModelAndView Accept() {
ModelAndView modelAndView = new ModelAndView();
System.out.println("######## Accepting accountant");
modelAndView.setViewName("AccountantListing");
return modelAndView;
}
#RequestMapping(value="/accountantApplication", method=RequestMethod.POST, params="action=Reject")
public ModelAndView Reject() {
ModelAndView modelAndView = new ModelAndView();
System.out.println("######## Rejecting accountant");
modelAndView.setViewName("AccountantListing");
return modelAndView;
}
The table shows a list of accountants.
All accountants are loaded from db and displayed on the table.
They need to be accepted or rejected.
When I click the accept button, Accept() is called.
How do I get the ID attached to button?
Or if there is better way of immplementing this. let me know too. Thanks so much
In your form, you should have a hidden input:
<form action="#" data-th-action="#{/accountantApplication}" method="post">
<input type="hidden" name="id" th:value="${acc.id}" />
<button type="submit" name="action" value="Accept">Accept</button>
<button type="submit" name="action" value="Reject">Reject</button>
</form>
Then, in your controllers:
public ModelAndView accept(#RequestParam String id) {
.
.
.
}
public ModelAndView Reject(#RequestParam String id) {
.
.
.
}
Also, as a side note, you can replace:
#RequestMapping(value="/accountantApplication", method=RequestMethod.POST, params="action=Accept")
#RequestMapping(value="/accountantApplication", method=RequestMethod.POST, params="action=Reject")
with
#PostMapping(value="/accountantApplication", params="action=Accept")
#PostMapping(value="/accountantApplication", params="action=Reject")

Pass id to the controller

Firstly, I am passing values from database to the table. In the first column I want to create a form that will pass the id to delete function in Controller.
<tr th:each="blg: ${all}" th:object="${blg}" >
<td>
<form th:action="#{/delete}" th:object= "${blg}" method="post">
<input type="text" th:field="${blg.id}"/>
<button type="submit">Delete</button>
</form>
</td>
<td th:text="*{title}"> title </td>
<td th:text="*{content}"> title </td>
<td th:text="*{category}"> title </td>
<td th:text="*{signature}"> title </td>
</tr>
Controller:
#GetMapping("/show")
public String show(Model model){
List<Blog> all = br.findAll();
model.addAttribute("all",all);
return "show";
}
#RequestMapping(value="/delete", method=RequestMethod.POST)
public String deletePost(#RequestParam Long id){
br.delete(id);
return "redirect:/show";
}
The thymeleaf engine doesn't map the object as this error occcurs:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'blg' available as request attribute.
What is the way to create a correct form in this case?
Update your html code as shown below:
<tr th:each="blg: ${all}" >
<td>
<form th:action="#{|/delete/${blg.id}|}" method="post">
<button type="submit">Delete</button>
</form>
</td>
<td th:text="${blg.title}"> title </td>
<td th:text="${blg.content}"> title </td>
<td th:text="${blg.category}"> title </td>
<td th:text="${blg.signature}"> title </td>
</tr>
Better to use HTTP method DELETE for delete operations.
The reason because th:object tried to look in your request attribute for the attribute blg. But blg is a result of an iteration.

Values for th:field attributes in checkbox

I have table with datas from database (insert dynamically). In one column I insert checkbox. Now I want to select one of them and send to next form (I select one product and send properties to another form. In this form should be displayed properties only the select product). But I don't know what kind of value insert in th:field="*{}". I tried many solutions but doesn't work. My html form with all products table:
<form action="/oferta/zamow" th:action="#{/oferta/zamow}"
th:object="${oferta}" method="post">
<table border="1" id="display-data">
<tr>
<td>#</td>
<td>title</td>
<td>author</td>
<td>rok</td>
<td>cena</td>
<td></td>
</tr>
<tr th:each="produkt, pozycja : ${oferta}">
<td th:text="${pozycja.count}"></td>
<td><span th:text="${produkt.tytul}"></span></td>
<td><span th:text="${produkt.autor}"></span></td>
<td><span th:text="${produkt.rok}"></span></td>
<td><span th:text="${produkt.cena}"></span></td>
<td>
<input type="submit" value="zamow"/>
<!-- <a th:href="#{/zamowienie}">zamow</a> -->
</td>
<td>
<label>zamow</label>
<input type="checkbox" th:field="*{produkt}" th:value="${produkt}"/>
</td>
</tr>
</table>
</form>
Form to display select product:
<form action="/zamowienie/zam" th:action="#{/zamowienie/zam}"
th:object="${zamowienie}" method="post">
<table border="1" id="display-data">
<tr align="center">
<td colspan="2">twoje zamowienie</td>
</tr>
<tr>
<td>tytul</td>
<td><span th:text="${produkt.tytul}"></span></td>
</tr>
<tr>
<td>autor</td>
<td><span th:text="${produkt.autor}"></span></td>
</tr>
<tr>
<td>rok</td>
<td><span th:text="${produkt.rok}"></span></td>
</tr>
<tr>
<td>cena</td>
<td><span th:text="${produkt.cena}"></span></td>
</tr>
<tr>
<td>data zlozenia zamowienia</td>
<td><span th:text="${datazam}"></span></td>
</tr>
</table>
</form>
Thanks for help.
I am not sure if this is the answer you seek, but you can find an example at http://www.thymeleaf.org/doc/html/Thymeleaf-Spring3.html#checkbox-fields.
Here is a simple example to illustrate how to use a checkbox in Thymeleaf with Spring MVC.
Controller:
#RequestMapping(value = "/showForm", method=RequestMethod.GET)
public String showForm(Model model) {
List<String> allItems = new ArrayList<String>();
allItems.add("value1");
allItems.add("value2");
allItems.add("value3");
model.addAttribute("allItems", allItems);
Foo foo = new Foo();
List<String> checkedItems = new ArrayList<String>();
// value1 will be checked by default.
checkedItems.add("value1");
foo.setCheckedItems(checkedItems);
model.addAttribute("foo", foo);
...
}
#RequestMapping(value = "/processForm", method=RequestMethod.POST)
public String processForm(#ModelAttribute(value="foo") Foo foo) {
// Get value of checked item.
List<String> checkedItems = foo.getCheckedItems();
...
}
html:
<form action="#" th:action="#{/processForm}" th:object="${foo}" method="post">
<div th:each="item : ${allItems}">
<input type="checkbox" th:field="*{checkedItems}" th:value="${item}" />
<label th:text="${item}">example</label>
</div>
<input type="submit" />
</form>
Foo.java:
public class Foo {
private List<String> checkedItems;
public List<String> getCheckedItems() {
return checkedItems;
}
public void setCheckedItems(List<String> checkedItems) {
this.checkedItems = checkedItems;
}
}
Hope this helps.
Take a look at the thymeleaf spring integration docs.
All th:field are mapped against the command object. Thats why you need the *{} expression.
One thing the template engine is not able to do (yet) is mapping fields inside a loop directly. So you cannot use the *{} approach to reference the produkt variable from the loop.
What you have to do is use the index of the th:each expression and build a property accessor with a pre-evaluated expression for the index.
<input type="checkbox" th:field="*{produkts[__${index}__].checked" />
You do not need the th:value, th:field is taking care of it. (Except if you want to superseed it)

How to display the similar information in every view?

I would like to display the information about user's registration state. It should be displayed on every view, but i consider, that writting this code for about 20 times is a bad idea. By the way, this is the code, it works, i guarantee that:
View/RegistrationInfo:
<table width="95%" border="0" cols="2">
<tr>
<td width="50%" height="124"><h2><strong>Simple Blog </strong></h2></td>
<td width="50%" height="124">
#if (System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account"))
{
<table width="95%" height="86" border="0">
<tr>
<td width="50%" valign="middle">Hello, #System.Web.HttpContext.Current.User.Identity.Name</td>
<td width="50%" valign="middle" align = "right"><input type="submit" value="Exit" /></td>
</tr>
</table>
}
}
else
{
using (Html.BeginForm("LogIn", "Home"))
{
<table width="95%" height="86" border="0">
<tr>
<td width="45%" valign="bottom">Login:</td>
<td width="45%" valign="bottom">Password:</td>
<td width="10%"></td>
</tr>
<tr>
<td width="45%">
<p>
<input type="text" name="login" />
</p>
</td>
<td width="45%">
<p>
<input type="password" name="password" />
</p>
</td>
<td width="10%" align="left">
<input type="submit" value="Enter" />
</td>
</tr>
<tr>
<td width="45%" valign="top">
#Html.ActionLink("Register", "Register", "Account")
</td>
</tr>
</table>
}
}
</td>
</tr>
</table>
<hr align="left" width="100%" size="2" />
As you can see, this view doesn't require to be strongly typed... and i don't know, should I modify any controllers (because, all information is stored in HTML Context), and how. I tried to call
#Html.RenderAction("RegistrationInfo", "Home");
or
#Html.RenderPartial("RegistrationInfo", "Home");
and every time i receive compile error with message about invalid parametres
While Darin's answer perfectly covers your question, I would point out that registration information seems like it's part of your layout more (master page for the .aspx-inclined) than an actual action.
So what I would do (and indeed, do do) is put it either in the header part of your layout in the top right or under your side menu or something, and let the layout handle all the details of rendering it (with a conditional around it to hide it when you're not logged in, so you don't see it on the login screen).
The following should work:
#Html.Partial("~/Views/Home/RegistrationInfo.cshtml")
Or if you are inside a view of the Home controller simply:
#Html.Partial("RegistrationInfo")
Or if you put this partial in ~/Views/Shared/RegistrationInfo.cshtml you will be able to reference with the shorthand syntax.

Resources