Getting value from s:select inside an iteration - java

I am iterating a list object in jsp, I want to get the <s:select> value when submitting the form.
My jsp is like this:
<s:iterator value="listeTypeEvent" status="event">
<tr>
<td>
<s:select id = "criticite"
list = "criticite"
name = "degreCriticite"
value = "%{event.degreCriticite}"/>
</td>
<td>
<s:select id = "famlle"
list = "listFamille"
name = "familleEvent.idFamille"
listKey = "idFamille"
listValue = "libelleFamille"
value = "%{event.idFamille}"/>
</td>
</tr>
</s:iterator>

The error is that the code in the question is confusing status (that instantiates an IteratorStatus object, and does not have degreCriticite nor idFamille attributes) with var (that instantiates a variable containing the current element in the iteration).
Another minor error is that id must be unique in an HTML page.
The missing piece to send back a value of an element created inside an iteration is the creation of an index (through the help of the aforamentioned IteratorStatus object):
<s:iterator value="listeTypeEvent" var="event" status="ctr">
<tr>
<td>
<s:select id = "criticite_%{#ctr.index}"
list = "criticite"
name = "degreCriticite[%{#ctr.index}]"
value = "%{event.degreCriticite}"/>
</td>
<td>
<s:select id = "famlle_%{#ctr.index}"
list = "listFamille"
name = "familleEvent[%{#ctr.index}].idFamille"
listKey = "idFamille"
listValue = "libelleFamille"
value = "%{event.idFamille}"/>
</td>
</tr>
</s:iterator>

Related

Is it possible to use th-field to retrieve the value of a list in Thymeleaf?

I am creating a page in thymeleaf where I retrieve a list from my controller to mount a table, in this table there is a selection field where I retrieve a list of values ​​but I am not able to display the value that is already being retrieved of the database can help me? Please!
I already tried to use the following commands but could not recover the value:
th:field="*{valoresAtributo[__${stat.index}__].valorUsuario}"
I receive the following error: Neither BindingResult nor plain target object for bean name available as request attribute.
<table class="table table-sm table-striped table-bordered" id="dataTable">
<thead>
<tr><th colspan="4">Valores dos Atributos</th></tr>
</thead>
<tbody>
<tr class="text-black">
<td rowspan="2"> Atributo</td>
<td rowspan="2"> Local</td>
<td>Aplicação</td>
<td>Usuário</td>
</tr>
<tr>
<td id="vlAppl"></td>
<td id="vlUser"></td>
</tr>
<tr th:each="valorAtributo, stat : ${valoresAtributo}">
<td th:text="${valoresAtributo[__${stat.index}__].nomeAtributo}"></td>
<td th:text="${valoresAtributo[__${stat.index}__].valorLocal}"></td>
<td th:text="${valoresAtributo[__${stat.index}__].valorAplicaco}"></td>
<td>
<select class="form-control col-md-10" th:field="*{valoresAtributo[__${stat.index}__].valorUsuario}">
<option th:each="option : ${T(com.jequiti.JequitiIntegrador.controller.AtributoController).test(valorAtributo.sqlValidacao)}"
th:value="${{option.valorAtributo}}"
th:text="${option.significadoAtributo}">
</option>
</select>
</td>
</tr>
</tbody>
</table>
#RequestMapping(value="/seguranca/atributo/valores", params = {"atributo","siteOpt","applOpt","userOpt","aplicacao","usuario"}, method = RequestMethod.GET)
public String initAttributeValuesFormFilter(#RequestParam("atributo") Long idAtributo, #RequestParam("siteOpt") Integer idNivel1, #RequestParam("applOpt") Integer idNivel2, #RequestParam("userOpt") Integer idNivel3, #RequestParam("aplicacao") String aplicacao, #RequestParam("usuario") String usuario, Model model)
{
Integer userId = 0;
if(!Strings.isNullOrEmpty(usuario))
userId = userServiceImpl.findIdUsuarioByFantasia(usuario).intValue();
List<ValoresAtributoView> valoresAtributo = buscaValoresAtributos(idAtributo, idNivel1, idNivel2, idNivel3, 0, userId);
model.addAttribute("opUsuarios", userServiceImpl.findAllActiveUsers());
model.addAttribute("opAtributos", atributoService.findAll());
model.addAttribute("valoresAtributo",valoresAtributo);
return "/valoresAtributo";
}
I expected the field to display the value that is currently in the database and the options in the list of values.
Thank you all!
You can only use th:field if you are using th:object in a parent <form /> tag. (Which isn't clear from the HTML you posted -- but you probably are not since your are adding valoresAtributo directly as a model attribute.)
If you wish to show a preselected <option> but without using th:object and th:field you should instead use the th:selected attribute which should evaluate to true or false based on if that option should be selected. It should look something like this:
<select class="form-control col-md-10">
<option
th:each="option : ${T(com.jequiti.JequitiIntegrador.controller.AtributoController).test(valorAtributo.sqlValidacao)}"
th:value="${{option.valorAtributo}}"
th:text="${option.significadoAtributo}"
th:selected="${valorAtributo.valorUsuario == option.valorAtributo}" />
</select>
My way to retrieve list using thymeleaf:
For example list users with list of User entity getting to html page:
#GetMapping("/parsing/explorer")
public ModelAndView parsing(){
ModelAndView modelAndView = new ModelAndView("show");
modelAndView.addObject("users", generateUsersList());
return modelAndView;
}
show.html example:
<table class="w3-table-all w3-card-4">
<tr>
<th>Id</th>
<th>Name</th>
<th>Last name</th>
</tr>
<tr th:each="user : ${users}">
<td th:text="${user.getId()}"></td>
<td th:text="${user.getName()}"></td>
<td th:text="${user.getLastName()}"></td>
</tr>
</table>
So list of User (users) is assigned to the variable user in string <tr th: every = "user: $ {users}">
In the next block of code, we can also call the "User" fields the same way as java using getters, but Thymeleaf also allows you to refer to the fields: user.id/ user.name....
Determining variable in the select block:
<select name="userFromHtml" id=userId required>
<option th:each="user: ${users}">
<title th:text="${user.getLastName()} + ' ' + ${user.getName()} + ' ' + ${user.getIdIO}" th:value="${user.getId()}"/>
</option>
</select>
in this case is necessary to determine th:value in title block: th:value="${user.getId()}". So, in controller is passed variable userFromHtml with value id of selected user.
PS Although Thymeleaf allows you to define variable in direct, I prefer to use getters for data getting.

Unable to grab an element in a dynamic table where we have only text of a td tag

I have a table whose data changes according to what is added and deleted. In the table there are multiple columns Name, Qty, type, Status. All i have is the Name Text with me , i need to find the status field of that row which has that Name.
Problem is the html tags of have same class names and i tried grabbing the parent and sibling everything failed. Please find the html structure of the table below:
<table>
<thead> </thead>
<tbody>
<tr>
<td class = "c1">
<a class = txtclass> text1 </a>
</td>
<td class = "c1"> Qty </td>
<td class = "c2"> type </td>
<td class = "c3">
<div id = "1" class = "status1"> /div>
</td>
</tr>
<tr>
<td class = "c1">
<a> text2 </a>
</td>
<td class = "c1"> Qty </td>
<td class = "c2"> type </td>
<td class = "c3">
<div id = "2" class = "status2"> /div>
</td>
</tr>
</tbody>
</table>
So all i have with me is text2 and i need to get the with the status of that row.
How do i proceed. I tried
List<WebElement> ele = driver.findElements(By.xpath("//*[#class = 'txtClass'][contains(text(),'text')]"));
for(WebElement el1:ele)
{
WebElement parent = el1.findElement(By.xpath(".."));
WebElement child1= parent.findElement(By.xpath("//td[4]/div"));
System.out.println(child1.getAttribute("class"));
}
this gives me the class name of the status of the first row in the table always.
Same i tried with
WebElement child = el1.findElement(By.xpath("//following-sibling::td[4]/div[1]"));
i got the same thing class name of the first row in the table. I figured since the class name of the are same for all child elements it will always grab the first row elements, and not the one from the row.
Please help i am stuck here for long, let me know if you need any other details.
You are trying using -
el1.findElements(By.xpath("//following-sibling::td[4]/div[1]"));
It is matching all the element present with format td[4]/div[1] in your page and retrieving first match.
You have to use following xpath to grab status present under div based on you text.
driver.findElement(By.xpath(".//tr/td[contains(.,'text1')]/following-sibling::td[3]/div")).getAttribute("class");
If your requirement to extract all status try following code-
List<WebElement> allElements = driver.findElements(By.xpath(".//tr/td[contains(.,'text2')]/following-sibling::td[3]/div"));
for(WebElement element:allElements)
{
String status = element.getAttribute("class");
System.out.println(status);
}
I think this approach suitable for you:
Get all div elements containt attribute status :
List<WebElement> listChildStatus = driver.findElements(By.xpath(".//tr[.//a[contains(.,'text')]]//div"));
Get specific div elements containt attribute status :
WebElement childStatus = driver.findElement(By.xpath(".//tr[.//a[contains(.,'{TEXT}')]]//div"));
{TEXT} = the text value that you have
You need to locate the element with the text, go one level up, and then get the sibling with the status
WebElement statusElement = driver.findElement(By.xpath(".//td[a[contains(text(),'text2')]]/following-sibling::td[3]/div"));
String status = statusElement.getAttribute("class"); // will be status2
If you don't want to relay on index you can use last() to find the last sibling
WebElement statusElement = driver.findElement(By.xpath(".//td[a[contains(text(),'text2')]]/following-sibling::td[last()]/div"));

How to create a dynamic URL in SPRING MVC

I have a requirement to open a PDF when the user clicks on a particular employee id present in a table. Like:
Employee id url
123 View
234 View
When user clicks on the View corresponding to that row, details of Employee id should open in a pdf.
Someone please give me pointers on how to move forward on this. I am using JAVA Spring MVC framework.
Also need to know how will I create VIEW hyperlink, as this comes in a coulmn of a table. I am populating this table from Java Class.
My Controller Class:
#RequestMapping
public ModelAndView getHeaders(PortletRequest portlestRequest, PortletResponse portletResponse){
TableDAO dao = new TableDAO();
List<String> headersList = dao.getHeaders();
TableView tableView = new TableView();
tableView.setGetHeaderCount(headersList.size());
//System.out.println("tableView::");
tableView.setTableHeaders(headersList);
List prepaidBillingDetailsList = new ArrayList();
prepaidBillingDetailsList = dao.getPrepaidBillingInfo();
tableView.setPrepaidBillingDetailsList(prepaidBillingDetailsList);
return new ModelAndView("tableView", "tableView", tableView);
}
My JSP:
<table border="1px" bordercolor="black" width=80% align="center">
<tr>
<c:forEach var = "headerList" items = "${tableView.tableHeaders}">
<th>
${headerList}
</th>
</c:forEach>
</tr>
<c:forEach var = "headerList" items = "${tableView.prepaidBillingDetailsList}">
<tr>
<c:forEach var = "headerList" items = "${headerList.stringlst}">
<td>
${headerList}
</td>
<td>
<a href="<c:url value="editEmployee.htm">
<c:param name="msisdn" value="${tableView.msisdn}"/>
</c:url> ">Edit</a>
</td>
</c:forEach>
</tr>
</c:forEach>
</table>
In this, First headerList will get my eadrs of the table, Next header list will display the data for of my employee class. Now in the last coulmn i need inks, which will take me to the PDF of that particular employee.
You can form your view link url something like www.appdomain.com/App/Profile?id=123
view
and then map your controller with this url and get the id parameter from url and with the id get the details of the user and display it.
Second way is you can also get the url like www.appdomain.com/App/Profile/123
view
i.e. id as a path variable and get this path variable in the controller and get the details and display.

How to set the checkbox in the first column based on the value in the second column of a table?

I'm automating a task using Java and Selenium.
I want to set a checkbox (which is in the first column of a table) based on whether the value in the second column matches my input value. For example, in the following code snippet, the value "Magnus" matches my input value so I want to set the checkbox associated with it.
<table class="cuesTableBg" width="100%" cellspacing="0" border="0" summary="Find List Table Result">
<tbody>
<tr class="cuesTableBg">
<tr class="cuesTableRowEven">
<tr class="cuesTableRowOdd">
<td align="center">
<input class="content-nogroove" type="checkbox" name="result[1].chked" value="true">
<input type="hidden" value="1c62dd7a-097a-d318-df13-75de31f54cb9" name="result[1].col[0].stringVal">
<input type="hidden" value="Magnus" name="result[1].col[1].stringVal">
</td>
<td align="left">
<a class="cuesTextLink" href="userEdit.do?key=1c62dd7a-097a-d318-df13-75de31f54cb9">Magnus</a>
</td>
<td align="left"></td>
<td align="left">Carlsen</td>
<td align="left"></td>
</tr>
<tr class="cuesTableRowEven">
</tbody>
</table>
But I'm unable to do it. In the above case, the following two lines serve the purpose (as my input value matches with that in the second row):
WebElement checkbox = driver.findElement(By.xpath("//input[#type = 'checkbox' and #name = 'result[1].chked']"));
checkbox.click();
But it can't be used as the required value might not always be in the second row.
I tried following code block but to no avail:
List<WebElement> rows = driver.findElements(By.xpath("//table[#summary = 'Find List Table Result']//tr"));
for (WebElement row : rows) {
WebElement userID = row.findElement(By.xpath(".//td[1]"));
if(userID.getText() == "Magnus") {
WebElement checkbox = row.findElement(By.xpath(".//input[#type = 'checkbox']"));
checkbox.click();
break;
}
}
For what it's worth, XPath of the text in the second column:
/html/body[#id='mainbody']/table/tbody/tr/td/div[#id='contentautoscroll']/form/table[2]/tbody/tr[3]/td[2]/a
I don't know about CSS Selectors. Will it help here?
If you know the input value already you just use below xpath to select respected checkbox
"//a[text(),'Magnus']/parent::td/preceding-sibling::td/input[#type='checkbox']"
Update:
"//a[text()='Magnus']/parent::td/preceding-sibling::td/input[#type='checkbox']"
While comparing two strings equals should be used instead of ==
Replace
if(userID.getText() == "Magnus")
with
String check1 = userID.getText();
if(check1.equals("Magnus")
Seems like it was a silly mistake on my part. The following code snippet, a fairly straightforward one, worked.
List<WebElement> rows = driver.findElements(By.xpath("//table[#class='cuesTableBg']//tr"));
for (WebElement row : rows) {
WebElement secondColumn = row.findElement(By.xpath(".//td[2]"));
if(secondColumn.getText().equals("Magnus")) {
WebElement checkbox = row.findElement(By.xpath(".//td[1]/input"));
checkbox.click();
break;
}
}

Getting a request parameter in a servlet from html form set with EL

I have a JSP with the following EL/html tags:
<c:forEach var="key" items="${resource.stringPropertyNames()}">
<tr>
<td>${key}</td>
<td><input type = "text" name = "${key}" value = "${resource.get(key)}"></td>
</tr>
</c:forEach>
When my jsp is rendered, the first <td> tag shows the evaluated value of ${key}. In the <input> tag however, the ${key} is not evaluated correctly. When I try to retrieve the input as request parameters from my servlet (request.getParameter(StringKey)), I get the literal $key without the braces. When I do request.getParameter("$key"), I get multiple values for the Strings that ${resource.get(key)} evaluate to in the EL.
What is going on?
EDIT
Controller method (using spring) code:
#RequestMapping(value = URI_PATH + "{fileName}", method = RequestMethod.GET)
public String getProperties(#PathVariable String fileName, ModelMap modelMap) {
Properties resource = ..//get properties file
modelMap.addAttribute("resource", resource);
return "configuration" // maps to my jsp;
}
If resource is a Map, which is set using request.setAttribute("resource", resource)
<c:forEach var="entry" items="${resource}">
<tr>
<td>${entry.key}</td>
<td><input type = "text" name = "${entry.key}" value = "${entry.value}"></td>
</tr>
</c:forEach>

Categories