Hi I am wondering how to create dynamic drop down lists that get refined after the selection of a value in another drop down list.
For example, if I have two drop down lists Customer Name and Customer Country and I select a certain Customer Name, I only want to see the corresponding Customer Countries.
Using a query:
public List<Customer> getAllCustomerCountries(customerName) {
return this.sessionFactory
.getCurrentSession()
.createQuery(
"select distinct customerCountry from Customer where
customerName=:name").setParameter("name", customerName)
.list();
}
I can get the corresponding Countries but how do I pass on the input value customerName when it is selected in its own drop down list?
here is the code I'm using for the customerName drop down list:
<tr>
<td>Customer Name</td>
<td><form:select path="customerName">
<form:option value="" label="--- Select ---" />
<form:options items="${customerNameList}" />
</form:select>
</td>
<td><form:errors path="customerName" cssClass="error" /></td>
</tr>
In the controller the lists are populated by:
model.addAttribute("customerNameList",
customerService.listAllCustomerNames());
model.addAttribute("customerCountryList",
customerService.listAllCustomerCountries());
Thank you for your help!
/D
Update
Ok, so I have now used JavaScript to submit the page when a CustomerName is chosen so that a refined list list is loaded for the CustomerCountry drop down box.
Here is part of the jsp including the script:
<script>
function repopulate(){
document.getElementById("hasId").value ="true";
alert("You selected : " + document.getElementById("hasId").value);
document.deliveryForm.submit();
}
</script>
<!-- ... -->
<tr>
<td><form:hidden id="hasId" path="hasCustomerName" value="false"/></td>
</tr>
<tr>
<td>Customer Name</td>
<td><form:select path="customerName" onChange="repopulate()">
<form:option value="" label="--- Select ---" />
<form:options items="${customerNameList}" />
</form:select>
</td>
<td><form:errors path="customerName" cssClass="error" /></td>
</tr>
And here is part of the controller:
#RequestMapping(value = "/add", method = RequestMethod.GET)
public String getDelivery(ModelMap model) {
DeliveryDto deliveryDto = new DeliveryDto();
model.addAttribute("deliveryDtoAttribute", deliveryDto)
model.addAttribute("customerNameList",
customerService.listAllCustomerNames());
model.addAttribute("customerCountryList", null);
return "new-delivery";
}
#RequestMapping(value = "/add", method = RequestMethod.POST)
public String postDelivery(
#ModelAttribute("deliveryDtoAttribute") #Valid DeliveryDto deliveryDto,
BindingResult result, ModelMap model) {
if (deliveryDto.getHasCustomerName() == "true"){
model.addAttribute("deliveryDtoAttribute", deliveryDto);
model.addAttribute("customerNameList",
customerService.listAllCustomerNames());
model.addAttribute("customerCountryList",
customerService.listAllCustomerCountries(deliveryDto.getCustomerName()));
return "new-delivery";
}
if (result.hasErrors()) {
model.addAttribute("deliveryDtoAttribute", deliveryDto);
model.addAttribute("customerTargetIdList",
customerService.listAllCustomerTargetIds());
model.addAttribute("customerNameList",
customerService.listAllCustomerNames());
model.addAttribute("customerCountryList",
customerService.listAllCustomerCountries(deliveryDto.getCustomerName()));
}
Delivery delivery = new Delivery();
/* A bunch of setters and to set the values in the delivery object that will be saved */
deliveryService.createDelivery(delivery);
return "redirect:/home";
}
The problem I'm having is that the post method doesn't stop after the first if-loop and checks for errors and then tries to save the delivery as soon as i select a value in the CustomerName drop down box.
Does anyone know how I can make it so that it only continues on to check for errors (2nd if-loop) and save the delivery when I hit the submit button in the jsp page?
You must add a JavaScript event listener to the select box, which will do one of the following:
submit the form (after modifying its action attribute), in order for the controller to redisplay the same page but with a different set of countries
send an AJAX request to the controller with the customer name, and dynamically populate the select box with the set of countries contained in the response. The response could be a JSON array of countries, or an HTML snippet containing the new options of the select box, for example.
Related
In workers.jsp I have:
....
<form action="/workers" id="personForm" method="post" >
<c:forEach items="${page.content}" var="row" varStatus="status">
<tr>
<td><input type="checkbox"/></td>
<td>${row.name}</td>
...
<td>
<input type='image' src='/pages/img/del.png' />
<input type='hidden' name="removeid" value='${row.id}'/>
</td>
</tr>
</c:forEach>
</form>
When I click on input, ${row.id} goes to:
#RequestMapping(value = "/workers", method = RequestMethod.POST)
public ModelAndView getAllByPage(#ModelAttribute("removeid") Long removeid, Model uiModel, Pageable pageable) {
if(removeid!=null) {
userService.remove(removeid);
}
...
}
But removeid in this case is always the first, that was added to the jsp page.
Besides that, how to get the array of ids, using jsp to remove many items?
Help me, please.
You can write 1 separate REST end point for deleting multiple items.
Example:
public List<Long> deleteMultiple(List<Long> toBeDeleted){
deleteService(toBeDeleted);
return toBeDeleted;
}
You can call this End point via AJAX with multiple ides & refresh your page.
I am trying to create a table that displays a list of all logs that have been added. In addition to displaying the info I wanted to have another column of checkboxes that when clicked would allow me to delete them with the corresponding delete button.
The issue that I am having is that I am unable to put the values from my checkboxes into the array of Longs. I also want to keep the functionality of my table as it displays correctly.
For my table I have the following code:
<form method="post" th:action="#{/projects/log/delete/}" th:object="${deleteForm}">
<div th:each="log : ${allLogs}" class="row">
<tbody>
<tr class="active">
<td>
<input type="checkbox" th:field="*{logIds}" th:value="${log.id}" />
</td>
<td th:text="${log.teamUsed}"></td>
<td th:text="${log.opponentStarters}"></td>
<td th:text="${log.opponentOthers}"></td>
<td th:text="${log.myStarters}"></td>
<td th:text="${log.myOthers}"></td>
<td th:text="${log.result}"></td>
</tr>
</tbody>
</div>
<button type="submit" id="deleteButton" class="hidden"></button>
</form>
The form that I am trying to place the checkbox values into is: (log.id is a long)
public class LogDeleteForm {
private List<Long> logIds = new ArrayList<>();
public List<Long> getLogIds() {
return logIds;
}
public void setLogIds(List<Long> logIds) {
this.logIds = logIds;
}
}
In my controller I have the following setup for my view:
#RequestMapping(value = "pokemon_log", method = RequestMethod.GET)
public String view(Model model) {
model.addAttribute("addForm", new logForm());
model.addAttribute("deleteForm", new logDeleteForm());
model.addAttribute("allLogs", logService.getAllLogs());
return "log";
}
I am able to implement the deletion fine I am just unable to get the Ids that I would like to delete. How can I get the checkbox values placed into the list of longs?
Turns out that my issue was in my deleteLogs method:
#RequestMapping(value = "/log/delete", method = RequestMethod.POST, params = "delete")
public String deleteLogs(#ModelAttribute("deleteForm") logDeleteForm deleteForm) {
List<Long> formIds = deleteForm.getLogIds();
if (formIds == null || formIds.size() == 0) {
return "redirect:/projects/log";
}
for (Long id : formIds) {
logService.deleteLog(id);
}
return "redirect:/projects/log";
}
My redirects were both "redirect:/log" instead of "redirect:/projects/log"
Also my button was missing name="delete" because it was unable to qualify as a submit with a delete param.
In my Controller I have
#RequestMapping(value="/getCounties", method = {RequestMethod.GET},produces=MediaType.Application_JSON_VALUE)
public #Responcebody List<Counties>(#RequestParam String province){
List<Counties> county = this.xService.getCounties(county);
return county;
}
This method send the province chosen in the form down to the repository and join on the counties within that province.
In my dropdown on the form how do I return these values into the dropdown.
I currently have
<tr>
<td>
<form:select path="cdGcd" class="textbox" onclick="getCounty()">
<form:option value="-" label="Please Select"/>
<form:options path="county" items='${county}' itemValue = "countycode" itemLabel="countydescription"/>
</form:select>
</td>
</tr>
You can not return List directly form controller.
For passing data from controller to JSP you need to add data in Model and return respective JSP page.
So you need to change your method to,
#RequestMapping(value="/getCounties", method = {RequestMethod.GET})
public String getCountries(#RequestParam String province, Model model){
List<Counties> county = this.xService.getCounties(county);
model.addAttribute("county",county);
return "jsp page";
}
If you want to achieve this using AJAX then,you need to return JsonObject from controller.
I am trying to create a way of filtering data that is stored within the datastore. The method I am using for this is a mixture of HTML, Javascript and Java Servlets. A form is made that allows data that is input into the Web Application to be sent to the Java Servlet. The Servlet then does the required actions and sends the user back to the page with the updated data. My problem is I have to use a SelectBox within this form that allows the user to select the atribute they wish to filter by, e.g. title, author. When the submit button is pressed, the value of the SelectBox is not sent as a parameter. This means a ERROR 500 appears as there isn't enough parameters to perform the function. I need to:-
Get the value of the SelectBox.
Pass it to the function with the parameter value in a text field. (Almost Completed)
Set the value of idvBook to equal the List that is sent back to the Webb Application.
Firstly, this is how I am creating the form with the SelectBox, TextInput and ButonInput:-
<div class="headline">Filter the DataStore</div>
<div class="info">To view individual records, select the attribute
you'd like to filter by and enter the value you'd like to find. Click
the button to generate the table based on your search criteria.</div>
<script type="text/javascript">
function filter(){
document.filterBooks.action="/get";
var idvBook = document.filterBooks.submit();
}
</script>
<form name="filterBooks">
<table>
<tr>
<td valign="top"><label for="attribute">Attribute</label></td>
<td>
<select id="attributeSelect">
<option value="void">Select Attribute</option>
<option value="id">ID</option>
<option value="title">Title</option>
<option value="author">Author</option>
<option value="publisher">Publisher</option>
</select>
</td>
</tr>
<tr>
<td valign="top"><label for="value">Value</label></td>
<td><input type="text" name="value" id="value"></input></td>
</tr>
<tr>
<td colspan="2" align="right"><input type="submit" value="Filter" onclick="filter()"></td>
</tr>
</table>
</form>
<table>
<tr>
<th>Book ID</th>
<th>Title</th>
<th>Description</th>
<th>Author</th>
<th>Publisher</th>
<th>Publish Date</th>
<th>Remove Book</th>
</tr>
<%
for (Book book : idvBook) {
%>
<tr>
<td><%=book.getId()%></td>
<td><%=book.getTitle()%></td>
<td><%=book.getDescription()%></td>
<td><%=book.getAuthor()%></td>
<td><%=book.getPublisher()%></td>
<td><%=book.getPublishDate()%></td>
<td><a class="done" href="/done?id=<%=book.getId()%>">Remove</a></td>
</tr>
<%
}
%>
</table>
</div>
Once this has been made, it is then placed in the HTML table located below the form (shown in the code above).
This sends the parameters to this servlet:-
public class ServletGetBooks extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse resp) throws IOException
{
resp.setContentType("text/plain");
resp.getWriter().println("Hello, world");
String attribute = request.getParameter("attributeSelect").toString();
String param = request.getParameter("value");
Dao.INSTANCE.getBooks(attribute, param);
resp.sendRedirect("/TodoApplication.jsp");
}
}
You can see another function is ran here. This function looks like this:-
public List<Book> getBooks(String attribute, String param) {
EntityManager em = EMFService.get().createEntityManager();
Query q = null;
if(attribute.equals("id"))
{
q = em.createQuery("select b from Book b where b.id = :id");
q.setParameter("id", param);
}
else if(attribute.equals("title"))
{
q = em.createQuery("select b from Book b where b.title = :title");
q.setParameter("title", param);
}
else if(attribute.equals("author"))
{
q = em.createQuery("select b from Book b where b.author = :author");
q.setParameter("author", param);
}
else if(attribute.equals("publisher"))
{
q = em.createQuery("select b from Book b where b.publisher = :publisher");
q.setParameter("publisher", param);
}
List<Book> books = q.getResultList();
return books;
}
How can i get it so that i can get the value of the SelectBox, run the function and set the result of this to equal idvBook?
EDIT-------------------------------------------------------------------------------------------------
I'll simplify things. I need this within <% ... %> tags:-
List<Book> idvBook = new ArrayList<Book>();
idvBook = dao.getBook("Value in SelectBox","Value in TextInput");
Your select box does not have a name attribute and its value is thus not sent with the form data.
Generating a Jasper report depending on the user selected values from drop down (have two drop downs).
JSP:
<form:form name="f" action="${flowExecutionUrl}" modelAttribute="simpleReportSelector">
<table class="search">
<tr><th colspan="3"><fmt:message key="report.someextract"/></th></tr>
<tr>
<td><b><fmt:message key="somereport.sortdate"/></b>
<select id="firstfield" name="localDate" onchange="this.form.reloadPage.value='true';submit()">
<c:forEach var="dl" items="${dateList}">
<c:if test="${dl.selected==false}">
<option value="${dl.itemValue}">${dl.itemLabel}</option>
</c:if>
<c:if test="${dl.selected==true}">
<option selected="selected" value="${dl.itemValue}">${dl.itemLabel}</option>
</c:if>
</c:forEach>
</select>
</td>
<td><input type="hidden" id="reloadPage" name="reloadPage" value=""/></td>
<td><b><fmt:message key="somereport.equipNumber"/></b>
<select id="uld" name="uldNumber">
<c:forEach var="u" items="${uldList}">
<option value="${u.itemValue}">${u.itemLabel}</option>
</c:forEach>
</select>
</td>
</tr>
<tr><td class="right" colspan="3"><button type="submit" name="_eventId_exportReport">Submit</button></td></tr>
<tr class="hide">
<td><input id="submithidden" type="submit" value="submithidden" name="_eventId_submitButton" /></td>
</tr>
</table>
</form:form>
When user selects this particular menu from header, page populates with datelist and uldlist. datelist will be defaulted to today date and uldlist with 'select'. When user selects a previous date or future date, uldlist supposed to populate with different list.
controller:
#Controller
#RequestMapping("/uldReport.do")
public class ULDReport {
#Transactional(readOnly=true)
#RequestMapping(value="/uldReport.do",method = RequestMethod.GET)
public String setupForm(Model model, HttpServletRequest request, HttpServletResponse response) {
//code to populate datelist and uld list(populates using present day)
}
#Transactional(readOnly=true)
#RequestMapping(params={"reloadPage='true'"}, value="/uldReport.do", method = RequestMethod.GET)
public String setUpUld(Model model, HttpServletRequest request, HttpServletResponse response) {
//this should populate the uld list by using the date seelcted by user
}
#Transactional(readOnly=true)
#RequestMapping(params={"reloadPage='false'"}, method = RequestMethod.POST)
public ModelAndView processSubmit(#ModelAttribute SimpleReportSelector simpleReportSelector, Model model, HttpServletRequest request, HttpServletResponse response) throws IOException{
//some code
}
}
First method works good, but when I change the date, app directs to an error page. I think may be something with #RequestMapping, if I remove params from second and third method in controller, app submits with processandsubmit. What am I doing wrong?
This could be happening because of the way the URL is constructed. The fact that the page is loading a blank page means that it can't find anything that matches the criteria you have set up, and so it's silently failing.
For it to work as you expect, chances are you need to have the url formatted something like this:
/uldReport.do?reloadPage=true
or
/uldReport.do/reloadPage/true
depending on your setup.
But the point is that it needs to be in the URL and not a submitted field in your form, which it seems like it is right now.