I have a bit of a dilemma. I have a table of 3 columns. Column 1 is a button to make that row active. The 2nd column is the name of the person. And the 3rd column is a button to view the person's details.
Using Selenium C#, I can search for a specific person in the table and click the button to View, using the code below:
currentDriver.FindElement(By.XPath("(.//*[normalize-space(text()) and normalize-space(.)='Name of person'])")).Click();
How do I select the button before the name of the person?
EDIT: Added HTML -
<table class="table table-hover>
<thead>...</thead>
<tbody id="listCompany">
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" ><i class="fas fa-times"></i></span>
</td>
<td>Test Director</td>
<td>
<button.>...</button>
</td>
</tr>
</tbody>
The class btnActivateCompany is used several times depending on how many rows exist. And the id changes depending on the rows as well. So I have to search to find the correct record and then select the span before it.
I tried the following to select the object:
currentDriver.FindElement(By.XPath("(.//*[normalize-space(text()) and normalize-space(.)='Test Director'])[1]/preceding::span[1]")).Click();
I get the feeling you've modified the HTML as you've posted. I guess you stripped out some data and typed other content in. You say you want the button before the person, but in your code the button is after the person?
Either way, both are achievable. I made a few quick additions to help visibility. If i'm wrong please correct me as it influences xpaths.
Quick change log: I ran your html through a beautifier, added text to all the columns for visibility, added "border=1" to the table, remove the . from button, added the </table> and duplicated the row so i can check unique objects are found.
This is the result: (useful if anyone else wants to chip in an identifier)
<html>
<body>
<table class="table table-hover" border=1>
<thead>...</thead>
<tbody id="listCompany">
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" >
<i class="fas fa-times"> Column 1</i>
</span>
</td>
<td>Test Director</td>
<td>
<button> Button in col 3
</button>
</td>
</tr>
<tr>
<td>
<span id="a5" class="badge btnActivateCompany clsActiveCompany15" >
<i class="fas fa-times"> Column 1</i>
</span>
</td>
<td>Second Row!</td>
<td>
<button> Button in col 3
</button>
</td>
</tr>
</tbody>
</table>
</body>
</html>
That renders like this:
Based on fact you say you can get the text in the middle column...
If you want the button in column 3, you can try xpath:
//td[text()='Test Director']/parent::*/td/button
If you want the span in column 1, you can try:
//td[text()='Test Director']/parent::*/td/span[contains(#class,'btnActivateCompany')]
In both of these instances this selects a unique hit in the source.
However, please note, this is dependent on the html provided. If there are other elements/attributes in the table the xpath might need more work. I'm happy to help more but you'll need to share more content.
Related
Hi I have a question is that possible to have function to display my table after the button was pressed, because now it's always on? I've tried with some IF functions but they weren't working.
My code:
#using (Html.BeginForm("Search", "Home", FormMethod.Post))
{
<br />
<span style="font-weight: bold">Tytuł filmu:</span> #Html.TextBox("VideoName")
<input type="submit" value="Szukaj" class="btn-primary" />
<br />
<br />
<table cellpadding="0" cellspacing="0">
<tr>
<th>
#Html.DisplayNameFor(model => model.ImageUrl)
</th>
<th>
#Html.DisplayNameFor(model => model.VideoName)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ImageUrl)
</td>
<td>
#Html.DisplayFor(modelItem => item.VideoName)
</td>
</tr>
}
</table>
}
If you put your markup inside a conditional block as follows:
#if (true)
{
#* PUT MARKUP HERE *#
}
Then the markup will only appear when the if condition is true.
Alternatively, you can use client-side code to simply hide the markup. I don't know which is best, because you haven't provided any details about what you are doing.
Instead of saying THE button, perhaps you should've talked about what kind of button you have and what is it supposed to do. If it works server side, use my first suggestion. If it needs to work client side, use my second suggestion.
You can do that in number of ways,
Javascript:
document.getElementById('mytable').style.display = 'block';
Give your table an ID and set its display to none; initially, then using javascript on the button click switch the table display to block;
function buttonClick(){
document.getElementById('myTable').style.display = 'block';
}
<table id='myTable' style='display:none;'>...</table>
<input type="submit" value="Szukaj" class="btn-primary" onclick='buttonClick()' />
Notes:
- It can be much easier if you are using jquery
- You can use event listener for the button click
Server side code:
On your action method set a TempData or ViewBag variable and then in the html check if this value exist, if true show the table
I am sure there are many other ways to do that but most of them will be around both ideas I listed.
You can have a button that toggles the visibility of the table, call the below function on the button onclick event to show or hide the table.
function toggleTable() {
var lTable = document.getElementById("YourTableId");
lTable.style.display = (lTable.style.display == "table") ? "none" : "table";
}
You have several good answers but it depends on exactly what you are trying to accomplish. I've used a variety of what has been provided. You mention showing table on button click. Do you also need to hide table if said button is clicked again? If so, client side jQuery and .toggle() could help.
$(document).ready(function(){
$("button").click(function(){
$("#myTable").toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<button>Toggle</button>
<table id="myTable" style="border: 1px solid black; display: none">
<tr>
<th>Header 1</th>
<th>Header 2</th>
</tr>
<tr>
<td>Data 1</td>
<td>Data 2</td>
</tr>
</table>
Using WatiN, can I access an url and change the value of a html table cell defined this way :
<TABLE class=table1>
<TBODY>
<TR class=dis>
<TD> rowSpan="1" colSpan="1"
Famille
<INPUT name="familySearch" onkeyup="toMaj(document.forms[0],'familySearch');changeFormEltFocus(3, 'eng.facLab');" onfocus=onKeyBack() maxLength=3 size=3 value="AAA"></input>
<A onclick="popupFamily('RFOS');" tabIndex=-1 href="#"><IMG border=0 hspace=4 alt=" " src="/ppm/images/picto_loupe.gif" align=absMiddle></A>
</TD>
</TR>
</TBODY>
I tried to do it using :
browser.Table(Find.ByClass("table1")).TableRows[0].TableCells[0].SetAttributeValue("AAA", "X82");
But I'm getting an error saying I can't access the cell. Any idea ? Thanks
Can you try focusing and then setting the value.
browser.TextField(Find.ByName("familySearch")).Focus();
browser.TextField(Find.ByName("familySearch")).TypeText("AAA");
I am using C# ASP.NET that uses html tables. The problem comes in to this specific panel that I am working with where my column inside the table is not expanding for what ever reason even though my other panels the colspan property works correctly except for this one.
Here are some screenshots to explain what is happening.
Not even though I am setting the colspan to what ever value the column does not expand. Also I know there is two tables within this panel and there is a reason to why I have two, so it's not a mistake. Basically I want the left button to stay left of the panel and secondly I want the right button ("Next") to be as far right of the page as possible.
Any ideas why this is happening or is there a better solution to this problem?
By the way I am using Google Chrome to test if this adds any value to the question.
Not sure why you are using ColSpan when you have only 1 row in second table. To achieve what you are expecting, do the following:
set Width="100%" in second table
in first "td" for back button, include "align=left"
in second "td" for next button, include "align="right"
colspan works with multiple rows; you are expecting it wrongly
<table id="tblButtons" runat="server">
<tr>
<td colspan="3">
column that covers three columns
</td>
<td align="right">
right button
</td>
</tr>
<tr>
<td>
column 1
</td>
<td>
column 2
</td>
<td>
column 3
</td>
<td>
column 4
</td>
</tr>
</table>
column 1, 2, 3 will be covered by the td having colspan="3"
There aren't 100 columns in your page, so that value is relatively worthless. You can (and should) use CSS to achieve your desired width. To have the table itself fill the page, you need to add a style="width:100%;" to it, then your cells will expand to split the difference.
colspan only changes how many columns in a table a cell takes up, not how wide it actually is. Use style="width:..." (or set it in CSS) to set the width. What's happening right now is your table is being divided into one hundred and one imaginary parts (the left side having one hundred parts, the right having one).
An example of using colspan correctly:
<table>
<tr>
<td colspan="2">
Hello world
</td>
</tr>
<tr>
<td>
Left
</td>
<td>
Top
</td>
</tr>
</table>
I am new at MVC and have a view that has a search text box + button a navigation tab and table.
I would like the table to be populated only when the search criteria is entered and the button clicked.
The problem I am having now is that the table section of the view is rendered and returns a null object reference error when the page is loaded.
Other than using jquery/java functions how can I get the table to only populate when the the search criteria is entered and the button clicked?
Do I need to create 2 separate views(one with the table and one without)?
Here are parts of my view:
<div class="searchBox">
<label>Please search here
<input type="text" name="searchTerm" id="searchTerm" value="<%= !string.IsNullOrEmpty((string) ViewData["SearchTerm"]) ? Html.Encode(ViewData["SearchTerm"]) : "" %>" />
<input type="button" value="Add" />
</label>
</div>
<ul class="navigation">
<li><a class="selected" href="#name" >Person1</a></li>
<li>Person2</li>
<li>Person3</li>
<li>Person4</li>
</ul>
<div class="tabSection">
<div class="basic">
<table id="person" class="gridview">
<thead>
<tr>
<th>name</th>
<th>dob</th>
<th>address</th>
<th></th>
</tr>
<tr>
<td><%= Model.name %></td>
<td><%= Model.dob%></td>
<td><%= Model.address%></td>
<td></td>
</tr>
</thead>
</table>
</div>
</div>
You should just wrap your table in this:
#if (Model != null)
{
// table code
}
Also, you might want to consider putting your table logic into a partial view, and have the if statement in the partial view. That way, in your main view you could just have Html.RenderPartial("PARTAILVIEWNAME"); Doing it this way would allow you to have the same table in as many views as you want without having to remember to wrap the table in an if statement every time.
This is what I should have posted in the first place.
This code displays an number of li inside an ol. Each li is represented on the page with a number(1 thru ...). Is there any way that I can access the current li number value with HTML, C#, Razor or JavaScript so that I can display it myself elsewhere on the page?
<div id="movieslist">
<ol>
#foreach(var row in data)
{
<li>
<table>
<tr>
<td width="950px" valign="baseline">#row.Name, #row.ReleaseYear, #row.Genre</td>
<td align="right" width="50px">
#{displayCount++;#displayCount;}
</td>
<td>
<select style="background-color:ThreeDFace">
<option>Choose Action</option>
<option onclick="window.location='dataMovies.cshtml?id=#row.id'">Google it</option>
<option onclick="window.location='EditMovie.cshtml?id=#row.id'">Edit Movie</option>
<option onclick="window.location='DeleteMovie.cshtml?id=#row.id'">Delete Movie</option>
</select>
</td>
</tr>
</table>
</li>
}
</ol>
I assume you mean the numbering that is automatically allied by the browser when ol or Ordered List is used.
With JQuery you could use .index()
In CSS3 you can use the nth-child pseudo-selector to style specific elements:-
http://reference.sitepoint.com/css/pseudoclass-nthchild
If you want to display it yourself, use ul and a counter. However, you can slightly modify the automatically displayed numbers as well.
This post will help you to achieve this.