Why is <c:forEach> not working with Ajax request in JSP Spring? - ajax

I am fetching some data with a Ajax request in my main JSP page.
Snippet of main.jsp
function gu(){
$.get('/admin/getAllUsers', {}, function(data) {
console.log(data); // see below
$("#allUsersData").html(data);
});
}
In my Spring controller I add all the users to a different JSP page.
Snippet of MainController.java
#RequestMapping(value = "/admin/getAllUsers", method = RequestMethod.GET)
public String getAllUsers(Model model){
List<User> users = userRepository.findAll();
System.out.println(users.size()); // output: 3
model.addAttribute("allUsers", users);
return "data/all-users";
}
Now in all-users.jsp I have a <c:forEach> which is supposed to load all users in a html table:
<table class="table">
<thead>
<tr>
<th>Firstname</th>
<th>Lastname</th>
<th>Email</th>
<th>Date</th>
</tr>
</thead>
<tbody>
<c:if test="${not empty allUsers}">
<c:forEach items="${allUsers}" var="usr">
<tr>
<td>${usr.firstName}</td>
<td>${usr.lastName}</td>
<td>${usr.username}</td>
<td>${usr.creationDate}</td>
</tr>
</c:forEach>
</c:if>
</tbody>
</table>
However, when I add the html coming from the request to my main JSP page, an empty table is shown. When I log the result of the Ajax request I find that the user data is inserted in the all-users.jsp:
<c:if test="true">
<c:forEach items="[User{id=1, username='username1', firstName='John', lastName='Doe', roles=[Role{id=1, name='ROLE_USER'}], creationDate=2018-02-19T08:58:13.333}, User{id=2, username='username2', firstName='John2', lastName='Doe2', roles=[Role{id=3, name='ROLE_USER'}], creationDate=2018-02-19T08:58:13.471}]" var="usr">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</c:forEach>
</c:if>
Why is it happening that the data is loaded into the data JSP page, but not shown when appending it to the main JSP page?

Can you check, maybe you haven't included the core tag library in your JSP file.
You will do this by inserting the following Line at the top of your file.
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

Related

findAll() in spring boot

When I try to select all details of my database, I don't get data s into a table structure in my jsp page. The array is printed in my jsp but don't know how to make it single objects.
Here is my mapping
#RequestMapping("/viewall")
public ModelAndView findAll(ModelAndView mav){
List<aswathyDTO>li= dao.findAll();
for (aswathyDTO aswathyDTO : li) {
System.out.println(li);
}
mav.addObject("li",li);
mav.setViewName("li");
return new ModelAndView("displayall.jsp","li",li);
}
and here is my jsp page
<body>
${li }
<table>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<c:forEach items="${li}" var="li">
<tr>
<td>${li.id}</td>
<td>${li.name}</td>
<td>${li.age}</td>
</tr>
</c:forEach>
</table>
</body>
Your JSP should look like this:
<body>
<table>
<tr>
<th>id</th>
<th>name</th>
<th>age</th>
<c:forEach items="${li}" var="element">
<tr>
<td>${element.id}</td>
<td>${element.name}</td>
<td>${element.age}</td>
</tr>
</c:forEach>
</table>
</body>
Also make sure that you import the standard library:
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>

Spring Boot And Thymeleaf remain on the same page on post request is made

I've created an web app that searches for online car ads and populates the page with a few tables after a post request.It looks like this:
After Search:
Every table element has a save button which should save those values to the database but my problem is that the page gets refreshed after submitting a post request. How can I do this without refreshing the page?
Table:
<form th:action="#{/saveAd}" method="POST">
<table class="table table-sm table-hover">
<thead class="thead-dark">
<tr>
<th>Imagine</th>
<th>Titlu Anunt</th>
<!-- <th style="width: 16.66%">Link</th> -->
<th>Pret</th>
<th>Oras</th>
</tr>
</thead>
<tbody id="myTable">
<th:block th:each="element : ${lista}">
<trth:onclick="'javascript:rowClicked(\'' + ${element.url} + '\');'">
<td><img th:src="#{${element.img}}" class="size" /></td>
<td th:text="${element.title}"></td>
<td th:text="${element.pret}"></td>
<td th:text="${element.oras}"></td>
<td><input class="btn btn-danger" type="submit"value="Save"></td>
</tr>
</th:block>
</tbody>
Controller:
#RequestMapping(path = "/saveAd", method = RequestMethod.POST)
public String saveAd(#ModelAttribute("adValue") AdValue adValue) {
System.out.println(adValue.getImg());
System.out.println(adValue.getLink());
System.out.println(adValue.getOras());
System.out.println(adValue.getPret());
System.out.println(adValue.getTitle());
return "home";
}
And also, how could I bind the list to a model object after pressing the save button?
I guess you may like this project. It is similar with what you need :
https://github.com/adinafometescu/tutorials/tree/master/spring-elasticsearch
You can use .bootstrapTable(). It a very method to update dynamically your table.
<table id="car-table" class="table table-striped">
<thead>
<tr>
<th data-field="id">Id</th>
<th data-field="title">Title</th>
<th data-field="price">Price</th>
<th data-field="city">City</th>
<th data-width="10" data-formatter="saveButtonFormatter"/>
</tr>
</thead>
</table>
The beauty is that it will map the data-field to a java object.
js stuff:
function saveButtonFormatter(value, row, index){
var adId = row.id;
return "<button class=\"btn btn-danger \" data-title=\"Save\"
data-toggle=\"modal\" onclick=\"saveAd(\'"+adId+"\')\"
</button>"
}
The function saveAd(adId) will call the rest endpoint and will update the bootstrap table on success.
I see that in your thymeleaf you don't have inputs. I suggest to not post your entire object if you don't need user input, just the id.
// anotate the controller class with #RestController
#Autowired
AdService adService;
#PostMapping(path = "/ad/{id}")
public ResponseEntity<?> saveAd(#PathVariable("id") String id) {
adService.saveAd(id);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
P.S : don't write code in Romanian :D

Table row data submit in struts 1.2

I have a table with each rows contain checkbox (Like gmail inbox). I want to select few checkboxes and submit data in one go to action class.
Please let me know how can i submit form using checkboxes.
First of all you must ensure that your form bean and your form action class are already working otherwise even if you prepare your jsp file you will not be able to check its correctness (Struts 1.2 drawback)
Here goes your jsp code
<%# taglib uri="http://jakarta.apache.org/struts/tags-html" prefix="html" %>
<html:html>
<html:form action="/formAction" method="GET">
<table>
<tr>
<td>Data 1</td>
<td>
<html:checkbox property="chk" value="value1"></html:checkbox>dln</td>
</tr>
<tr>
<td>Data 2</td>
<td>
<html:checkbox property="chk" value="value2"></html:checkbox>dln</td>
</tr>
<tr>
<td>Data 3</td>
<td>
<html:checkbox property="chk" value="value3"></html:checkbox>dln</td>
</tr>
<tr>
<td>Data 4</td>
<td>
<html:checkbox property="chk" value="value4"></html:checkbox>dln</td>
</tr>
<tr>
<td>
<html:submit value="Register"></html:submit>
</td>
</tr>
</table>
</html:form>
Form Bean
public class MyFormBean extends ActionForm {
private String chk;
[...]//other fields
public String getChk() {
return chk;
}
public void setChkString chk) {
this.chk= chk;
}
[....] // other getters and setters }
Action class's execute method
[...]
MyFormBean myForm = (MyFormBean) form;
String chkVal = myForm.getChk();
[...]
Form Bean Entry in struts-config.xml
[...]
<form-bean name="myBean" type="pkg.MyFormBean"/>
[...]
Form Action Entry in struts-config.xml
[...]
<action path="/formAction" type="pkg.formAction" name="myBean" scope="request">
[...]

how to get the element of a list inside jsp using JSTL?

I have such this code inside my Spring MVC java controller class:
#RequestMapping(value = "jobs", method = { RequestMethod.GET })
public String jobList(#PathVariable("username") String username, Model model) {
JobInfo[] jobInfo;
JobStatistics js;
LinkedList<JobStatistics> jobStats = new LinkedList<JobStatistics>();
try {
jobInfo = uiClient.getJobs(username);
for (int i = 0; i < jobInfo.length; i++) {
js = uiClient.getJobStatistics(jobInfo[i].getJobId());
jobStats.add(js);
}
model.addAttribute("jobs", jobInfo);
model.addAttribute("jobStats", jobStats);
}
which uiClient will get some data from database using RMI ...
now I want to show the jobs & related statistic inside my JSP file using JSTL :
<c:set var="stats" value="${jobStats}" />
<c:forEach var="jobs" items="${jobs}">
<c:set var="jobID" value="${jobs.JobId}"/>
<table>
<tr class="tr1">
<td>${jobs.Topic}</td>
<td>${stats.get(i).No}</td>
</tr>
</table>
</c:forEach>
How do I get the LinkedList elements of Model inside my JSP using JSTL? There might be no no counter i been put in scope for me.
In my opinion, the right answer is a combination of both of the answers you got:
use varStatus attribute of c:foreach tag
but:
"get" is not a jstl function.
<c:forEach var="jobs" items="${jobs}" varStatus="i">
<c:set var="jobID" value="${jobs.jobId}"/>
<table>
<tr class="tr1">
<td>${jobs.topic}</td>
<td>${stats[i.index].no}</td>
</tr>
</table>
</c:forEach>
EDIT: this is the code finally used by the author of the question:
<c:set var="stats" value="${jobStats}" />
<c:forEach items="${jobs}" varStatus="i">
<c:set var="jobID" value="${jobs[i.index].jobId}"/>
<table>
<tr class="tr1">
<td>${jobs[i.index].topic}</td>
<td>${stats[i.index].no}</td>
<td>${jobID}</td>
</tr>
</table>
</c:forEach>
get is not a jstl function.
<td>${stats[i.index].No}</td>
use varStatus attribute of c:foreach tag
<c:forEach var="jobs" items="${jobs}" varStatus="i">
<c:set var="jobID" value="${jobs.JobId}"/>
<table>
<tr class="tr1">
<td>${jobs.Topic}</td>
<td>${stats.get(i.index).No}</td>
</tr>
</table>
</c:forEach>

Dynamic Spring form action

I am trying to create a form in Spring MVC.
I would like to set action attribute of the <form> element dynamically using scriplet or something else.
MyForm:
<form:form id="myForm" modelAttribute="myFormBean"
action="<%=baseUrl%>/myFormControllerPattern" name="myForm">
<fieldset>
<table>
<tr>
<th>Name</th>
<td><form:input path="name" /></td>
</tr>
<tr>
<th>Age</th>
<td><form:input path="age"/></td>
</tr>
</table>
</fieldset>
</form:form>
Error:
attribute for %>" is not properly terminated
Found the solution. Thanks to jelies.
Added baseUrl in my controller like this:
model.setAttribute("baseUrl",url);
and then used it in my form in JSP:
<form action="${baseUrl}/myFormControllerPattern">
try to use javascript/jQuery trick:
var curl = document.location.pathname;
curl = curl.substring(0, curl.indexOf(".html"));
the first row will take your app address, then you cut the ".html" substring, thus enabling to add "/myFormControllerPattern" to the end of the string.
Change form action with javascript instead. Pass baseUrl as a model variable in your spring controller and use a javascript function like this to change form action:
function changeAction () {
var baseUrl = "${baseUrl}";
var form = document.getElementById("myForm");
form.action = baseUrl;
}
Hope it helps.
c:url tag can be usefull
include to jsp
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
and then
<form id="myForm" action="<c:url value="/myFormControllerPattern" />" name="myForm">

Resources