Thymeleaf: literals and variables in a HTML id - html

I have this piece of code in Thymeleaf:
<tr th:each="image: ${images}" >
<img id="|'idAwesomeIcon${image.id}'|" .. />
</tr>
also I tried
<tr th:each="image: ${images}" >
<img id=“idAwesomeIcon|${image.id}|" .. />
</tr>
also I tried
<tr th:each="image: ${images}" >
<img id="\'idAwesomeIcon' + ${image.id} +'\'" .. />
</tr>
expecting the id to be replace with something like idAwesomeIcon666 but when I see the source code of the HTML page there is no such a substitution and I can still see ${image.id}

You have to use th:id attribute if you want to dynamically populate values
<img th:id=“'idAwesomeIcon'+${image.id}" .. />

Related

Unable to extract value using xpath query

Learning to use xpath queries. I am having an issue were I am unable to extract a value that changes whenever the page is refreshed.
For example, I am trying to extract the value '62804' from the following html code: "canvas.strokeText('Answer: 62804',90,112);" . Any ideas how this can be done. Thanks
<html>
<div id="content" class="large-12 columns">
<div class="example">
<h3>Challenging DOM</h3>
<p>The hardest part in automated web testing is finding the best locators (e.g., ones that well named, unique, and unlikely to change). It's more often than not that the application you're testing was not built with this concept in mind. This example demonstrates that with unique IDs, a table with no helpful locators, and a canvas element.</p>
<hr>
<div class="row">
<div class="large-12 columns large-centered">
<div class="large-2 columns">
<a id="debcda40-b692-0137-457b-2213fbd48497" href="" class="button">qux</a><br>
<a id="debce410-b692-0137-457c-2213fbd48497" href="" class="button alert">baz</a><br>
<a id="debd03d0-b692-0137-457d-2213fbd48497" href="" class="button success">foo</a><br>
</div>
<div class="large-10 columns">
<table>
<thead>
<tr>
<th>Lorem</th>
<th>Ipsum</th>
<th>Dolor</th>
<th>Sit</th>
<th>Amet</th>
<th>Diceret</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr>
<td>Iuvaret0</td>
<td>Apeirian0</td>
<td>Adipisci0</td>
<td>Definiebas0</td>
<td>Consequuntur0</td>
<td>Phaedrum0</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret1</td>
<td>Apeirian1</td>
<td>Adipisci1</td>
<td>Definiebas1</td>
<td>Consequuntur1</td>
<td>Phaedrum1</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret2</td>
<td>Apeirian2</td>
<td>Adipisci2</td>
<td>Definiebas2</td>
<td>Consequuntur2</td>
<td>Phaedrum2</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret3</td>
<td>Apeirian3</td>
<td>Adipisci3</td>
<td>Definiebas3</td>
<td>Consequuntur3</td>
<td>Phaedrum3</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret4</td>
<td>Apeirian4</td>
<td>Adipisci4</td>
<td>Definiebas4</td>
<td>Consequuntur4</td>
<td>Phaedrum4</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret5</td>
<td>Apeirian5</td>
<td>Adipisci5</td>
<td>Definiebas5</td>
<td>Consequuntur5</td>
<td>Phaedrum5</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret6</td>
<td>Apeirian6</td>
<td>Adipisci6</td>
<td>Definiebas6</td>
<td>Consequuntur6</td>
<td>Phaedrum6</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret7</td>
<td>Apeirian7</td>
<td>Adipisci7</td>
<td>Definiebas7</td>
<td>Consequuntur7</td>
<td>Phaedrum7</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret8</td>
<td>Apeirian8</td>
<td>Adipisci8</td>
<td>Definiebas8</td>
<td>Consequuntur8</td>
<td>Phaedrum8</td>
<td>
edit
delete
</td>
</tr>
<tr>
<td>Iuvaret9</td>
<td>Apeirian9</td>
<td>Adipisci9</td>
<td>Definiebas9</td>
<td>Consequuntur9</td>
<td>Phaedrum9</td>
<td>
edit
delete
</td>
</tr>
</tbody></table>
<div class="row">
<div class="large-10 columns">
<canvas id="canvas" width="599" height="200" style="border:1px dotted;"></canvas>
</div>
</div>
</div>
</div>
</div>
<hr>
</div>
<script>
var canvas_el = document.getElementById('canvas');
var canvas = canvas_el.getContext('2d');
canvas.font = '60px Arial';
canvas.strokeText('Answer: 62804',90,112);
</script>
</div>
</html>
In order to use the XPath query the input document must be a valid XML.
In your case it isn't, because there are some tags that are not properly closed (you can verify it using an XMLLint tool).
E.g.
<hr> and <br> should be replaced with <hr/> and <br/>.
Once the XML is corrected, you can use an XPath query.
The fist step is select the script element:
//script
The output is:
Element='<script>
var canvas_el = document.getElementById('canvas');
var canvas = canvas_el.getContext('2d');
canvas.font = '60px Arial';
canvas.strokeText('Answer: 62804',90,112);
</script>'
Then you have to convert the Element Node in a String and then perform some parsing:
substring-before(substring-after(//script/text(), 'canvas.strokeText(''Answer: ') , ''',90,112)')
The result is the following:
String='62804'
Note: You can do the same operation in a more elastic way using Javascript, for example.
XPath is very good to query an XML (like the first operation that I mentioned) but quite complicated to do String parsing (like the second operation that I mentioned).
Hope it can help.

Use XPath in nodeset repeater (XForms)

I have a question about XPath and the nodeset repeater (XForms).
As you can see in the following code snippet I want to change an attribute of a specific entry of a list and additionally an attribute in the following entry in the nodeset with a trigger.
The first <xf:action> works fine but the second does not. What I want here is to leave the current nodeset of the processinstance, go to the following one and change the attribute state here. How do I realize that with XPath?
<div>
<xf:model>
<xf:instance xmlns="" id="template">
<project id="">
<name/>
...
<processinstance>
<name>
<state>
</processinstance>
</project>
</xf:instance>
</xf:model>
....
<!-- Process repeat table -->
<div>
<table class="table table-hover">
<thead>
<th width="50%">Processname</th>
<th width="50%">State</th>
<th width="50%">Action</th>
</thead>
<tbody id="process-repeat" xf:repeat-nodeset="//project[index('project-repeat')]/processinstance">
<tr>
<td>
<xf:output ref="name"/>
</td>
<td>
<xf:output ref="state"/>
</td>
<td>
<xf:group ref=".[state eq 'in processing']">
<xf:trigger appearance="minimal">
<xf:label>finish process</xf:label>
<xf:action>
<xf:setvalue ref="state">finished</xf:setvalue>
</xf:action>
<!-- THE FOLLOWING DOES NOT WORK AS I WANT! -->
<xf:action>
<xf:setvalue ref="//project[index('project-repeat')]/processinstance[index(process-repeat)+1]">in process</xf:setvalue>
</xf:action>
</xf:trigger>
</xf:group>
</td>
</tr>
</tbody>
</table>
</div>
</div>
Best regards,
Felix
One thing is that you have a typo:
index(process-repeat)
vs.
index('process-repeat')
In addition, the index() function represents the currently selected, in the UI, repeat iteration. It does not represent the current iteration being evaluated in XPath.
The bottom line is that you cannot use index('process-repeat') to identify the current repeat iteration. It is a common misunderstanding of the index() function.
Some implementations have functions to identify the current repeat iteration. I assume you are using BetterFORM, and I don't know if it has such a function. With Orbeon Forms you could write:
//project[index('project-repeat')]/processinstance[xxf:repeat-position()]
Or better, if betterFORM supports variables, you could use that to avoid repeating yourself with:
<tbody id="process-repeat" xf:repeat-nodeset="//project[index('project-repeat')]/processinstance">
<xf:var name="current-process" value="."/>
<tr>
<td>
<xf:output ref="name"/>
</td>
<td>
<xf:output ref="state"/>
</td>
<td>
<xf:group ref=".[state eq 'in processing']">
<xf:trigger appearance="minimal">
<xf:label>finish process</xf:label>
<xf:action>
<xf:setvalue ref="state">finished</xf:setvalue>
</xf:action>
<xf:action>
<xf:setvalue ref="$current-process">in process</xf:setvalue>
</xf:action>
</xf:trigger>
</xf:group>
</td>
</tr>
</tbody>

ASP.NET 1.1 - VB.NET HTML Markup not reading variable from Code-Behind

I am trying to dynamically change the values inside my HTML markup depending on certain conditions in the code-behind.
In my code-behind in the Page_Load(), I have the following:
If Not myCheck = 1 Then
mySuffix = "_gr"
myColor = "#cccccc"
Else
mySuffix = ""
myColor = "#bdd1ec"
End If
This is used for my HTML markup to change the way the page looks on certain conditions.
<table>
...
<tr>
<td style="background-color: <%=myColor%>" colSpan="6"><IMG height="5" src="/images/corner-inner-blue-topLeft<%=mySuffix%>.gif" width="5"></td>
<td style="background-color: <%=myColor%>; text-align:right"><IMG height="5" src="/images/corner-inner-blue-topRight<%=mySuffix%>.gif" width="5"></td>
</tr>
...
</table>
Now my problem is this. It works on the suffix but not on the color.
When I run my site, navigate to the page, and I do an inspect element, I get this.
<table>
...
<tr>
<td style="background-color: <%=myColor%>" colspan="6"><img src="/images/myImg_gr.gif" height="5" width="5"></td>
<td style="background-color: <%=myColor%>; text-align:right"><img src="/images/myImg_gr.gif" height="5" width="5"></td>
</tr>
...
</table>
It's reading the <%=mySuffix%> variable from my code-behind but not the <%=myColor%>.
I tried debugging just to be sure that it does pass something to the variable and it does.
Can someone help me point out which I am doing wrong? Or is there any other better way to achieve this?
Thanks a lot!
If not using the table is an option, you might consider using a span or div element, and give it an id, instead of using a <td> element. Then you can reference the span control inside the code-behind to set the style properties. Like this:
ASPX:
<span id="spnSample" runat="server">Hello</span>
.VB:
If Not myCheck = 1 Then
mySuffix = "_gr"
spnSample.Style.Add("background-color", "#cccccc")
Else
mySuffix = ""
spnSample.Style.Add("background-color", "#bdd1ec")
End If

How do i get the HTML element in the same row as a XPATH Contains?

I am using Selenium with Python. I have a table. I found the row which has the text 'Honorable' in it by using this Xpath :-
element = driver.find_element_by_xpath("//*[contains(., 'Honorable')]")
Now I need to click the Edit button which has the below HTML (taken from Chrome's Inspector Tools)
<a id="prefixmasterListForm:prefixMasterTable:0:editLink
The full HTML is:
<tr class="rich-table-row rich-table-firstrow ">
<td class="rich-table-cell " id="prefixmasterListForm:prefixMasterTable:0:j_id347" width="auto">
Honorable
</td>
<td class="rich-table-cell alignCenter" id="prefixmasterListForm:prefixMasterTable:0:j_id350" width="auto">
<img id="prefixmasterListForm:prefixMasterTable:0:activeic" src="images/yes.gif" alt="active">
</td>
<td class="rich-table-cell " id="prefixmasterListForm:prefixMasterTable:0:j_id352" width="auto">
General Prefix
</td>
<td class="rich-table-cell " id="prefixmasterListForm:prefixMasterTable:0:j_id360" width="auto">
MALE
</td>
<td class="rich-table-cell " id="prefixmasterListForm:prefixMasterTable:0:column6" width="auto">
<a id="prefixmasterListForm:prefixMasterTable:0:editLink" href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.forms['prefixmasterListForm'],'prefixmasterListForm:prefixMasterTable:0:editLink,prefixmasterListForm:prefixMasterTable:0:editLink,prefixMasterId,15661602','');}return false">
<img src="images/iconedit.gif" alt="Edit" class="image">
</a>
<a id="prefixmasterListForm:prefixMasterTable:0:deleteLink" href="#" onclick="if(typeof jsfcljs == 'function'){jsfcljs(document.forms['prefixmasterListForm'],'prefixmasterListForm:prefixMasterTable:0:deleteLink,prefixmasterListForm:prefixMasterTable:0:deleteLink,prefixMasterId,15661602,prefixMasterName,Honorable','');}return false">
<img src="images/icondelete.gif" alt="delete" class="image">
</a>
</td>
</tr>
How do i get hold of that Edit link element using XPath?
Based on Arran's help i also checked that the column next to 'Honorable' has an image with alt=inactive like this
"//td[normalize-space(text())='Honorable']/following-sibling::td[img[#alt='inactive']]"
//td[normalize-space(text())='Honorable']/following-sibling::td//a[.//img[#alt='Edit']]
The td that has it's text equal to 'Honorable', then get the td following it, that has an a inside it, which has an image within it that has it's alt attribute set to 'Edit'
Easy: //tr[td[contains(., 'Honorable')]]/td/a[contains(#id, ':editLink)] - literally, the A contained in the TD contained in the TR that also contains a TD that contains the string "Honorable".
Try: //a[#id='prefixmasterListForm:prefixMasterTable:0:editLink']
P.S.If you want to verify or do some easy job with xpath, you can install FF + FireBug + FirePath

How to embed links (anchor tag) into HTML context from UIBINDER in gwt

I have a HTML widget in my ui.xml which I am using in Uibinder to populate data as given below:
ui.xml ->
<g:HTML ui:field="operationsDetailTableTemplate" visible="false">
<table class="{style.LAYOUT_STYLE}" width="100%" border="1">
<tr>
<td><img src="images/indent-blue.gif"/></td>
<td>
<table class="{style.DEFAULT_STYLE}">
<thead>
<tr>
<th>OperationUuid</th>
....
</tr>
</thead>
<tbody>
<tr>
<td>%s</td>
...
</tr>
</tbody>
</table>
</td>
</tr>
....
</g:html>
Uibinder.java--->
String htmlText = operationsDetailTableTemplate.getHTML()
.replaceFirst("%s", toSafeString(operation.getOperationUuid()))
....
HTML html = new HTML(htmlText);
operationsDetail.add(html);
The above is done in a for loop for each of the operation retrieved from the database.
My question is how I can embed a hyperlink or an anchor tag on one of the cell (eg. operation id ) for each of the operation set retrieved. I also wish to have a listener attached to it.
P.S. - It does not allow me to have a anchor tag in HTML in ui.xml.
You'd better use the tools in the way they've been designed to be used: use ui:field="foo" on the <td> and #UiField Element foo + foo.setInnerHTML(toSafeString(...)) instead of extracting the HTML, modifying it and reinjecting it elsewhere. You could also use a <g:Anchor> and attach an #UiHandler to handle ClickEvents.
Your way of using UiBinder makes me think of SafeHtmlTemplates, or the new UiRenderer aka UiBinder for Cells: https://developers.google.com/web-toolkit/doc/latest/DevGuideUiBinder#Rendering_HTML_for_Cells