Thymeleaf adding attribute to only the first item from the each loop - java

I'm trying to validate with parsley but by adding a data-parsley-min="1" to my input loop will add them to all of them.
For some reason it's not working now and I'm thinking it's because the multiple data-parsley-min="1" attributes.
Here's my code:
<form id="questionSubmitForm" data-parsley-validate="">
<div class="form-group">
<label class="font-weight-bold" for="prechecks">Pre-checks</label>
<div class="form-check" th:each="researchType : ${question.research}">
<input class="form-check-input" type="checkbox" name="prechecks[]" th:value="${researchType.value}" data-parsley-mincheck="1">
<label class="form-check-label" th:for="${researchType.value}" th:text="${researchType.key}"></label>
</div>
</div>
</form>

You can use th:attrappend (and the iteration status -- notice the , i in the th:each attribute) for this:
<form id="questionSubmitForm" data-parsley-validate="">
<div class="form-group">
<label class="font-weight-bold" for="prechecks">Pre-checks</label>
<div class="form-check" th:each="researchType, i : ${question.research}">
<input class="form-check-input" type="checkbox" name="prechecks[]" th:value="${researchType.value}" th:attrappend="data-parsley-mincheck=${i.index == 0 ? 1 : ''}" />
<label class="form-check-label" th:for="${researchType.value}" th:text="${researchType.key}"></label>
</div>
</div>
</form>

Related

Thymeleaf if else [duplicate]

This question already has answers here:
How to do if-else in Thymeleaf?
(14 answers)
Closed 1 year ago.
I don't know how to wrote this kind of insruction using Thyeleaf.
I've got my view made with html.
<#if updateClient??>
<h2>Modifica del prodotto - ${updateClient.nome}</h2>
<div style="margin: 20px;">
<form method="POST" action="update" id="updateClient">
<input type="hidden" name="id" value="${updateClient.id}"/>
<div>
<label for="name">Name</label>
<input type="text" name="nome" id="nome" value="${updateClient.nome}" />
</div>
<div>
<input type="submit" name="invia" value="Update" />
</div>
</form>
</div>
<#else>
<h2>New Client</h2>
<div style="margin: 20px;">
<form method="POST" action="add" id="newDataClient">
<div>
<label for="nome">Nome</label>
<input type="text" name="nome" id="nome" value="" />
</div>
<div>
<input type="submit" name="invia" value="Add" />
</div>
</form>
</div>
</#if>
This was written using FreeMarker, but I need to use Thymeleaf.
I know simple Thymeleaf instructions, but I don't know how to do this. I read Thymeleaf instructions, and I find how to iterate a list of variables, but not how to create this structure using if and else. And if it's possible create something like this.
<div th:if="${updateClient.nome}">
<div>Edit Form</div>
</div>
<!-- ELSE -->
<div th:unless="${updateClient.nome}">
<div>New Form</div>
</div>

NoSuchElementException - junit test error

I am using selenium junit testing.
If i try with selenium ide, the test goes well, but with junit it gives me this error:
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#firstName"}
I think that the span doesn't redirect to the page it should (but in normal schedule it does).
#Test
public void adminCreateDoc() {
driver.get("http://localhost:8080/login");
driver.manage().window().setSize(new Dimension(550, 706));
driver.findElement(By.linkText("Accesso amministratori")).click();
driver.findElement(By.id("username")).sendKeys("8245");
driver.findElement(By.id("password")).click();
driver.findElement(By.id("password")).sendKeys("prova1");
driver.findElement(By.cssSelector(".btn")).click();
driver.findElement(By.id("btn_createDoc")).click();
driver.findElement(By.id("firstName")).click();
driver.findElement(By.id("firstName")).sendKeys("Marco");
driver.findElement(By.id("lastName")).click();
driver.findElement(By.id("lastName")).sendKeys("Battiato");
driver.findElement(By.id("doc_type")).click();
driver.findElement(By.id("doc_type")).sendKeys("Cardiologo");
driver.findElement(By.id("id")).click();
driver.findElement(By.id("id")).sendKeys("855555");
driver.findElement(By.id("password")).click();
driver.findElement(By.id("password")).sendKeys("prova1");
driver.findElement(By.cssSelector(".glyphicon-send")).click();
}
I've tried with xpath, but without success...
HTML page with span redirection:
<body>
<div class="container text-center">
<div align="center">
<h2>Gestione dottori</h2>
<table class="table table-striped table-responsive-md">
<tr>
<th>ID</th>
<th>Nome</th>
<th>Specialit&agrave</th>
</tr>
<tr th:each="doc: ${listDoc}">
<td th:text="${doc.getId()}"></td>
<td>Dr. <span th:text="${doc.getFirstName()}"></span> <span th:text="${doc.getLastName()}"></span></td>
<td th:text="${doc.getDoc_type()}"></td>
</tr>
</table>
<a th:href = "#{/admin_createdoc}"><span id="btn_createDoc" class="plus bg-dark" >+</span></a>
<hr>
<div class="col col-lg-2 align-self-center">
<div class="p-1">
<form th:action="#{/admin_logout}" method=post>
<button name="btn_logout_profile" id="btn_logout_profile"
type="submit" class="btn btn-primary">Log Out</button>
</form>
</div>
</div>
</div>
</div>
</body>
Which redirect to this page:
<body>
<div class="container">
<div class="d-flex align-items-center justify-content-start">
<form th:action="#{/admin_homepage}" method=get>
<button name="btn_back_profile" id="btn_back_profile" type="submit"
class="btn btn-info">
<span class="fas fa-chevron-left"></span>
</button>
</form>
</div>
<br>
<div style='text-align: center'>
<form class="well form-horizontal" action="#"
th:action="#{/saveDoctor}" th:object="${doc}" method="POST"
id="contact_form">
<fieldset>
<!-- Form Name -->
<legend>
<center>
<h2>
<b>Doctor Creation Form</b>
</h2>
</center>
</legend>
<br>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">First Name</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i
class="glyphicon glyphicon-user"></i></span> <input name="first_name"
th:field="*{firstName}" placeholder="Doc First Name"
class="form-control" type="text" required>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Last Name</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i
class="glyphicon glyphicon-user"></i></span> <input name="last_name"
th:field="*{lastName}" placeholder="Doc Last Name"
class="form-control" type="text" required>
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Type</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i
class="glyphicon glyphicon-list"></i></span> <input name="doc_type"
th:field="*{doc_type}" placeholder="Doc Type"
class="form-control" type="text" required>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Id</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i
class="glyphicon glyphicon-user"></i></span> <input name="id"
th:field="*{id}" placeholder="Doc ID" class="form-control"
type="number" required>
</div>
</div>
</div>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-4 inputGroupContainer">
<div class="input-group">
<span class="input-group-addon"><i
class="glyphicon glyphicon-user"></i></span> <input
th:field="*{password}" name="doc_password"
placeholder="Doc Password" class="form-control" type="password"
required>
</div>
</div>
</div>
<!-- Button -->
<div class="form-group" align="center">
<label class="col-md-4 control-label"></label>
<div class="col-md-4">
<br>
<button type="submit" class="btn btn-warning">
SUBMIT <span class="glyphicon glyphicon-send"></span>
</button>
</div>
</div>
</fieldset>
</form>
<div>
<form th:action="#{/admin_logout}" method=post>
<button name="btn_logout_profile" id="btn_logout_profile"
type="submit" class="btn btn-primary">Log Out</button>
</form>
</div>
</div>
</div>
</body>
Thank you for your time!
The failure is happening on this line
driver.findElement(By.id("firstName")).click();
ID as a CSS selector is #firstName. Since this is right after a page transition, my guess is that the page isn't fully loaded before the next line of code is run. This can sometimes happen on a modern site where the page is loaded but there's still stuff being loaded asynchronously in the background. The fix is to add a wait, specifically a WebDriverWait, to the following line. That is one option...
Instead of adding a wait piecemeal when it's found that you need it, I prefer to write helper methods that take care of common actions like click(), sendKeys(), etc. and then let those methods take care of the specific waits for me.
public void click(By locator) {
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator)).click();
}
public void sendKeys(By locator, String text) {
findElement(locator).sendKeys(text);
}
public WebElement findElement(By locator) {
return new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfElementLocated(locator));
}
Then you can change your script to
#Test
public void adminCreateDoc() {
driver.get("http://localhost:8080/login");
driver.manage().window().setSize(new Dimension(550, 706));
click(By.linkText("Accesso amministratori"));
sendKeys(By.id("username"), "8245");
sendKeys(By.id("password"), "prova1");
click(By.cssSelector(".btn"));
click(By.id("btn_createDoc"));
sendKeys(By.id("firstName"), "Marco");
sendKeys(By.id("lastName"), "Battiato");
sendKeys(By.id("doc_type"), "Cardiologo");
sendKeys(By.id("id"), "855555");
sendKeys(By.id("password"), "prova1");
click(By.cssSelector(".glyphicon-send"));
}
which I think makes it more readable, adds waits to everything in case it's needed with no extra code, and so on...
The next level is using the Page Object Model to contain the locators and methods for each page. Then your code gets cleaned up significantly, makes it near-human readable, and MUCH easier to manage.

Thymeleaf client side validation

I am new to thymeleaf and I working on a login form. I have found a simple example where there is login input text and password fields.
I have included the project in my system. When I click the login button without filling username and password section, a please fill in details ballon pops up. I have not configured it anywhere, but would like to know from it is getting popped up. Below is the code
<div class="row" style="margin-top:20px">
<div class="form-group " align="right">
</br> </br> </br> </br> </br></br> </br> </br> </br>
<form th:action="#{/login}" method="post">
<fieldset>
<h2 class="form-heading">Log in</h2>
<div th:if="${param.error}">
<div class="alert alert-danger">
Invalid username and password.
</div>
</div>
<div th:if="${param.logout}">
<div class="alert alert-info">
You have been logged out.
</div>
</div>
<div class="form-group">
<input type="text" name="username" id="userName" class="form-control input-lg"
placeholder="UserName" required="true" autofocus="true"/>
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-lg"
placeholder="Password" required="true"/>
</div>
<div class="row">
<button class="btn btn-default" role="button">Log In</button>
</div>
</div>
</fieldset>
</form>
</div>
</div>

thymeleaf checkbox always sets value as false

Method 1
<div class="col-sm-10">
<input type="checkbox" th:field="*{isEnabled}"/>
<i class="indigo"></i>
Enable User
<input type="hidden" value="on" name="_isEnabled"/>
</div>
Method 2
<div class="col-sm-10">
<input type="checkbox" th:checkbox="${isEnabled}" name="isEnabled"/>
<i class="indigo"></i>
Enable User
<input type="hidden" value="on" name="_isEnabled"/>
</div>
I always get the value of isEnabled as false in the backend.
There are other fields in the form that works well. I am stuck with this checkbox part.

Null value is getting passed to the Servlet from my jQuery script

I am passing a value from a jsp page to bootstrap modal using jQuery and it is working. I want to pass the same value from bootstrap modal to the servlet. I tried with ajax, post, nothing seems to be working. Here is my html:
<div class="container" style="padding-top: 60px;" >
<select class="createAlarm" id="createAlarm" name="metrics">
<option value="cpuUsage">CPU Usage</option>
<option value="memoryUsage">Memory Usage</option>
<option value="diskRead">Disk Read</option>
<option value="diskWrite">Disk Write</option>
<option value="diskUsage">Disk Usage</option>
<option value="netUsage">Net Usage</option>
</select>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal" data-whatever="Create Alarm">Create Alarm</button>
</div>
<!-- Modal- Create Alarm -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Create Alarm</h4>
</div>
<form action="/ProjectName/createAlarm" method="post" id="addcard" class="form-horizontal" role="form">
<div class="modal-body" style="height: 170px;">
<div class="form-group" style="height: 30px;">
<label for="title" class="col-md-3 control-label">Name</label>
<div class="col-md-9">
<input type="text" class="form-control" name="alarmName">
</div>
</div>
<div class="form-group" style="height: 30px; margin-bottom:30px;">
<label for="title" class="col-md-3 control-label">Description</label>
<div class="col-md-9">
<textarea class="form-control" name="desc"></textarea>
</div>
</div>
<div class="form-group">
<label for="priority" id="priority" name="priority" class="col-md-3 control-label">
<input type="text" class="form-control" name="name">
</label>
<div class="col-md-9">
<div class="col-md-3">
<select name="sign" class="form-control">
<option value="lessthan"><</option>
<option value="greaterthan">></option>
<option value="lessthanequalto"><=</option>
<option value="greaterthanequalto">>=</option>
</select>
</div>
<div class="col-md-3">
<input type="text" class="form-control" name="threshold">
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button class="btn btn-primary" id="formSubmit" type="submit">Create Alarm</button>
</div>
</form>
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->
</div><!-- /.modal -->
Here is my jQuery part:
<script>
$('#myModal').on('show.bs.modal', function(e) {
var metrics_key = $('.createAlarm').val();
var metrics_label = $(".createAlarm option:selected").text();
// Now you have the key and label in variables.
// Write the key into the textfield.
$('#myModal input[name="name"]').val(metrics_key);
// Change the HTML of an element to the label.
$('#myModal label[for="priority"]').text(metrics_label);
$.post("/CMPE283_Project2/createAlarm", { val : $("#priority").text()});
alert($('#priority').text());
});
My Servlet:
String Metric = request.getParameter("val");
But, I am getting null for the String Metric. But alert pop up after clicking 'Create Alarm' button shows the correct value I want to pass the servlet. Please help. Thanks.
Your post looks ok, I believe it's just a matter of jquery syntax for accessing controls.
In particular, I'd expect a text input with id="priority" (not just a label as it appears in your code), and then you access it with '.val()' and not 'text()'
<input type="text" id="priority" ... />
$.post('your url', {priority: $("#priority").val()} ...
At least this works for me (jquery version 2.1.3). If you want to make sure, you can just start by posting hard coded data such as {priority: '7'}

Categories