I have a dynamic table rendering where columns and rows of the table are rendered dynamically.
So here I have two sibling <td> elements in each row:
<td :key="`td3-${index}`" :id="`show_${key}`" v-show="`show_${key}`">
<input type="text" :v-model="key" :name="key" :value="entry[key]" />
</td>
<td :key="`td4-${index}`">
Edit
</td>
In the onclick event of the link in the second <td> I have to show and hide the first <td> element. Since it's dynamic I will have multiple rows. So I declared a dynamic boolean in my data to show and hide the specific <td> based on the click of another <td> in the same row.
v-show="`show_${key}`" - this is show property with dynamic key
show_firstname: false,
show_lastname: false,
show_email: false,
show_orgname: false
I created separate boolean elements for every <td> in each row.
But whenever I change the value of v-show property with the on click of second <td> element it's not making any difference. So I could not show or hide the <td>. Maybe v-show takes "`show_${key}`" as a string value not replacing true or false correctly. Can someone help me how can I achieve this?
Why don't you try organising the show_ in an object instead of a flat list of properties?
https://codesandbox.io/embed/vue-template-csncc?fontsize=14&hidenavigation=1&theme=dark
Related
I have a component which displays the list of 'matches' and after click on particular cell it should show the concrete information about it (with help of child's function passData(value)). The data is displayed via v-for in a table:
...
<tr v-for="(value,key) in matches" v-bind:key="(value,key)">
<td v-on:click="passData(value)">{{value.match_id}}</td>
<td>{{value.duration}}</td>
<td>{{value.start_time}}</td>
...
<match ref="match"></match>
</tr>
...
So result what I want to achive should be like this:
when a user clikcs on a match it displays a 'card' with some info about it and if the user clicks on it again it hides.
To make it clear all components are working correctly. The problem is that I can't intgrate it into the v-for method. I just need to display a 'card' on the needed place. How can I do this?
What I am having now:
what you can do is something like this to show details of each row next to it if needed
<template v-for="(value,key) in matches">
<tr v-bind:key="(value,key)">
<td v-on:click="toggleData(value)">{{value.match_id}}</td>
<td>{{value.duration}}</td>
<td>{{value.start_time}}</td>
...
<match ref="match"></match>
</tr>
<tr v-bind:key="`${key}_details`" v-if="details[value.match_id]">
... show whatever you want
</tr>
</template>
and in toggleData(value)
if not present add it else remove it
this.details[value.match_id] = value // if single
this.details[value.match_id] = [] // OR if multiple
this.details[value.match_id].push(value)
I'm working with a table display and am using vueJS to render a group of rows inside of a table. The bindings inside of the <tr> work fine, but I can't figure out how to bind say an attribute that lives on the parent <tr> that hosts the v-for directive:
<tr v-for="detailItem in itemList" data-key="{detailItem.pk}}">
<td>{{detailItem.cdesc}}</td>
<td>{{(detailItem.nnetunits * 1).toFixed(2)}}</td>
...
</tr>
In this code the inner items on the <td> bind just fine, but how would you get the data-key bound?
With Vue 2 you don't use interpolation in attributes, you use the attribute binding syntax.
<tr v-for="detailItem in itemList" v-bind:data-key="detailItem.pk">
Or the shortcut
<tr v-for="detailItem in itemList" :data-key="detailItem.pk">
I need to perform validation against the table that is being displayed like this.
code sample how I'm trying to find the checkbox Element
//navigate t the second tr where the input and img tags are stored
List<WebElement> daysCheckBox = this.driver.findElements(By.xpath(".//*[#id='RULE_KEY']/div/div/div/div/div/center[1]/table[2]/tbody/tr[2]/td"));
System.out.println("Test checkbox");
for(WebElement td : daysCheckBox){
System.out.println(td.getTagName());
}
The problems I have is that this table come with 2 tags first row represents the days and the second "checkboxes" as you can see they line up with days, however checkbox have no link to each day. I have tried to solve this with reverse logic to try to identify the input tag if it is disabled. But when the box is selected it turns from input tag into img tag, also when I identify input tags I cannot pinpoint what day deselected box it corresponds to.
Does anyone have any advice or suggestion how to approach this type of validation?
Thank you.
I have put the source to make it clearer how the picture above is presented.
<tbody>
<tr bgcolor="whitesmoke">
<td><b>Sun</b></td>
<td><b>Mon</b></td>
<td><b>Tues</b></td>
<td><b>Wed</b></td>
<td><b>Thurs</b></td>
<td><b>Fri</b></td>
<td><b>Sat</b></td>
</tr>
<tr>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><img src="webwb/dhtmlx_iconcheckall.gif" /></td>
<td><input disabled="disabled" type="checkbox" /></td>
</tr>
</tbody>
You can create method which will convert Your table to Java Map for example:
public static Map<String,String> getTableAsMap(WebDriver driver)
{
Map<String,String> checkboxMap = new TreeMap<>();
List<WebElement> header = driver.findElements(By.xpath("((//tbody/tr)[1])/td/*"));
List<WebElement> checkboxes = driver.findElements(By.xpath("((//tbody/tr)[2])/td/*"));
for(int i = 0;i<header.size();i++){
//Only for testing purpose
System.out.printf("KEY: %s, VALUE: %s\n",header.get(i).getText(),checkboxes.get(i).getAttribute("disabled"));
checkboxMap.put(
header.get(i).getText(),
checkboxes.get(i).getAttribute("disabled")
);
}
return checkboxMap;
}
Then In your main class with driver use:
Webdriver driver = new FirefoxDriver();
Map<String,String> map = getTableAsMap(driver);
System.out.println(map.get("Fri"));
System.out.println(map.get("Sat"));
For disabled (non selected) checkbox You will receive true for selected there will be null. Both as String.
as you haven't posted the code, my answer also doesn't have a code :)
Create the WebElement for second row, i.e. xpath: //tbody/tr[2]
Now traverse all the tds inside this row and check their child element.
If the child element is input you know that checkbox is not selected else it is.
About for which day, you know the first is Sunday and Second is Monday and so on..
The Page Object Model approach may be effective to deal with this scenario. So, you can refresh your page object after some action/set of actions.
Since you mentioned that once a checkbox is checked the tag gets changed for the element, so I assume this can happen multiple times in the page based on user activity.
I can suggest that you implement a callback that reloads the and set the page objects on user action say click. With the page objects, you always have track of all the WebElements, accessibility and any change of state.
I captured the testName by using driver.find_element_by_xpath("//td[contains(.,'%s')]" % test_name)
How can I capture class name based on testName?
I am trying to click on menu-button if it contains specific test name
<tr class="row-1">
<td>testName</td>
<td>testDes</td>
<td class="menu">
<div class="menu-button">
</div>
</td>
</tr>
This is one possible XPath expression :
//tr[td[contains(.,'testName')]]/td[#class='menu']/div[#class='menu-button']
Basically the above XPath locate tr element having child td value equals "testName", then return the corresponding div[#class='menu-button'] element.
I try to get a href from an anchor according to linkText given with func param (for example here Westwood or Linda).
In the code below I changed classes values (cause of company info), but beside thats the code. For each <tr> the hrefs are identical for both <td>, but different from <tr> to <tr>
I get the 1st href with:
driver.findElemnt(By.xpath("//a[#class = 'class Name of a']").getAttribute("href")
or the same with:
xpath="//a[#class = 'class Name of a'][1]";
but when I go:
"//a[#class = 'class Name of a'][2]" or 3 or 4...
or when I use:
By.partialLinkText
It fails, so I never get beyond the 1st <td> of the first <tr>.
The Error: oopenqa.selenium.StaleElementReferenceException : Element
is no longer attached to the Dom.
The Elements are visible all the time, so its not a visibility problem.
This is the html:
<tr class="Class name for tr here">
<td headers="description _ CustomerList:lastName">
Westwood
</td>
<td headers="description _CustomerList:firstName">
Linda
</td>
</tr>
You're trying to retrieve the second anchor tag within the same parent (in the example document: table cells).
Instead of
//a[#class = 'class Name of a'][2]
query the second anchor tag in the whole document:
(//a[#class = 'class Name of a'])[2]
Some more examples how to use positional predicates (I omitted the class predicate here):
Anchor tags from all second table cells per row:
//td[2]/a
Second anchor tag per row:
//tr//a[2]