I am looking to add a required attribute to one of my input with thymeleaf depending on a radio button.
My code is at the moment:
<div class="form-group row">
<fieldset class="col-md-6">
<legend class="control-label init-font-size">
<span th:text="#{myLabel}"></span>
</legend>
<label th:with="label_key='radio.'+${item}+'.label'" class="radio-inline required" th:id="'lbl_' + test + ${iteration.index}" th:for="'input_' + test + ${iteration.index}" th:each="item, iteration : ${ { 'yes', 'no' } }" >
<input type="radio" required="required" th:id="'input_' + test + ${iteration.index}" th:field="*{test}" th:value="${item}"/>
<span th:text="#{${label_key}}"></span>
</label>
</fieldset>
</div>
<div class="form-group row classTestInfos">
<div class="col-md-6">
<label class="control-label" th:for="testInfos">
<span th:text="#{test.label}"></span>
<a role="button" href="#" data-toggle="collapse" th:attr="'data-target'='#help' + testInfos" class="btn btn-help collapsed" th:title="#{testInfos.title}">
<span class="blank sr-only" th:text="#{testfInfos.title}"></span>
</a>
<span class="text-danger" aria-hidden="true" th:attr="'data-error-required'=#{testInfos.empty}, 'data-error-format'=#{testInfos.format}"></span>
</label>
<div>
<textarea id="testInfos" maxlength="400" class="form-control" th:field="*{testInfos}" aria-invalid="false"/>
</div>
</div>
</div>
How can I do so that when 'yes' is checked on the radio button, the textarea will be required, if not it won't.
Related
I have this stack, and i am trying to find my mistake but i can't.
When i print the validcheck box the value is null no matter if I check it or if not .
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<div class="checkbox">
<label><input type="checkbox" name="checkboxconfirm" >
<p style="color:Blue;">I agree to the terms and
conditions</p</label>
</div>
</div>
</div>
boolean validcheckbox = request.getParameter("checkboxconfirm");
out.println("<b>checkbox: </b>" + validcheckbox + "<br>");
I'm using thymeleaf and I want to iterate a loop and group by every n items. Right now my code wants to group by every 4 items. After a search in most of the questions, this is my code:
<div th:each="items, iter: ${myList}" th:if="${iter.count} % 4 == 0" th:class="${iter.first}? 'nice-slider-slide active first' : 'nice-slider-slide'">
<div class="nice-slider-entry" th:each="item, iter: ${items}">
<span th:text="${item.getName}"></span>
</div>
</div>
The result is blank and it is printing nothing. But the result I want is:
<div class="nice-slider-slide active first">
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
</div>
<div class="nice-slider-slide">
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
<div class="nice-slider-entry">
<span>Name</span>
</div>
</div>
Why not move the logic of the grouping outside view layer? Thymeleaf is not so friendly with data computation.
Instead of a simple list to have a list of lists:
List<String> myList;
to be replaced by:
List<List<String>> myList;
Your thymeleaf code will be something like this:
<div th:each="subList,iter : ${myList}" th:class="${iter.first}? 'nice-slider-slide active first' : 'nice-slider-slide'">
<div class="nice-slider-entry" th:each="index: ${subList}">
<span th:text="${index}"></span>
</div>
</div>
UPDATE with pure Thymeleaf solution:
<th:block th:with="noEl = 4,totalSize = ${#lists.size(myList)} - 1">
<th:block th:each=" listIndex: ${#numbers.sequence(0, totalSize, noEl)}">
<div th:class="${listIndex eq 0 }? 'nice-slider-slide active first' : 'nice-slider-slide'"
th:with="maxValue = ${ totalSize lt (listIndex + noEl -1) ? totalSize : listIndex + noEl -1}">
<div class="nice-slider-entry" th:each="index : ${#numbers.sequence(listIndex, maxValue)}">
<span th:text="${myList[index]}"></span>
</div>
</div>
</th:block>
</th:block>
I have a page where I need to extract the text from an xpath and the status of the radio or checkbox that is associated with the text.
Each element is contained in a class called "c-form-group", so i have written a loop to iterate through to extract the "Text" the will be 4 elements found on the page. But it is failing on element 3 & 4, i must have something wrong with my xpath. I have yet to add in the check for the checkbox/radio button,
The first two elements are returning the values i require, then fails on element3.
Here are the 4 text elements i am trying to extract:
Plan B Warranty (Taxi) & Breakdown Recovery
Vehicle Asset Protection - Standard Cover
Negative Equity Cover
You confirm that you have received the VAP key facts leaflet?
Here is the code for the loop.
WebElement elem = driver.findElement(By.className("c-form-group"));
System.out.println("a");
List<WebElement> elementz = elem.findElements(By.xpath("//label[contains(#class,'c-option')]"));
for(int i = 0 ; i< elementz.size() ; i++){
System.out.println("Loop : " + i);
String vapval1 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("0 = " + vapval1);
String vapval2 = elementz.get(i).findElement(By.xpath("//label[#class='c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__radio')]")).getText();
System.out.println("1 = " + vapval2);
String vapval3 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix ng-scope' and not(#class='ng-pristine ng-untouched ng-valid') and not (#class='c-option__checkbox')]")).getText();
System.out.println("3 = " + vapval3);
String vapval4 = elementz.get(i).findElement(By.xpath("//label[#class,'c-option c-option--right u-px u-py-sm u-clearfix' and not(#class='ng-pristine ng-untouched ng-valid ng-valid-required') and not (#class='c-option__checkbox')]")).getText();
System.out.println("4 = " + vapval4);
}
Here is the full html, which may help.
<!DOCTYPE html>
<html class="ng-scope" ng-app="dan">
<head>
<body class="u-scroll-y ng-scope" ng-controller="CoreController as cc">
<div class="c-animate c-animate--show u-pos-f-t ng-hide" ng-show="global.alerts.length">
<div class="o-grid-fluid u-h-100 u-pl-0">
<div class="o-grid__row u-ml-0 u-h-100">
<div class="c-loader ng-hide" ng-show="loadingHome" style="">
<nav class="o-grid__col-xl-2 o-grid__col-lg-3 o-grid__col-xs-4 u-p-0 c-card__block u-h-100 u-shadowed u-pos-f-t ng-scope" ng-if="global.loggedIn">
<div class="u-p-0 u-h-100 o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right" ng-class="{ 'o-grid__col-xl-10 o-grid__col-lg-9 o-grid__col-xs-8 u-pull-right' : global.loggedIn }">
<header class="o-layout-table__row u-bg-primary u-shadowed u-clearfix u-px ng-scope" ng-if="global.loggedIn">
<main class="o-view-container">
<div class="o-grid-fluid u-py-md">
<div class="o-grid__row">
<div class="c-animate c-animate--view-slide-in-right c-animate--view-slide-out-right ng-scope" ng-view="" style="">
<div class="o-grid__col-md-10 o-grid__col-xl-8 o-grid__col-xl-offset-2 o-grid__col-md-offset-1 ng-scope">
<div class="u-mb-lg u-text-center">
<h1 class="u-text-bold">Recommendations</h1>
</div>
<form class="ng-valid ng-valid-min ng-valid-max ng-valid-required ng-dirty ng-valid-parse" name="recommend" ng-submit="recommend.$valid" style="">
<div class="o-media c-card c-card__block u-shadowed u-mb-lg ng-scope" ng-if="rc.WarrantyEligible && !rc.prevWarranty()">
<label class="c-form-control-label u-px u-py-sm u-w-100">Warranty Options:</label>
<div class="c-form-group u-p-0 u-mb-sm u-clearfix">
<div class="o-grid__col-md-8">
<label class="c-form-control-label u-text-normal">Product Recommendations (Years):</label>
</div>
<div class="o-grid__col-md-4">
<input class="c-form-control ng-pristine ng-untouched ng-valid ng-valid-min ng-valid-max ng-valid-required" required="" placeholder="Years" ng-model="rc.recommend.year" min="1" max="3" type="number">
</div>
</div>
<div class="c-form-group ng-scope" ng-if="data.answer_taxi">
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="!rc.planA && !rc.prestige" ng-click="cc.utils.audit('recommendation_warranty_plan_taxi_b')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.warrantyPlan" value="taxiB" name="warrantyPlan" type="radio">
<i class="c-option__radio"></i>
Plan B Warranty (Taxi) & Breakdown Recovery
</label>
</div>
</div>
<div class="o-media c-card c-card__block u-shadowed u-mb-lg u-text-body u-bg-success" ng-if="!rc.prevVap() && rc.VapEligible ">
<div class="c-form-group">
<label class="c-form-control-label u-px u-py-sm u-w-100">Vehicle Asset Protection Options:</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('recommend_vap')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapPlan.plan" value="standard" name="vapPlan" type="radio">
<i class="c-option__radio"></i>
Vehicle Asset Protection - Standard Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix ng-scope" ng-if="data.answer_equity == true" ng-click="cc.utils.audit('recommend_negative_equity')">
<input class="ng-untouched ng-valid ng-dirty ng-valid-parse" ng-model="rc.recommend.vapPlan.equity" name="vapPlanEquity" type="checkbox" style="">
<i class="c-option__checkbox"></i>
Negative Equity Cover
</label>
<label class="c-option c-option--right u-px u-py-sm u-clearfix" ng-click="cc.utils.audit('vap_key_facts_checked')">
<input class="ng-pristine ng-untouched ng-valid ng-valid-required" required="" ng-model="rc.recommend.vapCheck" name="vapCheck" type="checkbox">
<i class="c-option__checkbox"></i>
You confirm that you have received the VAP key facts leaflet?
</label>
</div>
</div>
</form>
<div class="c-form-group">
</div>
</div>
</div>
</div>
</main>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js">
<script src="./build/app.js?v=2.13" defer="">
<script src="/build/standalone/jspdf.js" defer="">
<script src="/build/standalone/sigWebTablet.js" defer="">
</body>
</html>
I'm a little confused as to what you are trying to do. You mention getting the text from the elements and also getting the state of the checkboxes. Your XPaths on the outer and inner loop overlap. Your elementz list is pulled from a LABEL that contains the c-option class but then you start with an element from elementz and the first part of your XPath you repeat the search for a LABEL that contains the c-option class.
There is an much easier way to do this. Each of these checkboxes/radiobuttons are INPUT tags and have a name specific to their value.
Plan B Warranty (Taxi) & Breakdown Recovery: <input ... name="warrantyPlan" type="radio">
Vehicle Asset Protection - Standard Cover: <input ... name="vapPlan" type="radio">
Negative Equity Cover: <input ... name="vapPlanEquity" type="checkbox" style="">
You confirm that you have received the VAP key facts leaflet?: <input ... name="vapCheck" type="checkbox">
So with that info, you can just get each INPUT with CSS selectors like
By.cssSelector("input[name='warrantyPlan']")
Once you have the INPUT element, you can check if it's selected using .isSelected().
If you really do need the text, you can get the label because it's the parent of the INPUT we just got. We can do this with an XPath, By.xpath(".."), which gets the parent of the current element.
We can put this all together like
// Plan B Warranty (Taxi) & Breakdown Recovery
WebElement e = driver.findElement(By.cssSelector("input[name='warrantyPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Plan B Warranty (Taxi) & Breakdown Recovery
// Vehicle Asset Protection - Standard Cover
e = driver.findElement(By.cssSelector("input[name='vapPlan']"));
System.out.println(e.isSelected()); // false
System.out.println(e.findElement(By.xpath("..")).getText()); // Vehicle Asset Protection - Standard Cover
I just did the first two. You can see the pattern and apply it for the last two.
I am trying to check if a field in the database is true or false using the SpEl "th:if="${certs.flag == 'TRUE'}" ". If it is set to "true" the form should not be displayed. I have searched all over but can not seem to find any article that has an example of what i need exactly. Everyone seems to be using iteration. But iteration is not applicable to what i am doing.
#RequestMapping(value = "/cert_prog", method = RequestMethod.GET)
public String examsList(Model model, CertificateProgramme certificateProgramme){
Iterable<Exams> exams = examService.findAll();
Iterable<School> schools = schoolService.findAll();
Iterable<CertificateProgramme> certificateProgrammes = certificateService.findAll();
Iterable<Picture> pictures = pictureService.findAll();
CertificateProgramme mycert = certificateService.flagger(certificateProgramme);
model.addAttribute("mycert", mycert);
model.addAttribute("exams", exams);
if(!model.containsAttribute("newExam")){
model.addAttribute("newExam", new Exams());
}
model.addAttribute("certificateProgrammes", certificateProgrammes);
if(!model.containsAttribute("certificate")){
model.addAttribute("certificate",new CertificateProgramme());
}
model.addAttribute("grades", Grade.values());
model.addAttribute("regions", Region.values());
model.addAttribute("schools",schools);
if(!model.containsAttribute("newSchool")){
model.addAttribute("newSchool",new School());
}
model.addAttribute("picture", new Picture());
return "cert_prog";
}
<form th:if="${certs.flag == 'TRUE'}" method="post" th:object="${certificate}" th:action="#{/basic}" class="form-inline inline new-item">
<div th:replace="common/layout :: flash"></div>
<fieldset>
<legend> Personal Information</legend>
<div class="row" th:classappend="${#fields.hasErrors('fullName')}? 'error' : ''" >
<input type="text" class="form-control input-sm" th:field="*{fullName}" placeholder="Full Name example Jane Doe"/>
<div class="error-message" th:if="${#fields.hasErrors('fullName')}" th:errors="*{fullName}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('date')}? 'error' : ''" >
<input type="date" class="form-control input-sm datepicker" th:field="*{date}"
placeholder="Date Of Birth"/>
<div class="error-message" th:if="${#fields.hasErrors('gender')}" th:errors="*{date}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('Nationality')}? 'error' : ''" >
<input type="text" class="form-control input-sm autocomplete" th:field="*{Nationality}"
placeholder="Nationality"/>
<div class="error-message" th:if="${#fields.hasErrors('Nationality')}" th:errors="*{Nationality}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('email')}? 'error' : ''" >
<input type="text" class="form-control input-sm" th:field="*{email}"
placeholder="Email example jane.doe#example.com"/>
<div class="error-message" th:if="${#fields.hasErrors('email')}" th:errors="*{email}"></div>
</div>
<div class="row" th:classappend="${#fields.hasErrors('married')}? 'error' : ''" >
<select th:field="*{married}" class="form-control input-lg">
<option value="">[Select Martial Status]</option>
<option value="Single">Single</option>
<option value="Married">Married</option>
</select>
<div class="error-message" th:if="${#fields.hasErrors('married')}" th:errors="*{married}"></div>
</div>
<div class="row">
<input type="text" class="form-control input-sm" th:field="*{guardianTelephoneNumber}"
placeholder="Guardian Telephone Number"/>
</div>
<div th:classappend="${#fields.hasErrors('courseOffered')}? 'error' : ''">
<input type="text" th:field="*{courseOffered}" placeholder="CourseOffered"/>
<div class="error-message" th:if="${#fields.hasErrors('courseOffered')}" th:errors="*{courseOffered}"></div>
</div>
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-primary">Add</button>
</div>
</fieldset>
</form>
Your question doesn't really make sense to me. If you want to check a single field from the database, then you can't pass a list of items. For example, in your html:
<div th:each="certs : ${certificateProgrammes}">
<form th:if="${certs.flag == 'TRUE'}">
.
.
.
</form>
</div>
It's going through the list of ${certificateProgrammes} and assigning it to ${certs} each time in the loop. If you don't want to loop, then instead of adding Iterable<CertificateProgramme> certificateProgrammes = certificateService.findAll(); to the model, just add a single object of type CertificateProgramme. Then you can do:
model.addAttribute("certs", /* however you get the specific one you want to check */);
and in the html
<!-- no iterating required, because you know which object you're talking about -->
<form th:if="${certs.flag == 'TRUE'}">
Why can I not get the text from this element?
Elements el = doc.select("#Core_UI_AutogeneratedID_0 > fieldset:nth-child(1) > p:nth-child(23)");
for (Element e : el) {
System.out.println(e.text());
}
I am connecting to the website fine, it's this line that's the issue
Elements el = doc.select("#Core_UI_AutogeneratedID_0 > fieldset:nth-child(1) > p:nth-child(23)");
How would I print an Element?
HTML format:
<div class="Content">
<fieldset class="TableLike FixedLabelSmall Narrow">
<label>Age:</label>
<p class="Value" title="9 d 21 h ">9 d 21 h </p>
<div class="Clear"></div>
<label>Created:</label>
<p class="Value" title="06/13/2015 11:10">06/13/2015 11:10</p>
<div class="Clear"></div>
<label>State:</label>
<p class="Value" title="closed successful">closed successful</p>
<div class="Clear"></div>
<label>Locked:</label>
<p class="Value" title="unlock">unlock</p>
<div class="Clear"></div>
<label>Priority:</label>
<p class="Value" title="3 normal">3 normal</p>
<div class="Clear"></div>
<label>Queue:</label>
<p class="Value" title="Sydney">Sydney </p>
<div class="Clear"></div>
<label>Service:</label>
<p class="Value" title="SUV">SUV</p>
<div class="Clear"></div>
<label>Service Level Agreement:</label>
<p class="Value" title="**I WANT THIS TEXT**">Sydney SLA</p>
<div class="Clear"></div>
</fieldset>