How to add javascript handler to button? - java

I have a button on my JSP form which must send a boolean value to the controller.
<button type="button" class="btn btn-success"><i class="glyphicon glyphicon-ok-circle"></i> Activate</button>
On the form I'm using POJO object which actually have a status (boolean status).
public class User implements Serializable {
private String name;
private boolean status;
// getters and setters omitted
}
I need to add javascript handler to the button to send this status and user id to the controller only with POST method. How can I do it using javascript?
UPD:
<c:forEach items="${users}" var="user">
<tr>
<td>${user.id}</td>
<td>${user.name}</td>
<td>${user.email}</td>
<td>${user.country}</td>
<td class="col-sm-1 col-md-1">
<a href="/user/${user.id}" style="text-decoration: none">
<button type="button" class="btn btn-primary btn-block"><i
class="glyphicon glyphicon-pencil"></i> Edit
</button>
</a>
</td>
<c:choose>
<c:when test="${user.active == true}">
<td class="col-sm-1 col-md-1">
<button type="button" class="btn btn-danger btn-block"><i
class="glyphicon glyphicon-remove"></i> Suspend
</button>
</td>
</c:when>
<c:otherwise>
<td class="col-sm-1 col-md-1">
<button type="button" class="btn btn-success"><i
class="glyphicon glyphicon-ok-circle"></i> Activate
</button>
</td>
</c:otherwise>
</c:choose>
</tr>
</c:forEach>

you can use as:
function doSend(){
document.forms[0].action = "url?val=true";
document.forms[0].submit();
}
and
<button type="button" onclick="doSend()" and other attrubute>
Specify a method attribute on your form.
<form name="myform" method="POST">
It will cause the form to be submitted as a POST.
Or You can do it using hidden field as:
<html>
<head>
<script type="text/javascript">
function doSend(){
alert("hi");
document.forms[0].setAttribute("method","POST");
document.forms[0].submit();
}
</script>
</head>
<body>
<form action="test2.html" method="GET">
<input type="hidden" name="hiddenField" value="ture1"/>
<input type="button" onclick="doSend()" value="click"/>
</form>
</body>
</html>

Use ajax for it..
function ajaxRequest(){
var activexmodes=["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
if (window.ActiveXObject){ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
for (var i=0; i<activexmodes.length; i++){
try{
return new ActiveXObject(activexmodes[i])
}
catch(e){
//suppress error
}
}
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
return new XMLHttpRequest()
else
return false
}
Following function you have to call on click event.
function callOnClick(usrid)
{
var mypostrequest=new ajaxRequest()
mypostrequest.onreadystatechange=function(){
if (mypostrequest.readyState==4){
if (mypostrequest.status==200 || window.location.href.indexOf("http")==-1){
//action todo after successful return
}
else{
alert("An error has occured making the request")
}
}
}
var status=encodeURIComponent(document.getElementById("status").value)// make a hidden field and set the status in value attribute
var userid=usrid//set this value as the attribute of javascript function
var parameters="status="+status+"&id="+userid
mypostrequest.open("POST", "name of controller or servlet", true)
mypostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
mypostrequest.send(parameters)
}

Related

Why is it that my form does not redirect me to the route im passing?

Im doing a CRUD app with Java using Servlets and i have a jsp file as a list of many users where i have a button to edit my row. As i click on my button it should redirect me to ServletPacientes?Param=editar&dni=<%a.getDni()%>.
So this is my ListarPacientes.jsp: Where i have some scriplets and my html forms.
<body>
<% if (request.getSession().getAttribute("usuario") == null) {
request.getRequestDispatcher("Login.jsp").forward(request, response);
throw new UsuarioNoLoggeadoException();
}
Usuario user = (Usuario)request.getSession().getAttribute("usuario");
if (user.getTipo_usuario().getID() != 1) {
request.getRequestDispatcher("Home.jsp").forward(request, response);
throw new UsuarioSinPermisoException();
}
%>
<%
if (request.getParameter("buscarLista") == null) {
request.getRequestDispatcher("ServletPacientes?Param=list").forward(request, response);
}
List<Paciente> listaM = new ArrayList<Paciente>();
if (request.getAttribute("listaPac") != null) {
listaM = (List<Paciente>)request.getAttribute("listaPac");
}
%>
<jsp:include page="Menu.jsp"></jsp:include>
<div class="table-title">
<h3>Tabla Pacientes</h3>
</div>
<form method="post" action="ServletPacientes">
<div class="form-group">
<label>Buscar: </label>
<input type="text" class="form-control" name="txtBuscar">
</div>
<div class="col-12">
<input type="submit" class="btn btn-success" value="Buscar" name="btnBuscar">
</div>
<table class="table-fill">
<thead>
<tr>
<th class="text-left">Nombre</th>
<th class="text-left">Apellido</th>
<th class="text-left">DNI</th>
<th class="text-left">Sexo</th>
<th class="text-left">Direccion</th>
<th class="text-left">Fecha de Nacimiento</th>
<th class="text-left">Email</th>
<th class="text-left">Telefono</th>
<th class="text-left">Nacionalidad</th>
</tr>
</thead>
<tbody class="table-hover">
<tr>
<%
for (Paciente a : listaM) {
%>
<tr>
<form action="ServletPacientes" method="post">
<td><%=a.getNombre()%></td>
<td><%=a.getApellido()%></td>
<td><%=a.getDni()%> <input type="hidden" name="dniPaciente" value="<%=a.getDni()%>" ></td>
<td><%=a.getSexo()%></td>
<td><%=a.getDireccion()%></td>
<td><%=a.getFechaNac()%></td>
<td><%=a.getCorreo()%></td>
<td><%=a.getTelefono()%></td>
<td><%=a.getNacionalidad()%></td>
<td> <input type="submit" name="btnEliminar" value="Eliminar" class="btn btn-danger"></td>
</form>
<td> <input type="submit" name="btnEditar" value="Editar" class="btn btn-warning"></td>
</tr>
<%
}
%>
</tbody>
</table>
<br>
<div align="center">
</div>
</form>
</body>
As you can see i have de following tags
<td> <input type="submit" name="btnEditar" value="Editar" class="btn btn-warning"></td>
So in each row i have this button where i call my Controller (Servlet) with the parameter "editar" and i pass the method getDni() of my class Paciente.
And here is my code of my ServletPacientes:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if(request.getParameter("Param")!=null)
{
String opcion = request.getParameter("Param").toString();
switch (opcion) {
case "previoInsert":
{
break;
}
case "list":
{
request.setAttribute("listaPac", negPac.listarPacientes());
RequestDispatcher dispatcher = request.getRequestDispatcher("/ListarPacientes.jsp?buscarLista=1");
dispatcher.forward(request, response);
break;
}
case "editar":
{
Paciente p = new Paciente();
p = negPac.obtenerUno(request.getParameter("dniPaciente"));
System.out.println(p);
request.setAttribute("dniPac", p);
RequestDispatcher dispatcher = request.getRequestDispatcher("/EditarPaciente.jsp");
dispatcher.forward(request, response);
break;
}
default:
break;
}
}
}
The method above shows a switch where each case is a different parameter that im passing to my route. So when i click on my edit button instead of taking me to for example ServletPacientes?Param=editar&dni=20216447 it just redirects me to ServletsPacientes which is a blank page.
It looks like im never receiving the parameter editar neither the dni property. Becaus if i manually put on my url ServletPacientes?Param=editar&dni=20216447 it does takes me to the Edit view.
You essentially have the following structure:
<form method="post" action="ServletPacientes">
<a href="ServletPacientes?Param=editar&dni=<%=a.getDni()%>">
<input type="submit" value="Editar">
</a>
</form>
This means that when you click on this "Editar" button, a form submission will happen as a POST request. This request is supposed to be processed by a doPost method on the servlet side, and the URL would be /ServletPacientes. This is why you navigate to /ServletPacientes. The link in the wrapping <a> element will have no effect.
If you expect to navigate to something like ServletPacientes?Param=editar&dni=20216447, you'll have to make the nested input element a regular button, not a submit: <input type="button" value="Editar">.

Thymeleaf: Update Table on Form Submit

I have a view in which I have a Form to create a new Exercise object, and a table to display all exercises. Now I want that the table automatically refreshes with the newly created exercise. Currently it displays the table as empty, until I manually go to localhost:8080/exercise again.
Here's my controller:
#Controller
public class ExerciseController {
#Autowired
private ExerciseService exerciseService;
#Autowired
private ModelMapper modelMapper;
#GetMapping("/exercise")
public String exerciseView(final Model model) {
List<Exercise> exerciseList = exerciseService.getAllExercises();
model.addAttribute("exerciseDTO", new ExerciseDTO());
model.addAttribute("title", "Create an Exercise");
model.addAttribute("exercises", exerciseList);
return "exercise";
}
#PostMapping("/exercise")
public String createExercise(#ModelAttribute final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
this.exerciseService.createExercise(exercise);
return "exercise";
}
}
And my thymeleaf template:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form action="#" th:action="#{/exercise}" th:object="${exerciseDTO}" method="post">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" th:field="*{bpm}" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Now I thought the createExercise method returning "exercise" would call the exerciseView method and thus calling exerciseService.getAllExercises(). Is there a way to achieve this functionality? Or is there an even better way, without reloading the whole page?
To serve up data without page refreshes you'd need a client side technology like Angular or React. Or plain old javascript. But you can't serve up new data to a page in spring mvc w/o page refreshes.
You can use AJAX to send requests from a client side to a server side and receive an answer without refreshing the page.
Unfortunately I don't have enough time and I can't complete the code but you can do something like this:
function submitItems() {
var contextPath = $("meta[name='ctx']").attr("content");
var exerciseDto = {};
exerciseDto.name = $("#name").val();
exerciseDto.description = $("#description").val();
exerciseDto.typeSelector = $("#typeSelector).val();
exerciseDto.bpmInput = $("#bpmInput").val();
$.ajax({
dataType : "json",
type : "post",
url : contextPath + "/exercise",
data : JSON.stringify(exerciseDto),
cache : false,
contentType : "application/json",
beforeSend : function(xhr) {
xhr.setRequestHeader(header, token);
},
success : function(data) {
console.log(data);
//HERE YOU NEED ACTION TO UPDATE TABLE.
},
error : function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
console.log('getJSON request failed! ' + textStatus);
}
});
}
and then your view must be like this:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form onsubmit="submitItems();return false;">
<p>Name: <input id="name" type="text" /></p>
<p>Description: <input id="description" type="text" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Bear in mind that you need to create an JS action that will update the table. There are quite a few ways of doing that (you can push new data to the Datatable or add new content using JS functions).
I hope this will help you understand a bit more how the AJAX works.
PS. You will have to update your controller as well to return the results, in your instance will be
#PostMapping("/exercise")
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
//this.exerciseService.createExercise(exercise);
//return "exercise";
return this.exerciseService.createExercise(exercise);
}
You will have to change this line
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
to your createExercise Domain Type.

How do i pass an object from jsp to controller with spring

I have a class User and a class Project wich has an arraylist with users.
I have a Project page with a list of all my projects and when i click on one, it takes me to the page of that project by sending the id of that project in the url.
On my detail project page i want to add users that i created.
The users are displayed on a modal in a table with a button to add them.
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title"></h4>
</div>
<div class="modal-body">
<h1 class="text-center">UserList</h1>
<br><br>
<table class="table table-hover">
<thead>
<tr>
<th>Photo</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Function</th>
<th>Email</th>
</tr>
</thead>
<tbody>
<c:forEach var="u" items="${users}">
<tr>
<td><img src="${u.getPhoto()}"
alt="Alternate Text" class="img-responsive" /></td>
<td>${u.getFirstname()}</td>
<td>${u.getLastname()}</td>
<td>${u.getFunction()}</td>
<td>${u.getEmail()}</td>
<td><Button type="Button" class="btn btn-default">Add</button></td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</div>
My question is how do i send the id of the user and the id of the project i want them to be added to my controller?
I know i can pass an id with the url but i dont want to open a new page.
I want to send the ID of the user and the project to my controller by clicking on the add button to my controller so i can use those in my method called addUserToProject()
JSP
First, make a hidden input with selected project id, so you can get it later:
<input type="hidden" id="currentProjectId" value="12">
Second, set attribute name of add buttons equal userId:
<td><Button type="Button" name="${u.getId()}" class="btn btn-default">Add</button></td>
Javascript:
Define onclick linstener for each "add button" and get the current user id from the button:
$(".btn").click(function(event) {
event.preventDefault();
var currentProjectId= $('#currentProjectId').val();
var userId = $(this).attr("name");
addUser(currentProjectId, userId);
});
Make ajax request and post the ids to controller:
function addUser(currentProjectId, selectedUserId) {
$.ajax({
type : "POST",
contentType : "application/json",
url : "/addUserToProject",
data :{ projectId: currentProjectId, userId: selectedUserId},
dataType : 'json',
timeout : 100000,
success : function(data) {
console.log("SUCCESS: ", data);
},
error : function(e) {
console.log("ERROR: ", e);
display(e);
},
done : function(e) {
console.log("DONE");
}
});
}
Finally, controller accepts ids using #RequestParam:
#RequestMapping(value = "/addUserToProject", method = RequestMethod.POST,produces = MediaType.APPLICATION_JSON_VALUE)
public #ResponseBody
String Submit(#RequestParam("projectId") Integer projectId ,#RequestParam("userId ") Integer userId ) {
//insert user
return "ok";
}
From a rendered page you only have two options either you do a normal form post or use Ajax if you dont want to open a new url.

Spring Form: My not null value becomes null after submitting the form

I am using
Hibernate
Spring
Apache Tiles
JSTL
I am putting filled value in my form
#RequestMapping(value = "/create")
public String createInsuranceType(Model model, HttpServletRequest request) {
InsuranceType insuranceType = new InsuranceType();
InsuranceCompany insuranceCompany = insuranceCompanyService
.getInsuranceCompanyById(Long.parseLong(request.getParameter("id")));
insuranceType.setInsuranceCompany(insuranceCompany);
model.addAttribute("insuranceType", insuranceType);
System.out.println(insuranceType);
return "insurancetype-create";
}
And this is my console output
InsuranceType [id=0, type=null, insuranceCompany=InsuranceCompany [id=1, fullName=full, shortName=short]]
And in my form in jsp file I would like to fill only type value, but i want my insuranceCompany stay like it is. My form:
<sf:form method="post"
action="${pageContext.request.contextPath}/insurancetype/create"
commandName="insuranceType" id="insuranceTypeForm" class="col s12">
<sf:hidden path="id" />
<div class="row">
<div class="input-field col s6">
<sf:input path="type" id="type" type="text" class="validate" />
<label for="type">Insurance Type</label>
</div>
</div>
<div class="row">
<div class="col s12">
<c:choose>
<c:when test="${insuranceType.id < 1}">
<a onclick="document.getElementById('insuranceTypeForm').submit()"
class="waves-effect waves-light btn"><i
class="material-icons right">save</i>Zapisz</a>
</c:when>
<c:otherwise>
<a onclick="document.getElementById('insuranceTypeForm').submit()"
class="waves-effect waves-light btn"><i
class="material-icons right">edit</i>Edytuj</a>
</c:otherwise>
</c:choose>
</div>
</div>
</sf:form>
And after submit my output looks like this:
InsuranceType [id=0, type=test value, insuranceCompany=null]
My POST controller
#RequestMapping(value = "/create", method = RequestMethod.POST)
public String insuranceTypeCreated(#ModelAttribute("insuranceType") InsuranceType insuranceType,
#RequestParam("id") long id) {
System.out.println(insuranceType);
insuranceTypeService.insertOrUpdateInsuranceType(insuranceType);
if (id < 1)
return "redirect:/insurancecompany/list";
else
return "redirect:/insurancetype/list";
}
I tried something like
<sf:hidden path="insuranceCompany" />
But it returns error
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.
Apache Tomcat/8.0.39
Try to use modelAttribute="insuranceType" in your sf:form tag.

how to get data from label or span and transfer it to a div, an other span or a label

this is my form with div :
<form action="" method="post">
<label name="meal" value="meal">
Soupe
</label>
<table border="0">
<tr>
<td><span id="prix" name="price" >price</span></td>
<td><input type="number" id="nbr" name="quantity" min="1" max="5"value="1">
<label>Number of persons</label>
</td>
<td><input type="button" id="somebutton" value="order"
onclick="getdata('somebutton','empty-basket-wrapper')" />
</td>
</tr>
<tr>
<td colspan="3">description of the meal ....</td>
</tr>
</table>
</form>
<div class="order">
<div class="panier">
<span class="Ib"></span>
<span class="oh">my shopping cart</span>
</div>
<div id="empty-basket-wrapper">
empty
</div>
</div>
I would like when I click on the button, the datas to be transferred from the the label or span like soupe and price and be displayed in the div id ="empty-basket-wrapper".
I guess my problem is how to get data from label or span and transfer it to div or an other span or label
this is my AJAX :
var _xhr;
var _target;
function getdata(sourceId,targetId){
_xhr= new XMLHttpRequest();
_xhr.onreadystatechange=callback;
_xhr.open("POST", url, true);
_xhr.send();
var px=document.getElementById("prix").name;
function callback() {
_target = document.getElementById(targetId);
_target.innerHTML=px//_xhr.responseText;
}
}
Thanks for your help !
You should consider using jQuery, then it would be like:
$(document).ready(function() {
$("#somebutton").click(function(e) {
e.preventDefault();
var form = $(e.target).closest("form");
var target = $(form).attr("action");
$.post(target, form.serialize(), function(result) {
// your POST Target could give you HTML for the cart contents
$("#empty-basket-wrapper").html(result);
// your AJAX endpoint could also give you a JSON, then you could use mustache to render.
});
});
});
If you just want to popup the values in the cart and not POST back to your server you don't need no AJAX ... not sure if you mean that. If so, it would be simpler:
$(document).ready(function() {
$("#somebutton").click(function(e) {
e.preventDefault();
var form = $(e.target).closest("form");
// for sure you should investigate something more sophisticated, see mustache
$("#empty-basket-wrapper").html(form.serialize());
});
});

Categories

Resources