ASP.Net listview layout behaving oddly - c#

I'm trying to use a ListView in an ASP.Net page and failing to get the results I was expecting. My page looks like this:
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr>
<asp:ListView runat="server" id="lvwContacts">
<LayoutTemplate>
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
<tr id="itemPlaceHolder" runat="server"></tr>
</table>
</div>
</div>
</LayoutTemplate>
<ItemTemplate>
<tr>
... etc
but when I look at the output the table is not appearing inside the divs:
<div class="tableWrapper">
<div class="tableScroll"></div>
</div>
<table>
<tbody>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr></tr>
</tbody>
</table>
<table>
<tbody>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
... etc
I've tried putting the divs around the whole listview with much the same result. What on earth is going on here? Have I done something stupid or do ListViews really behave like this?
Thanks
John

You must make sure you have valid HTML markup. Currently one of your <tr>'s has a <div> as a child, not a <td> or <th>.
See this demo:
/* style used to illustrate problem */
.tableWrapper {
padding: 10px;
background: red;
}
<label>Invalid markup</label>
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr> <!-- Invalid. child is a div not a td or th -->
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
</table>
</div>
</div>
</tr>
</table>
<hr>
<label>Valid markup</label>
<table>
<tr>
<td><label class="subHeading">Contacts</label></td>
</tr>
<tr>
<td> <!-- This is required! -->
<div class="tableWrapper">
<div class="tableScroll">
<table>
<tr>
<th><label>Full Name</label></th>
<th><label>Job Title</label></th>
<th><label>Direct Line</label></th>
<th><label>Mobile Phone</label></th>
<th><label>Email</label></th>
</tr>
</table>
</div>
</div>
</td>
</tr>
</table>
Inspect the rendered output of both tables... you will see what happens when the markup is not valid (what you are experiencing) the browser removes the <div> from the table. The second table has correct markup so it renders as-is

Related

Retrieve only the HTML structure (All DOM elements) from HTML file

I want to retrieve only the structure of HTML document using C# as there is a requirement to create a template from the document and store in a database,which can be used in the future to compare if such a document was earlier received and process further For eg if have the below simple HTML:
<HTML>
<BODY>
<DIV name="Span1">Simple HTML Form</DIV>
<FORM>
<SPAN name="TextLabel">EID: 12345</SPAN>
<SPAN name="TextLabel1">Date:'2019-07-10'</SPAN>
</FORM>
<table>
<tr>
<td>Name </td>
<td> Occupation</td>
</tr>
<tr>
<td> XYZ </td>
<td> SSE </td>
</tr>
</table>
</BODY>
</HTML>
I want the following output:
<HTML>
<BODY>
<DIV></DIV>
<FORM>
<SPAN></SPAN>
<SPAN></SPAN>
</FORM>
<table>
<tr>
<td></td>
<td></td>
</tr>
<tr>
<td> </td>
<td> </td>
</tr>
</table>
</BODY>
</HTML>
Using HtmlAgilityPack might be an option. You can start from this example and develop...
HtmlDocument doc = new HtmlDocument();
string html = #"<HTML>
<BODY>
<DIV name=""Span1"">Simple HTML Form</DIV>
<FORM>
<SPAN name=""TextLabel"">EID: 12345</SPAN>
<SPAN name=""TextLabel1"">Date:'2019-07-10'</SPAN>
</FORM>
<table>
<tr>
<td>Name </td>
<td> Occupation</td>
</tr>
<tr>
<td> XYZ </td>
<td> SSE </td>
</tr>
</table>
</BODY>
</HTML>";
doc.LoadHtml(html);
var nodes = doc.DocumentNode.Descendants();
you can use Regex :
string html = #"<HTML>
<BODY>
<DIV name=""Span1"">Simple HTML Form</DIV>
<FORM>
<SPAN name=""TextLabel"">EID: 12345</SPAN>
<SPAN name=""TextLabel1"">Date:'2019-07-10'</SPAN>
</FORM>
<table>
<tr>
<td>Name </td>
<td> Occupation</td>
</tr>
<tr>
<td> XYZ </td>
<td> SSE </td>
</tr>
</table>
</BODY>
</HTML>";
Regex regex = new Regex(#"<.+?>");
MatchCollection match = regex.Matches(html);
foreach(var item in match)
Console.WriteLine(item);

display anchor tag in angular expressions enclosed by html tag

I want to display an anchor tag inside angular expression enclosed by html tag. when I am using it inside html tag, it is displaying the raw path as it is which is:
<a href='../UserControls/DownloadRLCSFile.ashx?Path=\\\\dotnetdev\\csv\\RLCSDocuments\\Registrations\\ABACF\\E.S.I.C. Registration\\Sample.xlsx' target='_blank' download><i class='fa fa-download' style='font-size: 13pt;' ></i></a> Code :
<div id="Div2" ng-controller="BasicRegulatoryDetail">
<!--added by dilip -->
<h4 class="padder-sm b-b"><b>Regulatory Updates</b></h4>
<div>
<div class="table-responsive">
<table class="table table-striped bg-white ">
<%--<thead>
<tr>
<th>Subject</th>
<th>Download</th>
</tr>
</thead>--%>
<tbody>
<tr ng-repeat="bs in BasicInfo">
<td>
<asp:HyperLink ID="HyperLink1" NavigateUrl="~/RLCS_Connect/RegulatoryUpdateDetails.aspx?Subject={{bs.Subject}}" runat="server">{{bs.Subject}}</asp:HyperLink>
</td>
<td>{{bs.Document_Path}}</td>//here i am facing the problem </tr>
</tbody>
</table>
</div>
</div>
</div>
use ng-bind-html something like
<td><span ng-bind-html='bs.Document_Path'></span></td>

Move a button to another tr programatically

I have a login form designed using a <table> in an ASP.NET application.
A client is asking to modify the layout by moving around a few UI controls. They want to move the Forgot Password link below the Login button so they are on separate lines.
However, for all other clients, everything needs to remain the same, so if any CSS or style changes need to be done, I would need to do it programatically. Are there any easy ways to do this?
I am trying to avoid creating duplicate user controls to fit the layout they want, and then hide/show controls, depending on the client.
<table style="TABLE-LAYOUT: fixed; WIDTH: 370px;">
<COLGROUP>
<COL width="120px">
<COL width="250px">
</COLGROUP>
<tr>
<td>Username:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td> </td>
<td>
<table>
<tr>
<td style="text-align:right;">
Forgot Password
</td>
<td>
<button type="submit">Login</button>
</td>
</tr>
</table>
</td>
</tr>
</table>
JSfiddle Demo
EDIT: jQuery NOT allowed. JavaScript OK.
Jquery can do this for you. the code might look something like this:
$("#toggle").click(toggleButtonPosition);
function toggleButtonPosition() {
var buttonRow = $("button[type=submit]").closest("tr"), buttonCell, newTR, tr;
if (buttonRow.find("td").length === 2) {
// the table is in its initial configuration. Need to extract the button cell and add it to a new row
buttonCell = buttonRow.find("button").closest("td");
buttonCell.remove();
newTR = $("<tr />").append(buttonCell);
newTR.insertBefore(buttonRow);
} else {
// Reverse the process
buttonCell = buttonRow.find("td");
tr = buttonRow.siblings().first();
tr.append(buttonCell);
buttonRow.remove();
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="TABLE-LAYOUT: fixed; WIDTH: 370px;">
<COLGROUP>
<COL width="120px">
<COL width="250px">
</COLGROUP>
<tr>
<td>Username:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td> </td>
<td>
<table>
<tr>
<td style="text-align:right;">
Forgot Password
</td>
<td>
<button type="submit">Login</button>
</td>
</tr>
</table>
</td>
</tr>
</table>
Toggle Button Position
You don't need to duplicate the layout. You can do it by adding/ removing the css class depending upon the client using jquery or javascript.
$(document).ready(function(){
var client1 = true; // variable to store client
if(client1){
$('button').removeClass('client2').addClass('client1');
}
else {
$('button').removeClass('client1').addClass('client2');
}});
Css classes to be added/removed from the button depending upon the client. I have put 'client1' css class on the button.
button.client1{display:block;margin:0 auto}
button.client2{float:right;margin-left:4px}
Html code as follows:
<table style="TABLE-LAYOUT: fixed; WIDTH: 370px;">
<COLGROUP>
<COL width="120px">
<COL width="250px">
</COLGROUP>
<tr>
<td>Username:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td> </td>
<td>
<table>
<tr>
<td>
<button type="submit" class='client1'>Login</button>
Forgot Password
</td>
</tr>
</table>
</td>
</tr>
You could use jQuery to archive that.
Here is an example of moving the button one step back
$(document).ready(function() {
var loginLayOut = $(".login"); // login Table
var btnTd = loginLayOut.find("button").parent(); // button container, in this case its td
var tbody = btnTd.parent().parent(); // we get the tbody by moving two step back
var tr = $("<tr></tr>"); // create a new tr
tr.append(btnTd); // append the td to the new created tr
tbody.prepend(tr); // insert the tr to the tbody at position 0
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class='login' style="TABLE-LAYOUT: fixed; WIDTH: 370px;">
<COLGROUP>
<COL width="120px">
<COL width="250px">
</COLGROUP>
<tr>
<td>Username:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>Password:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td> </td>
<td>
<table>
<tr>
<td style="text-align:right;">
Forgot Password
</td>
<td>
<button type="submit">Login</button>
</td>
</tr>
</table>
</td>
</tr>
</table>

Handling tables in c# selenium

<table cellpadding="0" cellspacing="0" onclick="" style="width: 1345px;">
<tbody>
<tr id="item_tcm:222-382904-131104" title="2. Publish to WIP (tcm:222-382904-131104)" class="item even" c:drawn="true">
<td class="col0 icon odd" value="T131104L0P0">
<div class="icon" style="background-image: url("/WebUI/Editors/CME/Themes/Carbon2/icon_v7.1.0.66.55_.png?name=T131104L0P0&size=16");"></div>
</td>
<td class="col1 even">
<div class="text">2. Publish to WIP</div>
</td>
<td class="col2 odd">
<div class="text">JH Anchor link 2</div>
</td>
<td class="col3 even">
<div class="text">S070 Public Site US English</div>
</td>
<td class="col4 odd" value="2015-12-23T14:41:04">
<div class="text">12/23/2015 2:41 PM</div>
</td>
<td class="col5 even">
<div class="text">NT AUTHORITY\SYSTEM</div>
</td>
<td class="col6 odd" value="">
<div class="text">
<span style="color: #f00"></span>
</div>
</td>
<td class="col7 even" value="16">
<div class="text">Suspended</div>
</td>
<td class="col8 odd">
<div class="text">NT AUTHORITY\SYSTEM</div>
</td>
<td class="col9 even">
<div class="text">Publishing Failed</div>
</td>
</tr>
<tr id="item_tcm:222-382901-131104" title="2. Publish to WIP (tcm:222-382901-131104)" class="item even" c:drawn="true">
<td class="col0 icon odd" value="T131104L0P0">
<div class="icon" style="background-image: url("/WebUI/Editors/CME/Themes/Carbon2/icon_v7.1.0.66.55_.png?name=T131104L0P0&size=16");"></div>
</td>
<td class="col1 even">
<div class="text">2. Publish to WIP</div>
</td>
<td class="col2 odd">
<div class="text">JH_anchor link</div>
</td>
<td class="col3 even">
<div class="text">S070 Public Site US English</div>
</td>
<td class="col4 odd" value="2015-12-23T14:17:51">
<div class="text">12/23/2015 2:17 PM</div>
</td>
<td class="col5 even">
<div class="text">NT AUTHORITY\SYSTEM</div>
</td>
<td class="col6 odd" value="">
<div class="text">
<span style="color: #f00"></span>
</div>
</td>
<td class="col7 even" value="16">
<div class="text">Suspended</div>
</td>
<td class="col8 odd">
<div class="text">NT AUTHORITY\SYSTEM</div>
</td>
<td class="col9 even">
<div class="text">Publishing Failed</div>
</td>
</tr>
.....
</tbody>
</table>
I have collection of rows. Inside each row i have 10 columns(td). I want to iterate to each row. For each row I want to get the 8th and 10 th column.
Note :- The test case will get Fail if the 8th column value is "Suspended" and 10th column value is "Publishing Failed" or else the test case would get Pass
I tried the below logic
IWebElement tableElement = driver.FindElement(By.XPath("/html/body/table"));
IList<IWebElement> tableRow = tableElement.FindElements(By.TagName("tr"));
foreach (var item in tableRow)
{
}
I'm not sure how to proceed further. Could anyone help me? Thanks in advance
Your logic is good:
IWebElement tableElement = driver.FindElement(By.XPath("/html/body/table"));
IList<IWebElement> tableRow = tableElement.FindElements(By.TagName("tr"));
IList<IWebElement> rowTD;
foreach (IWebElement row in tableRow)
{
rowTD = row.FindElements(By.TagName("td"));
if(rowTD.Count > 9)
{
if(rowTD[8].Text.Equals("Suspended") && rowTD[10].Text.Equals("Publishing Failed");
//test failed
}
}
What if you would just try to find the rows having the 8th column value "Suspended" and 10th column value "Publishing Failed":
IList<IWebElement> rows = tableElement.FindElements(By.TagName("//table//tr[td[8]/div = 'Suspended' and td[10]/div = 'Publishing Failed']"));
Then, you can fail the test if rows list is not empty.
Try this:
foreach (var item in tableRow)
{
IWebElement column7 = item.FindElement(By.CssSelector("[class*='col7']"));
IWebElement column9 = item.FindElement(By.CssSelector("[class*='col9']"));
if (column7.Text.Equals("Suspended") && column9.Text.Equals("Publishing Failed"))
Assert.Fail("Failed because column8 is 'Suspended' and column10 is 'Publishing Failed'");
else
Assert.Pass();
}
Please note that this code will stop testing when it has found the "Suspended" and "Publishing Failed". If you want to continue testing until the final row in table, you have to use multiple assertions. NUnit, is it possible to continue executing test after Assert fails?

Automatic Web content downloading using C#

I want to develop a program to automatically lookup words in Longman online dictionary and copy its definition and meanings. I am using visual studio and C# language and I have developed the part which browse to the website and search for a word. However, the problem is in navigating through Longman online website when there are some word forms. for example for this link the html code of the suggested words is as following:
<div class="content1">
<style>
.dictionary-results-title .topic_bullet {
margin: 0px;
}
</style>
<div class="border-search">
<div class="dictionary-results-title">
Results from the Longman Dictionary of Contemporary English:
</div>
<div class="dictionary-results-title">
<span class="dictionary-results-title-topic-new">
Click on topic labels to navigate through our Topic Dictionary
</span>
</div>
<!-- google_ad_section_start -->
<div id="42385" class="folded">
<table id="hwdfolded" class="hwdfolded" cellspacing="0" cellpadding="0">
<tr>
<td class="hwdunSelHG"></td>
<td class="hwdunSelHM"></td>
<td class="hwdunSelHD"></td>
</tr>
<tr>
<td class="hwdunSelMG"></td>
<td class="hwdunSelMM">
<a href="/dictionary/superman">
<span class="headword">superman</span></a>
<span class="homographs"></span>
<span class="wordclass">noun</span>
<span class="topiclinks"></span>
</td>
<td class="hwdunSelMD"></td>
</tr>
<tr>
<td class="hwdunSelBG"></td>
<td class="hwdunSelBM"></td>
<td class="hwdunSelBD"></td>
</tr>
</table>
</div>
<div id="42386" class="folded">
<table id="hwdfolded" class="hwdfolded" cellspacing="0" cellpadding="0">
<tr>
<td class="hwdunSelHG"></td>
<td class="hwdunSelHM"></td>
<td class="hwdunSelHD"></td>
</tr>
<tr>
<td class="hwdunSelMG"></td>
<td class="hwdunSelMM">
<a href="/dictionary/Superman">
<span class="headword">Superman</span></a>
<span class="homographs"></span>
<span class="wordclass"></span>
<span class="topiclinks"></span>
</td>
<td class="hwdunSelMD"></td>
</tr>
<tr>
<td class="hwdunSelBG"></td>
<td class="hwdunSelBM"></td>
<td class="hwdunSelBD"></td>
</tr>
</table>
</div>
<script language="JavaScript" type="text/javascript">
parent.curEntryId=42385; parent.prevEntryId=42385; parent.nextEntryId=42385;
parent.gsSenseId=null; parent.giPhrId=null;
</script>
</div>
</div>
I have found the way to find the ID of the words like id="42385" and id="42386" but I cannot navigate through them. There is a table inside each element with these ids. As you can see in the html code the second data of the second row of the table contains the links for each word.
the code I have written to click on them is like this:
HtmlElement Word = webBrowser1.Document.GetElementById("hwdfolded");
foreach (HtmlElement ele in Word.Parent.Parent.Children)
{
if (ele.Id != null && ele.InnerText.ToLower().Contains(Stword))
{
HtmlElement clickon = webBrowser1.Document.GetElementById(ele.Id);
clickon.InvokeMember("click");
//ele.InvokeMember("click");
while (webBrowser1.ReadyState != WebBrowserReadyState.Interactive)
Application.DoEvents();
do
{
Application.DoEvents();
} while (webBrowser1.ReadyState != WebBrowserReadyState.Complete);
break;
}
}
Note that Stword contains the string of the word I am searching for in this example it contains "superman" and also the ele.Id contains one the specified Ids and I checked it in debug mode. But the click command not works. I will appreciate it if you can tell me the solution or give me another solution which is better.
I suggest that you use a scraping tool to perform the navigation through the page. With Selenium it is really easy to obtain elements by XPATH and navigate through them and also obtain the text inside them. Hope it helps.

Categories

Resources