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>
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 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 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.
what i want to accomplish is detect first the changes on the div(ng-repeat) list which is is the result of a search query and click the first result ,but my problem is the click event are already firing and selecting the already listed item which is must be the result the search
Search event
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.findElement(By.xpath("//*[#id='bs-example-navbar-collapse-1']/ul[2]/li[1]/div/input")).sendKeys(fname);
Click Event
WebDriverWait dList = new WebDriverWait(driver, 10);
dList.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[#id=\"top-menu-members\"]/div[1]/div")));
here is the div listing
<div class="list cursor-pointer ng-scope" ng-mouseenter="memberEntered(member)" ng-mouseleave="memberLeft(member)" ng-repeat="member in (members | orderBy:['-new','firstname'])" ng-hide="member.id == user.id" ng-init="member.name = member.firstname + ' ' + member.lastname;" ng-if="members.length">
<div class="settings pull-left blue" ng-click="selectMemberSubmenu(member); moveSubmenu($event, 2);">
<a href="#" ng-class="{ 'open': member.id == selectedMember.id }">
<i class="fa fa-caret-left" aria-hidden="true"></i>
</a>
</div>
<a ui-sref="members.task({ id: member.id })" ng-click="markAsSeen('member', member, $event, false)" href="/members/7E1C4A77-C29A-4121-B305-8766340F4DDA">
<div class="profpic members pull-left">
<div class="bg-image" style="background-image: url(/img/avatar-man.png)"></div>
</div>
<div class="info pull-left">
<p class="pull-left ng-binding">Kyben Jal</p>
<p class="pull-left role ng-binding">Company Manager</p>
</div>
<!-- ngIf: member.new --><div class="member-circle pull-right ng-scope" ng-if="member.new" ng-click="markAsSeen('member', member, $event)">
<img src="/img/notif.png">
</div><!-- end ngIf: member.new -->
</a>
</div>
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>