Can I use a jsp:include to include an entire JSP page as tab content? - html

I'm trying to define JSP pages as content for my tabs using the "jsp:include" - like this (Note: "page0.jsp")...
<ul id="smTabs" class="nav nav-tabs" style="margin-bottom: 15px;">
<li class="active">
Page0
</li>
-
-
-
<div id="smTabContent" class="tab-content">
<div class="tab-pane fade active in" id="page0">
<jsp:include page="page0.jsp" />
</div>
The problem:
When the user clicks on a tab, the "included" (i.e., "jsp:include") JSP page form fields are empty because the controller has not been initialized.
QUESTION:
What "href=" value will succeed in both revealing the tab contents (e.g., page0.jsp) and, as well, initialize the controller so the page is displayed properly with data?
Thanks for any help.
Here's what the empty form for page0.jsp looks like...
Here is what it should look like...
BELOW IS EXTRA INFORMATION IF INTERESTED...
Here is the tabbedPage.jsp
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%#taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%#taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%#taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<br/><br/><br/>
<div class="page-header"><h1>Tabbed Page Management</h1></div>
<div class="bs-component">
<ul id="smTabs" class="nav nav-tabs" style="margin-bottom: 15px;">
<li class="active">
Page0
</li>
<li>
Page1
</li>
<li>
Page2
</li>
</ul>
<div id="smTabContent" class="tab-content">
<div class="tab-pane fade active in" id="page0">
<h4>${page0FormBean}</h4>
<jsp:include page="page0.jsp" />
</div>
<div class="tab-pane fade" id="page1">
<h4>${page1FormBean}</h4>
<jsp:include page="page1.jsp" />
</div>
<div class="tab-pane fade" id="page2">
<h4>${page2FormBean}</h4>
<jsp:include page="page2.jsp" />
</div>
</div>
</div>
here is the controller for "tabbedPage.jsp"...: TabbedPageController.java
import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
#Controller
#Scope("session")
public class TabbedPageController
{
private static final Logger LOG = Logger.getLogger("TabbedPageController");
#RequestMapping(value = {"/tabbedPage"}, method = RequestMethod.GET)
public String tabbedPage(ModelMap model, HttpSession session)
{
LOG.info("_________________________tabbedPage_________________________entering...");
return "tabbedPage";
}
}
Here is page0.jsp (one of the JSP pages included...i.e., via "jsp:include")
<%#taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>
<%#taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%#taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%#taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<br/><br/><br/>
<div class='panel panel-primary'>
<div class='panel-heading'>
<h2 class='panel-title'>Page0</h2>
</div>
</div>
<form:form id="page0Form" modelAttribute="page0FormBean" method="post">
<div class="form-group row-fluid">
<label class='col-xs-6 control-label' for='formFieldA'>Page0's Form Field A</label>
<div class='col-xs-6'>
<input class='form-control' type='text' id='formFieldA' value='${page0FormBean.formFieldA}' />
</div>
</div>
<div class="form-group row-fluid">
<label class='col-xs-6 control-label' for='formFieldB'>Page0's Form Field B</label>
<div class='col-xs-6'>
<input class='form-control' type='text' id='formFieldB' value='${page0FormBean.formFieldB}' />
</div>
</div>
<div class="form-group row-fluid">
<label class='col-xs-6 control-label' for='formFieldC'>Page0's Form Field C</label>
<div class='col-xs-6'>
<input class='form-control' type='text' id='formFieldC' value='${page0FormBean.formFieldC}' />
</div>
</div>
</form:form>
here is the controller for "page0.jsp"...: Page0Controller.java
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.apache.log4j.Logger;
import java.io.Serializable;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
#Controller
#Scope("session")
public class Page0Controller implements Serializable
{
private static final Logger LOG = Logger.getLogger("Page0Controller");
private static final long serialVersionUID = 1602123387257827883L;
#RequestMapping(value = "/page0", method = RequestMethod.GET)
public ModelAndView page0(ModelMap model)
{
LOG.info("____________________page0___________________entering...");
Page0FormBean page0FormBean = new Page0FormBean("page0fieldavalue", "page0fieldbvalue", "page0fieldcvalue");
model.addAttribute("page0FormBean", page0FormBean);
return new ModelAndView("tabbedPage", "page0FormBean", page0FormBean);
}
}
here is the "form bean" used by "page0.jsp"...: Page0FormBean.java
public class Page0FormBean
{
private String formFieldA;
private String formFieldB;
private String formFieldC;
public Page0FormBean(String formFieldA, String formFieldB, String formFieldC)
{
this.formFieldA = formFieldA;
this.formFieldB = formFieldB;
this.formFieldC = formFieldC;
}
public String getFormFieldA()
{
return formFieldA;
}
public void setFormFieldA(String formFieldA)
{
this.formFieldA = formFieldA;
}
public String getFormFieldB()
{
return formFieldB;
}
public void setFormFieldB(String formFieldB)
{
this.formFieldB = formFieldB;
}
public String getFormFieldC()
{
return formFieldC;
}
public void setFormFieldC(String formFieldC)
{
this.formFieldC = formFieldC;
}
#Override
public String toString()
{
return "Page0FormBean{" + "formFieldA=" + formFieldA + ", formFieldB=" + formFieldB + ", formFieldC=" + formFieldC + '}';
}
}

I've arrived at a solution for now. - Hopefully, the Spring MVC mavens will chime in if they have a better approach
Essentially, I am using a session scope variable: "tabno". -I use "tabno" in the JSP page to control the active tab, etc. (Note: the use of a ternary expression in EL)
Instead of href=#page0, I am instead using href=page1 to invoke the page0.jsp's controller.
-Page0Controller then passes control to TabbedPageController, and page0.jsp is displayed as "tab content' in tabbedPage.jsp.
Works for now.
Thanks
The tab JSP code looks like this...
-
-
-
<div class="bs-component">
<ul id="smTabs" class="nav nav-tabs" style="margin-bottom: 15px;"> <%-- <%pageContext.forward("page1.jsp");%> --%>
<li class="${sessionScope.tabno==0?'active':''}" >
Page0
</li>
<li class="${sessionScope.tabno==1?'active':''}" >
Page1
</li>
<li class="${sessionScope.tabno==2?'active':''}" >
Page2
</li>
</ul>
<div id="smTabContent" class="tab-content">
<div class="${sessionScope.tabno==0?'tab-pane fade active in':'tab-pane fade'}" id="page0">
<jsp:include page="page0.jsp" />
</div>
<div class="${sessionScope.tabno==1?'tab-pane fade active in':'tab-pane fade'}" id="page1">
<jsp:include page="page1.jsp" />
</div>
<div class="${sessionScope.tabno==2?'tab-pane fade active in':'tab-pane fade'}" id="page2">
<jsp:include page="page2.jsp" />
</div>
</div>
</div>
-
-
-
Page0Controller.java (associated with page0.jsp) looks like this... (you can see where I set the "tabno" value in a session attribute)...
#Controller
#Scope("session")
public class Page0Controller implements Serializable
{
private static final Logger LOG = Logger.getLogger("Page0Controller");
private static final long serialVersionUID = 1602123387257827883L;
#RequestMapping(value = "/page0", method = RequestMethod.GET)
public ModelAndView page0(ModelMap model, HttpSession session)
{
Page0FormBean page0FormBean = new Page0FormBean("page0fieldavalue", "page0fieldbvalue", "page0fieldcvalue");
model.addAttribute("page0FormBean", page0FormBean); //<== setting the "modelAttribute" that's used in page.jsp...
session.setAttribute("tabno", "0"); //<== setting "tabno" value here...
return new ModelAndView("tabbedPage", "page0FormBean", page0FormBean);
}
}
TabbedPageController.java (associated with tabbedPage.jsp) looks like this...
#Controller
#Scope("session")
public class TabbedPageController implements Serializable
{
private static final Logger LOG = Logger.getLogger("TabbedPageController");
private static final long serialVersionUID = 6570072463879652843L;
#RequestMapping(value = {"/tabbedPage"}, method = RequestMethod.GET)
public String tabbedPage(ModelMap model, HttpSession session)
{
return "tabbedPage";
}
}

Related

razor-pages Delete functional doesn't work, how to delete?

I'm currently learning RazorPages in codeacademy.com.
I did everything that was shown in the video Tutorial, and unfortunately is doesn't work:
The task for the project:
"Data Delete
The current project has a button on the Index page list that deletes the current Continent or Country. The button will be modified to call a discrete Delete.cshtml page. This page will display the current record for review and provide a Delete button. Once the deletion occurs, the user is redirected back to the list so they get visual feedback of a successful task.
The code and markup are easily copied from the existing Detail.cshtml page. After copying that page, we add a delete button and copy the necessary statements from the OnPostAsync() method in the Index.cshtml.cs page."
The Delete page was created. The problem is:
When I press button Delete on the Delete page I have redirection to this link in browser:
https://localhost/Continents/Delete/SA?Continent.ID=SA
Actually no Delete happends
No redirection
What mistakes maybe here?
The code Delete.cshtml:
#page "{id}"
#model DeleteModel
#{
ViewData["Title"] = "Continent Delete";
}
<div class="jumbotron p-3">
<div class="d-flex align-items-center">
<h1 class="display-4 flex-grow-1">
Continent Delete
</h1>
<a class="btn btn-primary btn-sm" asp-page="./Index">
Back to List
</a>
</div>
</div>
[enter image description here](https://i.stack.imgur.com/tFnrX.jpg)
<div class="d-flex">
<div class="p-2 bg-primary text-white text-right" style="flex:0 0 15%">
#Html.DisplayNameFor(model => model.Continent.ID)
</div>
<div class="p-2 border-top border-right border-bottom border-primary" style="flex:1 0 auto">
#Html.DisplayFor(model => model.Continent.ID)
</div>
</div>
<div class="d-flex">
<div class="p-2 bg-primary text-white text-right" style="flex:0 0 15%">
#Html.DisplayNameFor(model => model.Continent.Name)
</div>
<div class="p-2 border-right border-bottom border-primary" style="flex:1 0 auto">
#Html.DisplayFor(model => model.Continent.Name)
</div>
</div>
<form metod="post" class="d-flex flex-row-reverse mt-3">
<input type="hidden" asp-for="Continent.ID"/>
<input type="submit" value="Delete" class="btn btn-danger btn-sm"/>
</form>
Delete.cshtml.cs:
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorCountry.Models;
using RazorCountry.Data;
namespace RazorCountry.Pages.Continents
{
public class DeleteModel : PageModel
{
private readonly CountryContext _context;
public DeleteModel(CountryContext context)
{
_context = context;
}
public Continent Continent { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
Continent = await _context.Continents
.Include(c => c.Countries)
.AsNoTracking()
.FirstOrDefaultAsync(m => m.ID == id);
if (Continent == null)
{
return NotFound();
}
return Page();
}
public async Task<IActionResult> OnPostAsync(string id)
{
if (id == null)
{
return NotFound();
}
// Find the continent
Continent Continent = await _context.Continents.FindAsync(id);
//Delete the continent
if (Continent != null)
{
_context.Continents.Remove(Continent);
}
//Persist Changes
await _context.SaveChangesAsync();
//Redirect to the user
return RedirectToPage("./Index");
}
}
}
Model Continent.cs:
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
namespace RazorCountry.Models
{
public class Continent
{
[Required, StringLength(2, MinimumLength = 2), Display(Name = "Code")]
[RegularExpression(#"[A-Z]+", ErrorMessage = "Only upper case characters are allowed.")]
public string ID { get; set; }
[Required]
public string Name { get; set; }
public ICollection<Country> Countries { get; set; }
}
}
Try to understand how RazorPages functional works, try to fix mistake in a correct way
The reason that no error occurs is because your OnPostAsync method is not being hit. You have mis-spelled the method attribute in your form (you have metod) so submitting it generates the default GET request and your OnGetAsync handler is executed instead.
Once you have corrected that error, you still have an unresolved issue.
Your OnPostAsync handler expects a parameter named id. The hidden field tag helper in your form generates a parameter with a name of Continent.ID. Consequently the value will not be bound to the id parameter. The simplest solution is to do away with the tag helper in the form a the bottom of your Delete page and replace it with a plain HTML input with a name attribute:
<form method="post" class="d-flex flex-row-reverse mt-3">
<input type="hidden" name="id" value="#Continent.ID"/>
<input type="submit" value="Delete" class="btn btn-danger btn-sm"/>
</form>
You can read more about model binding in general here: https://www.learnrazorpages.com/razor-pages/model-binding
Thanks to #MikeBrind finally, I changed the code
<form method="post" class="d-flex flex-row-reverse mt-3">
<input type="hidden" name="id" value="#Model.Continent.ID"/>
<input type="submit" value="Delete" class="btn btn-danger btn-sm"/>
</form>
And it works!

How to initialize an external reference in Thymeleaf?

If I had a Java class called for instance Buffet and one of its fields was something like:
#ManyToOne
private Chef chef
and I had to create a new Buffet object in an html form using Thymeleaf, how would I be able to refer to this chef field? At the moment my html looks like this:
<form th:action="#{/newBuffet}" method="POST" th:object="${buffet}">
<div>
<div>
<span><input type="text" th:field="*{name}" placeholder="name"/></span>
</div>
<div>
<span><input type="text" th:field="*{chef}" placeholder="chef"/></span>
</div>
<div>
<span><button type="submit">Invio<i class="material-icons">done</i></button></span>
</div>
</div>
</form>
and my controller like this:
#RequestMapping(value = "/newBuffet", method = RequestMethod.GET)
public String formBuffet (Model model) {
model.addAttribute("buffet", new Buffet());
return "newBuffet.html";
}
#RequestMapping(value = "/newBuffet", method = RequestMethod.POST)
public String addBuffet (#ModelAttribute("buffet") Buffet b, Model model) {
this.buffetService.save(b);
model.addAttribute("buffets", this.buffetService.listBuffets());
return "buffets.html";
}
the error it gives is, of course, because of the way Thymeleaf's input takes only strings whilst my input is an instance of my class Chef.

HTML Select option does not work after validation error in Thymeleaf SpringBoot

I have a form where a user can submit his team to the web application. He can select an option and enter his name. I have validated the name field that it cannot be blank. If the user leaves the name field blank and clicks "add", the page refreshes with the error name "enter name", but the selected option cannot be opened. User can not select option again and change it. It is not possible to move on.
Using java-Spring boot - Hibernate - thymeleaf
SubmitController
#GetMapping("/submit")
public String showForm (Model model) {
Submit submit = new Submit();
model.addAttribute("submit", submit);
List<String> rank = Arrays.asList("I", "II", "III", "IV", "V", "VI", "X" );
model.addAttribute("rank", rank);
return "submit_form";
}
#PostMapping("/submit")
public String submitForm (#Valid #ModelAttribute("submit") Submit submit, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "submit_form";
} else {
submitRepo.save(submit);
return "submit_ok";
}
}
Submit
#Entity
public class Submit {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank(message = "Please enter your team name")
private String name;
private String rank;
//...
submit_form.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Submit your team</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.4.1/css/all.css"
integrity="sha384-5sAR7xN1Nv6T6+dT2mhtzEpVJvfS3NScPQTrOxhwjIuvcA67KV2R5Jz6kr4abQsz" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" th:href="#{/css/index.css}"/>
</head>
<body>
<nav th:replace="index :: nav"></nav>
<div class="container my-5">
<div align="center"><h1>Submit your team here! </h1></div>
<div class="card">
<div class="card-body">
<div class="col-md-10">
<form action="#" th:action="#{/submit}" th:object="${submit}" method="post">
<div class="row">
<div class="form-group col-md-8">
<label for="name" class="col-form-label">Name of your team: </label>
<input type="text" th:field="*{name}" class="form-control" id="name">
<span th:if="${#fields.hasErrors('name')}" th:errors="*{name}" style="color: red">Name error</span>
</div>
<div class="form-group col-md-8">
<label for="rank" class="col-form-label">Select Team's rank: </label>
<select th:field="*{rank}" class="form-control" id="rank">
<option th:each="p : ${rank}" th:value="${p}" th:text="${p}"></option>
</select>
</div>
<div class="col-md-6">
<input type="submit" class="btn btn-primary" value="Add team">
</div>
<div class="form-group col-md-8"></div>
</div>
</form>
</div>
</div>
</div>
</div>
The problem is that rank is no longer in the model when you show the errors.
The solution is to add it again to the model:
#PostMapping("/submit")
public String submitForm (#Valid #ModelAttribute("submit") Submit submit, BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
List<String> rank = Arrays.asList("I", "II", "III", "IV", "V", "VI", "X" );
model.addAttribute("rank", rank);
return "submit_form";
} else {
submitRepo.save(submit);
return "submit_ok";
}
}
Side note:
It is best to use a GET-POST-REDIRECT flow with Thymeleaf. You are already doing the GET-POST part, but when the flow in the controller is ok, it is best to use a redirect:
#PostMapping("/submit")
public String submitForm (#Valid #ModelAttribute("submit") Submit submit, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
List<String> rank = Arrays.asList("I", "II", "III", "IV", "V", "VI", "X" );
model.addAttribute("rank", rank);
return "submit_form";
} else {
submitRepo.save(submit);
return "redirect:/submit";
}
}

How to Update a record in spring boot and mysql

I am a newbie to spring boot.I have created a crud operation and the insert operation is working properly. I have a challenge on the update operation , the program is giving an error on the web page
Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback.Wed Jul 22 20:39:03 CAT 2020 There was an unexpected error (type=Bad Request, status=400)
and the following error from the console
Resolved [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'long'; nested exception is java.lang.NumberFormatException: For input string: "saveEmployee"]
how can I solve the problem?
my code is below
Controller Class
```
package com.zimprogrammer.springboot.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import com.zimprogrammer.springboot.model.Employee;
import com.zimprogrammer.springboot.service.EmployeeService;
#Controller
public class EmployeeController {
#Autowired
private EmployeeService employeeService;
#GetMapping("/")
public String vieHomePage(Model model) {
// this shows a list of employees
model.addAttribute("listEmployees", employeeService.getAllEmployees());
return "index";
}
#GetMapping("/showEmployeeForm")
public String showEmployeeForm(Model model){
//request for the form to enter the data
Employee employee =new Employee();
model.addAttribute("employee", employee);
return "new_employee";
}
#PostMapping("/saveEmployee")
public String saveEmployee(#ModelAttribute("employee") Employee employee) {
//save data to the database
employeeService.saveEmployee(employee);
return "redirect:/";
}
#GetMapping("/showFormForUpdate/{id}")
public String showFormForUpdate(#PathVariable( value="id") long id, Model model) {
//get the employee from the service
Employee employee =employeeService.getEmployeeById(id);
// set the employee to pre-populate the form
model.addAttribute("employee", employee);
return "update_employee";
}
}```
Employee Service Interface
```package com.zimprogrammer.springboot.service;
import java.util.List;
import com.zimprogrammer.springboot.model.Employee;
public interface EmployeeService {
List<Employee> getAllEmployees();
void saveEmployee(Employee employee);
Employee getEmployeeById(long id);
}
```
Employee Service Class
```
package com.zimprogrammer.springboot.service;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zimprogrammer.springboot.model.Employee;
import com.zimprogrammer.springboot.repository.EmployeeRepository;
#Service
public class EmployeeServiceImpl implements EmployeeService{
#Autowired
private EmployeeRepository employeeRepository;
#Override
public List<Employee> getAllEmployees() {
return employeeRepository.findAll();
}
#Override
public void saveEmployee(Employee employee) {
this.employeeRepository.save(employee);
}
#Override
public Employee getEmployeeById(long id) {
Optional<Employee> optional=employeeRepository.findById(id);
Employee employee=null;
if(optional.isPresent()) {
employee=optional.get();
}else {
throw new RuntimeException("User not found for id::" + id);
}
return employee;
}
}
```
Employee Repository Interface
```
package com.zimprogrammer.springboot.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.zimprogrammer.springboot.model.Employee;
#Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long>{
}
```
Update Form : Thymeleaf and bootstrap
```
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>Employee Management System</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container" style="width:40%; height:40%;">
<h1>Employee Management system</h1>
<hr>
<h2>Update Employee</h2>
<form action="#" th:action="#{saveEmployee}" th:object="${employee}"
method="POST">
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{firstName}"
class="form-control mb-4 col-4">
<input type="text" th:field="*{lastName}"
class="form-control mb-4 col-4">
<input type="text" th:field="*{email}"
class="form-control mb-4 col-4">
<button type="submit" class="btn btn-info col-2">Update
Employee</button>
</form>
<hr>
<a th:href = "#{/}"> Back to Employee List</a>
</div>
</body>
</html>
```
Can you also post you entity class?
From the error it is telling that the required type is long but it is getting it as string? It may be possible that you have mentioned your id as string instead of long.
Also try to add th:action="#{/saveEmployee}" to be exact as that of your /saveEmployee endpoint
Add "/" in form th:action, like so -> th:action="#{/saveEmployee}"
Also check your crud repository, insted of long use Long.
I solved the problem
I added a / to make th:action="#{/saveEmployee}" and changed long to Long in my controller Class in the following request
#GetMapping("/showFormForUpdate/{id}")
public String showFormForUpdate(#PathVariable( value="id") Long id, Model model) {
//get the employee from the service
Employee employee =employeeService.getEmployeeById(id);
// set the employee to pre-populate the form
model.addAttribute("employee", employee);
return "update_employee";
}
and this solved the problem

Select tag always returns null

I am trying to create a search module to search shop details from database based on the criteria in select that user chooses
index.scala.html
#import helper._
#import helper.twitterBootstrap._
#main(Html("Home")) {
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Shop Directory</h1>
<p>Lets you search a nearby Shop and get to know their location</p>
<p>Search Shop by Product or Shop name</p>
<form class="form-inline" action="#routes.SearchController.search()" method="post">
<input type="text" class="form-inline input-lg" placeholder="Product/Shop name" name="keyword" required="keyword required">
<select class="form-inline input-lg" id="Select1" name="criteria">
<option value="">-:Select Criteria:- </option>
<option value="shop">Shop</option>
<option value="product">Product</option>
</select>
<button class="btn btn-lg btn-primary" role="button">Search</button>
</form>
</div>
}
Search.java
package viewmodels;
public class Search {
public String keyword;
public String criteria;
}
SearchResult.java
package viewmodels;
import models.Shop;
import play.mvc.Controller;
import java.util.ArrayList;
import java.util.List;
public class SearchResult extends Controller {
public String criteria;
public String keyword;
public List<Shop> shops;
public SearchResult() {
shops = new ArrayList();
}
}
SearchController.java
package controllers;
import models.Product;
import models.Shop;
import play.data.DynamicForm;
import play.data.Form;
import play.mvc.Controller;
import viewmodels.Search;
import viewmodels.SearchResult;
import java.util.List;
import play.mvc.Result;
import static play.data.Form.*;
public class SearchController extends Controller {
public static Result search() {
Form<Search> requestData = form(Search.class).bindFromRequest();
Search datatosearch = requestData.get();
// String criteria="shop";
String criteria = datatosearch.criteria;
SearchResult result = new SearchResult();
result.criteria = criteria;
result.keyword = datatosearch.keyword;
if (criteria == "shop") {
List<Shop> shops = Shop.findByShopName(datatosearch.keyword);
result.shops.addAll(shops);
}
else if (criteria == "product") {
List<Shop> shops = Product.findByShopName(datatosearch.keyword);
result.shops.addAll(shops);
}
return ok(views.html.search.results.render(result));
}
}
if I do String criteria="shop" or String criteria="product" in my SearchController.java then it works fine, meaning my model query is correct, but if I execute the above code with String criteria = datatosearch.criteria it shows a blank screen.
I am using play framework, I am really stuck at this and any help would be appreciated.
You are comparing strings with the == operator which is a no-no. Change your string comparisons to use String.equals so you are actually comparing the values instead of object references.
if (criteria.equals("shop") {
...
}
else if (criteria.equals("product") {
...
}
You probably also want to add some validation to check that criteria isn't NULL.