How to add id to items when using v-for in VueJS - vue.js

I have a data table and when I render those records on the website, I will add ids to the elements, each element is a different id(id="item-first"), so what to do?
<div class="" v-for="(item, index) in producthots" :key="index">
<div
:class="
index % 2 == 0 ? 'product-item row-reverse' : 'product-item'
"
>
I want when rendered, each element will have an id object

for adding id you can bind it as like as :src and :class, it would be like this :id look at the example below:
<div :id="'CollapseState' + index" aria-expanded="false"
class="ChangeState bg-white collapse"></div>
I binded the id and also for making it uniq I added + index end of it so the short answer is below code:
:id="'CollapseState' + index"

Related

Vue check in nested v-for if a record doesn't exist

I am trying to build a table where rows are items (first v-for), columns are locations (second v-for), cells are item_locations (third -v-for).
If for a certain location the item is present (hence an item_location object) I want to print yes, else I want to print No.
<div v-for="item in items" :key="item.id>
{{item.name}}
<div v-for="location in locations" :key="location.id">
<div v-for="item_location in location.item_locations" :key="item_location.id">
</div>
</div>
</div>
By adding this in the third loop:
<p v-if="item_location.item_id == item.id">Yes</p>
I it correctly prints yes for combination of item/location for which there is an item_location.
What I am unable to do is to print No only for the combinations of item/location for which an item_location object does not exist. To further clarify, item_locations is a joining table.
A little confused on what your asking but Im going to suggest this
Your nested v-for must use the property declared from its parent like so
<div class="table-cell" v-for="location in locations" :key="location.id">
<div v-for="item_location in location.item_locations" :key="item_location.id">
<div v-if="item_location.location_id == location.id ">Yes</div>
<div v-else>No</div>
</div>
</div>
so the nested v-for would be location.item_locations and if your only checking for one condition you can just do a v-else.
I solved this way:
<div v-for="item in items" :key="item.id>
{{item.name}}
<div v-for="location in locations" :key="location.id">
<div>{{filterLocation(item, location)}}</div>
</div>
</div>
filterLocation: function(item, location) {
let value = item.item_locations.filter(item_location => {
return item_location.location_id == location.id;
});
var that = this;
that.item_location_exists = value.length;
},
And in template I can do a conditional as item_location_exists equals to 0 or 1.

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)

Dynamic binding of class based on index in v-for

<transition-group appear name="fade" class="row no-gutters" v-if="currentTab === 'living'">
<div class="col-6 pr-3 pb-3" :class="[ isEven(index) ? 'col-md-8' : 'col-md-4']" v-for="(item, index) in livingGallery" :key="'living' + index">
<img :src="item.photoThumbSmall" alt="Gallery Photo index" class="d-block w-100">
</div>
</transition-group>
This is the code for isEvent:
methods: {
isEven(i) {
return i / 2 === 0;
}
},
I need to render the div different based on the index. div with even index gets the class col-md-8, otherwise col-md-4.
This is what I expected from the code:
index 0 => col-md-8
index 1 => col-md-4
index 2 => col-md-8
......
However, only the first element has col-md-8. The remaining elements are assigned col-md-4.
What's the problem?
You want to do i modulus 2, not divided by 2.
isEven(i) {
return i % 2 === 0;
}
i / 2 will only ever be 0 if i is 0. Since you want to know whether the given index is even, you should check the remainder of the division, which is what the modulus operation returns.

how to embed a span tag in a list iteration in vue

New to vuejs and I would like to be able to output something like
<div>
<span>
item 1
item 2
</span>
<span>
item 3
item 4
</span>
</div>
I have tried with the following but doesn't seem to work. I think th issue is the <span> tag and straight text works fine. How would I make Vuejs output a span or is there a different way to achieve this?
<div v-for="(item,idx) in selectedItems">
<span v-if="(idx % 2) == 0" v-html="rawHtml"><span></span>
{{item.display_name}}
<span v-if="((idx-1) % 2) == 0" v-html="rawHtml"></span></span>
</div>
Try next variant:
<div>
<span v-for="(item, idx) in selectedItems"
v-if="idx % 2 === 0">
<p>{{item.display_name}}</p>
<p v-if="selectedItems[idx + 1]">{{selectedItems[idx + 1].display_name}}</p>
</span>
</div>

Dynamic buttons added to the page, don't know how to find the element

I have a complected structure of the page and I have no idea how to find the element...
The page contains folders that are created by a user, I need to create a folder and then to click on it, but I have no idea how to find the element that I've created. The structure look like this:
<div class="row-text" style="width: calc(100% - 84px);">
<span class="row-item-name">
<span class="row-item-link">
<a class="grid-row-element-name">Eclipse111</a>
</span>
<span class="row-item-actions hover-child">
<a>Share</a><span> | </span><a watchdox-rename="name" watchdox-save-func="rename(element, name)" class="rename-link"><span translate="">Rename</span></a>
</span>
</span>
<br>
<span class="row-meta-data">
<span class="creation-date-formatted">Today at 10:30 | </span>
<span class="row-email">orgadmin#mailinator.com</span>
</span>
</div>
<div class="grid-row-buttons">
<div class="row-tools">
<div class="btn-group dropdown" uib-dropdown="">
<button type="button" class="btn btn-default uib-dropdown-toggle clear-button dropdown-toggle" uib-dropdown-toggle="" aria-haspopup="true" aria-expanded="false">
<span class="icon-wd-material-menu"></span>
</button>
<ul uib-dropdown-menu="" class="dropdown-menu-highZ contextual-menu dropdown-menu" role="menu">
</ul>
</div>
</div>
</div>
The class="grid-row-element-name" contains the name of the folder that was created (each folder has its own )....
I have no idea how to continue with the testing cause I am not able to click on the folder....
Thank you.
try the following, since you said "grid-row-element-name" has the folder name then trying using that class name in cssSelector.
List<WebElement> elements = driver.findElements(By.cssSelector("a.grid-row-element-name"));
String folderName = null; //name of the folder which you want to click.
for (WebElement ele : elements) { //Iterate over the loop
if (ele.getText().equalsIgnoreCase(folderName)) {
ele.click();//once the folder you want is found go for the click.
}
}
//OR
//To click on the last element try this
elements.get(elements.size()-1).click();
Since you are looking for an element with specific text that you have created (the folder name), I would approach this by looking for an A tag that contains the folder name.
BTW, you didn't tag your question with a language so the below is Java. You should be able to convert it easily to another language by just reusing the XPath, if needed.
String folderName = "Eclipse111";
// create folder
WebElement folder = driver.findElement(By.xpath("//a[text()='" + folderName + "']"));