Thymeleaf iterate through a nested list to create table <th> title and the <td> text for golf app - java

Hi Im relatively new with Spring and Thymeleaf but I am creating a disc golf CRUD app and I'm able to add a course with a Course object which has a oneToMany relation to ParList. All works fine I can add a course but a course doesnt always have 18 holes. How can I show this dynamically so a 9 hole courses table has 9 columns, a 14 - 14 columns etc?
I have tried using th:each="par, iterStat : ${course.parLists}" and trying to use iterStat.index but I can't quite get it.
So how can I get the index of the list and use it in the hole number and display the courses par without repeating like I have below?
So my data looks like this:
Course{id=3, name='Legende Main', parLists=[ParList{parListId=10, parHole1='3', parHole2='3', parHole3='3', parHole4='3', parHole5='3', parHole6='3', parHole7='3', parHole8='3', parHole9='3', parHole10='', parHole11='', parHole12='', parHole13='', parHole14='', parHole15='', parHole16='', parHole17='', parHole18=''}]}
My HTML
<div class="container" th:each="course : ${courses}">
<div class="border">
<div id="courseDetails" class="row">
<div class="col-sm-4">
<p><strong>Course Name:</strong>
<a th:text="${course.name}"></a>
</p>
</div>
</div>
</div>
<div >
<table th:each="par, index : ${course.parLists}" id="courseInfo" class="table table-bordered w-auto">
<tr >
<th th:text="${'Hole'}"></th>
<th th:text="${}"></th>
<th th:text="${'#2'}"></th>
<th th:text="${'#3'}"></th>
<th th:text="${'#4'}"></th>
<th th:text="${'#5'}"></th>
<th th:text="${'#6'}"></th>
<th th:text="${'#7'}"></th>
<th th:text="${'#8'}"></th>
<th th:text="${'#9'}"></th>
<th th:text="${'#10'}"></th>
<th th:text="${'#11'}"></th>
<th th:text="${'#12'}"></th>
<th th:text="${'#13'}"></th>
<th th:text="${'#14'}"></th>
<th th:text="${'#15'}"></th>
<th th:text="${'#16'}"></th>
<th th:text="${'#17'}"></th>
<th th:text="${'#18'}"></th>
<th>Actions</th>
</tr>
<tr>
<td th:text="${'Par'}"></td>
<td th:text="${par.parHole1}"></td>
<td th:text="${par.parHole2}"></td>
<td th:text="${par.parHole3}"></td>
<td th:text="${par.parHole4}"></td>
<td th:text="${par.parHole5}"></td>
<td th:text="${par.parHole6}"></td>
<td th:text="${par.parHole7}"></td>
<td th:text="${par.parHole8}"></td>
<td th:text="${par.parHole9}"></td>
<td th:text="${par.parHole10}"></td>
<td th:text="${par.parHole11}"></td>
<td th:text="${par.parHole12}"></td>
<td th:text="${par.parHole13}"></td>
<td th:text="${par.parHole14}"></td>
<td th:text="${par.parHole15}"></td>
<td th:text="${par.parHole16}"></td>
<td th:text="${par.parHole17}"></td>
<td th:text="${par.parHole18}"></td>
<td>
New Course
<form action="#" th:action="#{/discgolf/saveCourse}" th:object="${newCourse}"
method="POST">
<div class="form-group">
<input type="text" th:field="*{name}"
placeholder="Course name" class="form-control mb-4 col-4">
</div>
<th:block th:object="${hole}">
<div class="container">
<div id="parRow" class="row g-0">
<div class="col">
<label>#1</label>
<input type="text" th:field="*{par}" placeholder="#1">
</div>
#2 - #17
<div class="col">
<label>#18</label>
<input type="text" th:field="*{par}" placeholder="#18">
</div>
</div>
</div>
</th:block>
<button type="submit" class="btn btn-info col-2">Save Course</button>
</form>

If your parHole would be a List<Int> or Map<Int,Int> then you could iterate over it or its entries with th:each like with any list. But as you have static field names for each parHole you can't do it and you have to be repetetive like in your example.

Following Tarmo's answer, if I were you, I would convert your parList to a List of holes, add the "Hole" and "Par" as the first values in your list so they can be included as the header rows in your table, and then iterate over them. Also then you could then use index in your :each iterator to keep track of your hole numbers

Related

Get checkbox selection of a dynamic table

first of all, I am very sorry to ask that question because I know kind of this already exist. But my search with google leads me to answer with angular, JavaScript and plenty other different techs, so I unfortunately cannot find a working answer and I hope you can help me. I am totally new to HTML, and everything with webdev. I use Java with Spring MVC, Thymleaf, have JQuery and Bootstrap dependencies.
I wrote a simple HTMl file
As you can see below the table there is a "Delete Product button"
I just want that the user can select 1 to many products and if he clicks on delete the Rest Service should delete the elements and refresh the site.
What is not working:
The program doesn't receive the selection with the connected product.
Here is the code:
<div class="container" >
<h3>Fill form and execute changes</h3>
<div class="container">
<table class="table table-striped">
<thead>
<tr>
<th>Product Name</th>
<th>Price</th>
<th>Old price</th>
<th>Fee</th>
<th>Edit</th>
<th>Select</th>
</tr>
</thead>
<tbody>
<!--/*#thymesVar id="productList" type="java.util.List"*/-->
<tr th:each="product : ${productList}">
<td th:text="${product.getProductName()}">ProductName</td>
<!--/*#thymesVar id="getTradableBTC" type="java.lang.Double"*/-->
<td th:text="${product.getPrice()}">></td>
<!--/*#thymesVar id="getTop" type="java.lang.Double"*/-->
<td th:text="${product.getOldPrice()}">></td>
<!--/*#thymesVar id="getBottom" type="java.lang.Double"*/-->
<td th:text="${product.getFee()}">></td>
<!--/*#thymesVar id="getCurrencyName" type="java.lang.String"*/-->
<td>Edit</td>
<td><div class="checkbox">
<label>
<input type="checkbox" id="blankCheckbox" value=""/>
</label>
</div></td>
</tr>
</tbody>
</table>
<a th:href="'addproduct'" href="#" class="btn btn-info" role="button">Add Product</a>
<a th:href="deleteproduct" href="#" class="btn btn-info" role="button">Delete Products</a>
</div>
</div>
Can you please help me? Thank you!

JSP not displaying DB data on index page, Java Web App using Derby

I am building a simple CRUD application and after the form is submitted, the data goes to the DB. I am trying to loop through the data and show it in a listing page but cannot make it work and after hours of searching,, I come to you for an answer.
This the the listing page code where data is to be displayed. The DAO and Bean class all seem to be in order but I'll gladly upload if needed. Thanks.
<%# page import="java.util.List, models.beans.*, models.entity.*"%>
<jsp:useBean id="load" class="models.beans.LoadBean" scope="request"></jsp:useBean>
<% List<Load> loadListing = load.findAll();%>
<% for (Load lod : loadListing) {%>
<div class ="row container-fluid">
<div class="list-group col-md-6 inline">
<b><%= lod.getApptTime()%><span class="space"></span><%= lod.getCarrier()%></b>
</div>
</div>
<div id="load" class="collapse">
<div id="dvData">
<table class="table">
<tr class="row">
<th class="col-md-1 main-h">Order #</th>
<th class="col-md-1 main-h">Vendor</th>
<th class="col-md-1 main-h">Cases</th>
<th class="col-md-1 main-h">Pallets</th>
<th class="col-md-2 text-center main-h">Unload Start</th>
<th class="col-md-2 text-center main-h">Unload End</th>
<th class="col-md-2 main-h">Total Cost</th>
<th class="col-md-2 main-h">Notify Driver</th>
</tr>
<tr class="row">
<td class="col-md-1"><%= lod.getWorkOrder()%></td>
<td class="col-md-1"><%= lod.getVendor()%></td>
<td class="col-md-1"><%= lod.getCases()%></td>
<td class="col-md-1"><%= lod.getPallets()%></td>
<td>
<div class="form-group">
<input type='text' class="form-control" value="<%= lod.getUnldStart()%>" readonly/>
</div>
</td>
<td>
<div class="form-group">
<input type='text' class="form-control" value="<%= lod.getUnldEnd()%>" readonly/>
</div>
</td>
<td>
<div class="form-group">
<input type='text' class="form-control" value="$234.34" readonly/>
</div>
</td>
<td>
<button class="btn btn-md btn-primary">Send</button>
</td>
<td>
<a class="btn btn-sm btn-warning" href="<%= request.getContextPath()%>/pages/form.jsp?id=<%= lod.getId()%>">Edit
</td>
<td>
<a class="btn btn-sm btn-warning" onclick="return confirm('Are you sure?');" href="<%= request.getContextPath()%>/pages/delete.jsp?id=<%= lod.getId()%>">Delete
</td>
</tr>
<%}%>
</table>
</div>
</div>
Try out this i think this will help you-
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:forEach items="${yourList}" var="var">
<tr>
<td><c:out value="${count = count+1 }" /></td>
<td>${var.attributeName}</td>
</tr>
</c:forEach>

how to remove input fields according to values given in thymeleaf

I have a select box which looks like
My html code looks like this,
<div class="box-body" >
<span class="successMessage" th:text="${dataSuccess}" style="color: green; align-self:flex-end"></span>
<table id="example1" class="table table-bordered table-striped">
<thead>
<tr>
<th>Person Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
<th>Sex</th>
<th>District</th>
<th>VDC/MUNICIPAL</th>
<th>Ward No.</th>
<th>Xray Status</th>
<th>Remarks</th>
<th>Actions</th>
</tr>
</thead>
<tbody th:each="persons : ${part}">
<form method="post" th:action="#{/xraystatus(id=${persons.id})}" enctype="multipart/form-data" id="form1">
<td th:text="${persons.id}" id="xrayid"></td>
<td th:text="${persons.name}"></td>
<td th:text="${persons.lastName}"></td >
<td th:text="${persons.age}"></td>
<td th:text="${persons.sex}"> </td>
<td th:text="${persons.district}"></td>
<td th:text="${persons.district}"></td>
<td th:text="${persons.wardNo}"></td>
<td>
<div class="checkbox" >
<select name="xraystatus" onchange="yesnoCheck(this);" style="width:61px" >
<option value="">Select</option>
<option value="1">Yes</option>
<option value="0">No</option>
<option value="2">Possible</option>
<option value="3">Exempted</option>
</select>
</div>
</td>
<td >
<input type="text" name="remarks" >
<!--</div>-->
</td>
<td><button type="submit" class="btn btn-success" >Submit</button> </td>
</form>
</tbody>
</table>
</div>
My problem here is on checkbox only. for e.g if value 1 is returned from back-end, means yes is selected and other three thymeleaf options are ignored. So only yes is selected and shown in choose option box. But when "yes" is selected i want to show other three options too. I tried to add manual options but this idea seems to have the same option duplicated. how can this be solved?

Thymeleaf format for list within a HashMap

I'm trying to put template which has a list of values within a key in a hashmap, However when I try to put it into the template if falls over into new row by itself.
Picture:
Thymeleaf part of code:
<div class="container">
<h1 class="text-center">Boards</h1>
<hr />
<table class="table table-striped">
<tr>
<th>Board Name</th>
<th>Investor</th>
<th>Fuse Manufacturer</th>
<th>Fuse Nr. Of Poles</th>
<th>Fuse Characteritics</th>
<th>Fuse Amount</th>
</tr>
<th:block th:each="item, iterStat : ${map}" varStatus="status">
<tr>
<td th:text="${item.key.name}"></td>
<td th:text="${item.key.investor}"></td>
<tr th:each="fuse : ${item.value}">
<td th:text="${fuse.fuse.manufacturer.name}"></td>
<td th:text="${fuse.fuse.type}"></td>
<td th:text="${fuse.fuse.characteristics}"></td>
<td th:text="${fuse.quantity}"></td>
</tr>
</tr>
</th:block>
</table>
</div>
You're creating <tr />s in your <tr />s. Looking at the source generated by thymeleaf should tell you this. I would guess your html should look something like this:
<table class="table table-striped">
<tr>
<th>Board Name</th>
<th>Investor</th>
<th>Fuse Manufacturer</th>
<th>Fuse Nr. Of Poles</th>
<th>Fuse Characteritics</th>
<th>Fuse Amount</th>
</tr>
<th:block th:each="item: ${map}">
<tr th:each="fuse: ${item.value}">
<td th:text="${item.key.name}" />
<td th:text="${item.key.investor}" />
<td th:text="${fuse.fuse.manufacturer.name}" />
<td th:text="${fuse.fuse.type}" />
<td th:text="${fuse.fuse.characteristics}" />
<td th:text="${fuse.quantity}" />
</tr>
</th:block>
</table>

How to click on one href which has certain words as text using selenium web driver java

I am trying to click on href which has neither id nor name. It has text as "Proof of Prior Insurance" . When i tried with xpath
"webDriver.findElement(By.xpath("//form*[#name='plaRequiredDocumentsForm']/table[3]/tbody/tr[4]/td/table/tbody/tr/td/table/tbody/tr[2]/td[3]/a")).click()"
it prints "cannot be evaluated or does notresult in a WebElement " in console.
Website code is:
<FORM method=post name=plaRequiredDocumentsForm>
<INPUT name=expVIPCacheKey value=null type=hidden>
<INPUT name=wintag value=1411453320424 type=hidden>
<DIV style="DISPLAY: none" id=signatureOptionSection>
<TABLE width=750>
<TBODY>
<TR>
<TD style="PADDING-LEFT: 10pt">
Signature Option : <INPUT class=bodytext onclick="javascript: setPageDataChangeIndicator(); toggleSignatueStatus(this)" name=signature value=ePad type=radio value2="" value1="">
E-Pad <INPUT class=bodytext onclick="javascript: setPageDataChangeIndicator(); toggleSignatueStatus(this)" name=signature value=ink CHECKED type=radio value2="" value1=""> Ink
</TD>
</TR>
</TBODY>
</TABLE>
</DIV>
<TABLE width=750>
<TBODY>
<TR>
<TD style="TEXT-ALIGN: right; PADDING-LEFT: 5pt; PADDING-RIGHT: 10pt">
<A onblur="if (this.children[0]) this.children[0].className='';window.defaultStatus=''" onfocus="if (this.children[0] != null) this.children[0].className='activeButton';window.defaultStatus='button exit '" onmouseover="window.status='button exit ';return true;" href="javascript:formExit()">
<IMG class=bodytext border=0 align=middle src="../../../images/button_exit.gif"></A> <A onblur="if (this.children[0]) this.children[0].className='';window.defaultStatus=''" onfocus="if (this.children[0] != null) this.children[0].className='activeButton';window.defaultStatus='button image center '" onmouseover="window.status='button image center ';return true;" href="javascript:imageCenterSubmit()"><IMG class=bodytext border=0 align=middle src="../../../images/image_center.gif"></A>
<A onblur="if (this.children[0]) this.children[0].className='';window.defaultStatus=''" onfocus="if (this.children[0] != null) this.children[0].className='activeButton';window.defaultStatus='button refresh '" onmouseover="window.status='button refresh ';return true;" href="javascript:refresh()">
<IMG class=bodytext border=0 align=middle src="../../../images/button_refresh.gif"></A>
</TD>
</TR>
</TBODY>
</TABLE>
<TABLE><BR>
<TBODY>
<TR>
<TD style="PADDING-LEFT: 10pt"><FONT color=red size=2>
<B>IMPORTANT:</B> Scanning into the Application of Insurance document type will automatically apply a copy to the Subscription Agreement document type if a Subscription Agreement is required. Each document will be approved independently. </FONT>
</TD>
</TR>
</TBODY>
</TABLE>
<TABLE class=surroundingTable border=1 width=750>
<TBODY>
<TR>
<TD colSpan=2>
<TABLE class=txnTable>
<TBODY>
<TR class=sectionHeader>
<TD>
<DIV style="FLOAT: left">Household Documents </DIV>
<DIV style="FLOAT: right"><A tabIndex=-1 href="javascript:openHelpTagWindow('/TR/eAgent/Ade/eauto.help.ade?req_page=help&TransType=NN&StateCode=OH&HelpTextId=H02710001')">
<IMG border=0 src="../../../images/icon_question_mark_green_cropped.gif" width=15 height=15></A>
</DIV>
</TD>
</TR>
</TBODY>
</TABLE>
</TD>
</TR>
<TR>
<TD colSpan=2>
<TABLE class=surroundingTable>
<TBODY>
<TR>
<TD>
<TABLE class=txnTable>
<TBODY>
<TR class=columnHeader>
<TD>Household Number</TD>
<TD>Document</TD>
<TD>Status</TD>
<TD>Customer Notified</TD>
<TD>Due Date</TD>
<TD>Signature</TD>
<TD></TD>
</TR>
</TBODY>
</TABLE>
</TD>
</TR>
</TBODY>
</TABLE>
</TD>
</TR><BR>
<TR>
<TD colSpan=2>
<TABLE class=txnTable>
<TBODY>
<TR class=sectionHeader>
<TD>
<DIV style="FLOAT: left">Client Documents </DIV>
<DIV style="FLOAT: right">
<A tabIndex=-1 href="javascript:openHelpTagWindow('/TR/help.ade?req_page=help&TransType=NN&StateCode=OH&HelpTextId=H02710002')">
<IMG border=0 src="../../../images/icon_question_mark_green_cropped.gif" width=15 height=15></A>
</DIV>
</TD>
</TR>
</TBODY>
</TABLE>
</TD>
</TR>
<TR>
<TD colSpan=2>
<TABLE class=surroundingTable>
<TBODY>
<TR>
<TD>
<TABLE class=txnTable>
<TBODY>
<TR class=columnHeader>
<TD>Client Name</TD>
<TD>Date of Birth</TD>
<TD>Document</TD>
<TD>Status</TD>
<TD>Customer Notified</TD>
<TD>Due Date</TD>
<TD>Signature</TD>
<TD></TD>
</TR>
<TR class=resultsOff>
<TD>KARTHICK KAMAL </TD>
<TD>December 24, 1986</TD>
<TD>
Affinity Discount Documentation
</TD>
<TD>Not Received </TD>
<TD></TD>
<TD></TD>
<TD></TD>
<TD> </TD>
</TR>
<TR class=resultsOff>
<TD></TD>
<TD></TD>
<TD>
**Proof of Prior Insurance **
</TD>
</TR>
Please help me to solve this issue.
use 'driver.findElements(By.cssLocator("td > a"))' method to get the list of elements.
Iterate each element in the said list and get the text in it and compare it to your expected text. Where it matches that is your element and then you can take an action on it.
Use the following XPath:
//a[contains(text(),'Proof of Prior Insurance')]

Categories

Resources