Thymeleaf does not recognize the span-tag - html-table

I just wanted to have different colors for the different enum values in my DataTable. I also need th:text for my filter I created.
What can I do so that I can use th:text and keep my span formatting?
<td class="incident" th:text="${ticket.getStatus().toString()}">
<a th:if="${ticket.getStatus().toString()} == 'OPEN'">
<span th:text="${ticket.getStatus().toString()}" class="badge text-white" style="background-color: #F93154"></span>
</a>
<a th:if="${ticket.getStatus().toString()} == 'IN_PROCESS'">
<span th:text="${ticket.getStatus().toString()}" class="badge text-white" style="background-color: #FFEA00"></span>
</a>
<a th:if="${ticket.getStatus().toString()} == 'CLOSED'">
<span th:text="${ticket.getStatus().toString()}" class="badge text-white" style="background-color: #00E676"></span>
</a>
</td>

Change this:
<td class="incident" th:text="${ticket.getStatus().toString()}">
to this:
<td class="incident">
The reason is that the th:text expression in the <td> tag will cause all child content to be ignored.
You can also clean up the Thymeleaf a bit by changing getStatus() to just status, since Thymeleaf will automatically apply JavaBean naming rules to the field name status and acutally invoke getStatus() behind the scenes.
I would also recommend considering updating your enum, so that it can return string values directly - see Using Enum values as String literals. This will further allow you to simplify your Thymeleaf, and get rid of all those .toString() methods embedded in the template.
For example, assume you have the enum:
public enum Status {
OPEN, IN_PROCESS, CLOSED;
}
You can change that to the following:
public enum Status {
OPEN("Open"),
IN_PROCESS("In Process"),
CLOSED("Closed");
private final String label;
private Status(String s) {
label = s;
}
public String getLabel() {
return label;
}
// toString and comparison methods not shown
}
Now each enum has a related string value (the "label") which you can use as follows:
<table>
<td class="incident">
<a th:if="${ticket.status.label} == 'Open'">
<span th:text="${ticket.status.label}"
class="badge text-white"
style="background-color: #F93154"></span>
</a>
<a th:if="${ticket.status.label} == 'In Progress'">
<span th:text="${ticket.status.label}"
class="badge text-white"
style="background-color: #FFEA00"></span>
</a>
<a th:if="${ticket.status.label} == 'Closed'">
<span th:text="${ticket.status.label}"
class="badge text-white"
style="background-color: #00E676"></span>
</a>
</td>
</table>

Related

Vue - change/set a variable value in template

Working in Vue, I am trying to set a variable based on another variable within the template. This is within a loop, and I need to set a value that can be used in 'next' iteration of the loop (to change the way a table is rendered, based on the variable).
I have the following:
<template>
...
<tbody v-for="(lo,index) in learn" :key="lo.id">
<tr>
<td colspan="2">LO{{index+1}} {{lo.attributes.field_lo}}</td>
<td v-if="!nextDist"> </td>
</tr>
<tr>
<td>
<div
v-for="(pass,index) in lo.attributes.field_pass"
:key="index"
>P{{pStep()}} {{pass}}</div>
</td>
<td>
<div
v-for="(merit,index) in lo.attributes.field_merit"
:key="index"
>M{{mStep()}} {{merit}}</div>
</td>
<td v-if="lo.attributes.field_dshared && next" ***SET VALUE OF this.next*** rowspan="3">
<span class="has-text-weight-bold">D{{dStep()}} </span>{{lo.attributes.field_dist}}
</td>
<td v-else-if="!lo.attributes.field_dshared" ***SET VALUE of this.next*** ><span class="has-text-weight-bold">D{{dStep()}} </span>{{lo.attributes.field_dist}}
</td>
***else render nothing***
</tr>
</tbody>
</template>
export default {
name: "SpecUnit",
components: {
EssentialContent
},
data() {
return {
unit: "",
learn: "",
nextDist: "",
next: ""
};
},
...
}
What I'd like to be able to do is set the value of 'next' (this.next) so that when the loop iterates, I can check to see if I should which of the I should render or render nothing (because we are 'rowspanning').
I've tried computed and methods, but can't seem to get this working. I've looked to use Vue.set, but I'm struggling with that.
I'm still new to Vue, so any help would be greatly appreciated.
Thanks
It looks like Florian Reuschel had a similar problem and already solved it (although with some caveats)
Let's say we have something like that:
<!-- List.vue -->
<ul>
<li v-for="id in users" :key="id">
<img :src="getUserData(id).avatar"><br>
🏷️ {{ getUserData(id).name }}<br>
🔗 {{ getUserData(id).homepage }}
</li>
</ul>
His approach is to use a helper renderless component with a scoped slot
const Pass = {
render() {
return this.$scopedSlots.default(this.$attrs)
}
}
and then
<!-- List.vue -->
<ul>
<Pass v-for="id in users" :key="id" :metadata="getUserData(id)">
<li slot-scope="{ metadata }">
<img :src="metadata.avatar"><br>
🏷️ {{ metadata.name }}<br>
🔗 {{ metadata.homepage }}
</li>
</Pass>
</ul>
If you take a look at the comments section on his blog article, you will see other approaches, too. For example, you can use an expression inside v-bind
<li v-for="id in users" :key="id" :demo="item = getUserData(id)">
<img :src="item.avatar" /><br />
🏷️ {{ item.name }}<br />
🔗 {{ item.homepage }}
</li>

How can I find the exact value using xpath in selenium webdriver for text that contains ?

I'm having an issue selecting the exact text 'Section' from the code using xpath.
** To be clear I require the exact text selection to be made from the innerText or innerHTML of the element if that is possible, not the id. **
I'm able to use the contains text function, but that results in other partial matches that contain 'Section' being returned/highlighted as well:
//div[#aria-hidden='false']//ul/li[contains(text(),'Section')]
I've tried using the following methods, but I don't know if I've got the syntax correct, as nothing is returned/highlighted:
//div[#aria-hidden='false']//ul/li[text()='Section')]
//div[#aria-hidden='false']//ul/li[.='Section']
//div[#aria-hidden='false']//ul/li[normalize-space(.)='Section']
This is what is shown when inspecting the Section node:
<li id="GOS--/40" class="nodecollapsed item parent-node xh-highlight" style="" xpath="1">
Section <span class="child-count"></span>
</li>
This is what is shown in the element properties:
id: "GOS--/40"
innerHTML: "↵ Section <span class="child-count"></span>↵ "
innerText: " Section "
Here is the xml which shows the other partial matches that are returned:
<div class="selection-list-dialog modal-dialog Dialog">
<div class="modal-content">
<div class="modal-header SectionHeader">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<span class="modal-title" data-lang="StandardItems">Standard Items</span>
</div>
<div class="modal-body selection-list-container" style="margin-top: 30px" id="base">
<div>
<span data-lang="SelectItemInstructions">Select the items you are interested in from the list.</span>
</div>
<br/>
<div class="pull-left selection-tree-container">
<h4 class="selection-list-title">
<span data-lang="Available">Available</span>
</h4>
<ul class="selection-list selection-tree-list">
<li id="CS--/14" class="nodecollapsed item parent-node">
Country Section <span class="child-count"></span>
</li>
<li id="Sec1--/23" class="nodecollapsed item parent-node">
Section 1 <span class="child-count"></span>
</li>
<li id="Sec2--/24" class="nodecollapsed item parent-node">
Section 2 <span class="child-count"></span>
</li>
<li id="GOS--/40" class="nodecollapsed item parent-node">
Section <span class="child-count"></span>
</li>
<li id="RS--/43" class="nodecollapsed item parent-node">
Regional Section <span class="child-count"></span>
</li>
This was a tough one. The problem is that you have a number of similar options all containing "Section" in some flavor and it's hard to distinguish them apart. What adds to this is that each one contains a non-breaking space which means that normalize-space() won't work (directly) either.
But... I found that the below XPath will work.
//li[normalize-space()='Section\u00a0']
normalize-space() removes whitespace (but not &nbsp) so you have to add it in there with \u00a0. I've tested this locally and it's working.
Try following xpath see if it helps.
//li[starts-with(#id,'GOS')][#class='nodecollapsed item parent-node xh-highlight']
OR
//li[#class='nodecollapsed item parent-node xh-highlight'][#xpath='1']
you can try the below XPath to find a section node
Try if it helps
//li[#id='GOS--/40'][contains(text(),'Section')]
Let me throw my hat into the ring....
//li[(normalize-space(text()) = 'Section')]
Here is the method that will fetch the text from the parent only. (exclude the text in the child(ren))
In Python:
def get_pure_element_text(element):
return driver.execute_script(
"""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element).strip()
This method will iterate all the firstChild (direct children) and extract all text from all the text nodes.
In this context If you want to retrieve the text of li which have the id GOS--/40 then use the method as below.
element = driver.find_element_by_xpath("//li[#id='GOS--/40']")
print(get_pure_element_text(element))
Sharing this method, at least might help the others (if not the OP in this context).
C# implementation:(not tested)
string get_pure_text(IWebDriver driver, IWebElement element){
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
return (string)js.ExecuteScript(""""
var parent = arguments[0];
var child = parent.firstChild;
var textValue = "";
while(child) {
if (child.nodeType === Node.TEXT_NODE)
textValue += child.textContent;
child = child.nextSibling;
}
return textValue;""",
element");
Usage:
string output = get_pure_text(driver,element)

Angular 5 trying to loop through array with ngIf's to show spans gives me all of them

I am trying to loop trough an array of objects that have an array of "dependent"-objects in them. For every dependent there is an array of, up to three ENUMS, AssignmentRoles. So for every AssignmentRole I want to display some html. My problem is I am displaying all three of the AssignmentRoles for every dependent even though they dont have every AssignmentRole in their AssignmentRole Array. This is what I am working with, and trying to do:
The object:
and this is the html:
<tr *ngFor="let assignment of filteredAssignments">
<td>
<ul class="dependent-entities" *ngFor="let dependent of assignment.DependentEntities">
<li class="filterable">
<span class="assignment-roles">
<ng-container *ngIf="dependent.AssignmentRoles[0] == AssignmentRole.HRResponsible">
<span class="hr-responsible"
HR
</span>
<input data-val="true"
name="AssignmentRole[0]"
type="hidden"
value="HRResponsible">
</ng-container>
<ng-container *ngIf="dependent.AssignmentRoles[1] == AssignmentRole.SoFContact">
<span class="sof-contact">
SF
</span>
<input data-val="true"
name="AssignmentRole[0]"
type="hidden"
value="SoFContact">
</ng-container>
<ng-container *ngIf="dependent.AssignmentRoles[2] == AssignmentRole.GeneralContact">
<span class="general-contact">
G
</span>
<input data-val="true"
name="AssignmentRole[0]"
type="hidden"
value="GeneralContact">
</ng-container>
</span>
</li>
</ul>
</td>
</tr>
*Edit, I placed the spans in ng-containers and removed the ngFor. Here is an image of how it looks. The first row is correct, the second should not be empty, the third is correct and the fourth should not be empty... So every other one is empty..
I got it working by removing the index e.g *ngIf="dependent.AssignmentRoles == AssignmentRole.GeneralContact"

Selenium automation script for <input>tag working as select tag (drop down) with checkbox in it for multiple selection?

Can anybody help me to find a solution on here
Selenium automation script for <input> tag working as select tag (drop down) with checkbox in it for multiple selection.
The values selected are reading from excel file. Please find below code trial :
List<WebElement> elements = (List<WebElement>) driver
.findElements(By.id("ctl00_ContentPlaceHolder1_rcbClinicians_Input"));
int numberOfElements = elements.size();
System.out.println("----size----- " + numberOfElements);
for (int i = 0; i < numberOfElements; i++) {
System.out.println(i);
elements = driver.findElements(By.id("ctl00_ContentPlaceHolder1_rcbClinicians_Input"));
elements.get(i).click();
}
Please help me find a solution
<li>Choose Clincians* </li>
<li>
<div id="ctl00_ContentPlaceHolder1_rcbClinicians" class="RadComboBox RadComboBox_Default" style="width:500px;white-space:normal;">
<table summary="combobox" style="border-width:0;border-collapse:collapse;width:100%" class="rcbFocused">
<tbody><tr>
<td style="width:100%;" class="rcbInputCell rcbInputCellLeft"><input name="ctl00$ContentPlaceHolder1$rcbClinicians" type="text" class="rcbInput" id="ctl00_ContentPlaceHolder1_rcbClinicians_Input" value="" autocomplete="off"></td>
<td class="rcbArrowCell rcbArrowCellRight"><a id="ctl00_ContentPlaceHolder1_rcbClinicians_Arrow" style="overflow: hidden;display: block;position: relative;outline: none;">select</a></td>
</tr>
</tbody></table>
<input id="ctl00_ContentPlaceHolder1_rcbClinicians_ClientState" name="ctl00_ContentPlaceHolder1_rcbClinicians_ClientState" type="hidden" autocomplete="off" value="{"logEntries":[],"value":"","text":"","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false}">
</div>
</li>
</ul>
<ul>
<li>Choose CaseManagers* </li>
<li>
<div id="ctl00_ContentPlaceHolder1_rcbCaseManagers" class="RadComboBox RadComboBox_Default" style="width:500px;white-space:normal;">
<table summary="combobox" style="border-width:0;border-collapse:collapse;width:100%" class="">
<tbody><tr>
<td style="width:100%;" class="rcbInputCell rcbInputCellLeft"><input name="ctl00$ContentPlaceHolder1$rcbCaseManagers" type="text" class="rcbInput" id="ctl00_ContentPlaceHolder1_rcbCaseManagers_Input" value="" autocomplete="off"></td>
<td class="rcbArrowCell rcbArrowCellRight"><a id="ctl00_ContentPlaceHolder1_rcbCaseManagers_Arrow" style="overflow: hidden;display: block;position: relative;outline: none;">select</a></td>
</tr>
</tbody></table>
<input id="ctl00_ContentPlaceHolder1_rcbCaseManagers_ClientState" name="ctl00_ContentPlaceHolder1_rcbCaseManagers_ClientState" type="hidden" autocomplete="off" value="{"logEntries":[],"value":"","text":"","enabled":true,"checkedIndices":[],"checkedItemsTextOverflows":false}">
</div>
</li>
</ul>
I don't see anything in your code that you are reading values from Excel. if you want to select value one by one yu can call this below method n time witch the the value you want to select. If you want multiple selection you can modify it with a for loop to do so.
/**
* #author mbn217
* #Date ------
* #Purpose This method will select a element from a list of
* values by the name passed in the parameter
* #param element --> element of the webpage (the weblist element)
* #param Name --> The value we want to select
* #return N/A
*/
public static void selectElementByName(WebElement element, String Name) {
Select selectitem = new Select(element);
selectitem.selectByVisibleText(Name);
}

Vue access iteration item inside method from template

Learning Vue and stuck.
I am trying to access user in each of the methods to confirm true/false values for each isHuman and isPlayerTurn functions. How do I access the user in the loop instance inside each method?
I have the following table row in a template:
<template>
<div class="col-xs-12">
<h5>Enemies online</h5>
<span id="no-online-players" class="player-label pull-right">{{ usersCount }}</span>
<table id="new-game-opponents" class="new-game-opponents">
<tbody>
<tr v-for="(user, index) in users" :key="index" :class="[isPlayerTurn() ? playerTurnClass : '']">
<td class="player-status text-right">
<div v-if="isPlayerTurn">
<span :id="['player_turn-' + user.owner_id]" class="stage-label pull-right">{{ progress }}</span>
</div>
<div v-else>
<i class="fa fa-clock-o" aria-hidden="true" style="margin-right:5px;"></i>
</div>
</td>
<td class="player-status text-right">
<div v-if="isHuman">
<i class="fa fa-desktop" aria-hidden="true"></i>
</div>
<div v-else>
<i class="fa fa-user" aria-hidden="true" style="margin-right:2px;"></i>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
props: ['users', 'usersCount'],
data: function () {
return {
playerTurnClass: 'next-player-turn',
myPlayer: my_player,
progress: game.progress.status.turn_status.current_stage
}
},
methods: {
isPlayerTurn: function(user, index) {
return this.myPlayer.id === this.users[index]['id'];
},
isHuman: function(user, index) {
return this.users[index]['owner_id'] !== 'ai';
}
}
};
</script>
I am trying to access user in each of the methods to confirm true/false values for each isHuman and isPlayerTurn functions.
How do I access the user in the loop instance inside each method? Or should I be doing this a different way?
Additionally, the progress property is not rendered. But one step at a time!
First of all, try
<div v-if="isPlayerTurn(user, index)">...</div>
and
<div v-if="isHuman(user, index)">...</div>
I noticed you don't really use user in both isPlayerTurn and isHuman methods, so I suggest leaving user out.
And regarding progress, I don't know where game is from, but I'm guessing the value in game.progress.status.turn_status.current_stage is dynamic, so I suggest you first try changing progress to a computed property:
computed: {
progress() {
return game.progress.status.turn_status.current_stage
}
}