Dynamically Assigning value to hyperlink for file Downloads - vb.net

MVC3 VB.NET Razor view Application... I have a view that uses a for each loop to display all the available courses. Next to each of these I would like to place a Html link to download that courses class handout file. Problem is I have not found anything on any forums about assigning the value to the hyperlink dynamically since it will vary with every iteration of the for each loop. I have coded the model to hold the file name associated with each class. Below is a snippet from the view...
#For Each item In Model
Dim currentItem = item
Dim Handout = Path.Combine((AppDomain.CurrentDomain.BaseDirectory) + "CourseHandouts\") + currentItem.handoutFile1
#<tr>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.course_ref)
</td>
<td>
#Html.DisplayFor(Function(modelItem) currentItem.course_title)
</td>
<td>#Html.DisplayFor(Function(modelitem) currentItem.course_start)</td>
<td>#Html.DisplayFor(Function(modelitem) currentItem.course_end)</td>
<td id="Actions">
#Html.ActionLink("Details", "CourseDetails", New With {.id = currentItem.course_id})
</td>
Course Handout
</tr>
Next
Anyone have any ideas on how I could create a unique download link for each file???

You need to make the link point to a client-facing URL:
<a href="#Url.Content("~/CourseHandouts/" + currentItem.handoutFile1)">

you also have the much overlooked #Href() which can be popped in in place of #Url.Content():
Download File

Related

Web Automation - How do I input text into a rich text box on a website (textarea) defined by a class?

I have been trying this for a few days and am completely stuck. If anybody could help me out I would be very grateful; Im using VB.NET.
The HTML Code:
<tbody>
<tr>
<td class="chat-attachment-cell"></td>
<td class="chat-input-cell">
<textarea class="chat-message-input"></textarea>
</td>
<td class="chat-send-cell"><a href="#" class="chat-send-button"> alt="Send" width="66" height="66" border="0">
</a>
</td>
</tr>
</tbody>
The text box I need to input into is this bit
<textarea class="chat-message-input"></textarea>
Thankyou in advance for any help provided
You select the element then change the .innertext property with what you want.
There are multiple ways to do it, and I can't give you an example because I don't know what you are using nor the whole html, but for example it could look like this:
WebBrowser1.Document.GetElementById("someid").InnerText="Sometext"
For start, you can try looking how the collection of elements you get looks, then you should be able to figure out what to do next.
Dim test = WebBrowser1.Document.GetElementsByTagName("textarea")
For example on this page:
Dim test = WebBrowser1.Document.GetElementsByTagName("tbody")
test(1).InnerText = "Hi there"

selenium webdriver validate if checkbox is checked

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.

Get classname from tag in LESS

I want to use a classname to set a background on a element, but i'm not sure if it's possible with LESS js at the moment.
The case is:
I have a table with a list of athletes, on these lists i want to show a country flag as a background of a p tag.
In HTML it looks like:
<table>
<tr>
<td class="athlete"><p class="us">Athlete 1</p></td>
</tr>
</table>
I want to set the background image through a mixin, if i can get the classname from the P tag i would be there.
.athlete {
p {
.setBackgroundImage(#ClassName);
}
}
is there anyway in LESS to achieve this?
The problem is that i need a whole new rule for every possible country. My loop implementation didn't cut it either.
I went for the javascript implementation, i add a background image to a iso coded classname in a certain parent class.
<div class="nationality">
<p class="athlete">Athlete X<span class="nl"></span></p>
</div>
jQuery(".nationality span").css('background-image', 'url(../img/flags/60/'+jQuery(".nationality span").attr("class")+'.png);
Thanks guys.

Element is no longer attached to the Dom error for link

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]

Foreach property in item from list

I'm revamping a small helpdesk application (moving from ASP classic to MVC4). This is my first full MVC application. I've opted to go with Razor, and I feel like it's pretty intuitive. But I've hit a wall on this part.
I get a list of tickets from the database to display to the user. What I would like is to dynamically create a table. Right now I have put the headers in place manually, which is fine. If there's a way to do that dynamically, though, I'm open to suggestions.
But the crucial piece is to get each property from the ticket. I have a Ticket class that has over 20 properties. I'll be working on whittling those down to the minimum we want to display, but as a starting point, I'm trying to throw them all up on the screen.
I have the following:
#model IList<Helpdesk4.Models.Ticket>
...
#foreach (var ticket in Model)
{
<tr>
#foreach (var item in ticket)
{
<td>item</td>
}
</tr>
}
But I can't run that foreach on ticket. I'm enough of a noob that I don't totally understand why, but I think that the properties have to be loaded and so can't be enumerated by default. So without pulling up each property name, how do I just get each property's value from ticket?
I am using NHibernate for the queries to the db if that makes any difference.
The absolutely clearest and easiest way to do this if to manually add each of the properties values to the row. This does require a small amount of "extra" work, but it is a one time thing, and 20 properties is not that much. It also gives you much finer control over exactly how each property is displayed, if it is aligned right or left, etc.
What you end up with is something like this
#foreach (var ticket in Model)
{
<tr>
<td>
#ticket.FirstProperty
</td>
<td class="align-right">
#ticket.SecondProperty
</td>
<td class="align-center bold">
#Html.DisplayFor(m => ticket.ThirdProperty)
</td>
<td>
<i>#ticket.FourthProperty</i>
</td>
...
</tr>
}
Stylings and such added for emphasis of customizability.
Good luck with your first MVC project!
Foreach only works with an enumerable item, and general classes don't implement IEnumerable. You need to put each item on there yourself. The best way would be to use something like Html.TextBoxFor(m => m.Property) for each property.
edit:
The best way would be to just use Html.LabelFor on the object itself.
#for(int index = 0; index < Model.Count; ++index)
{
<tr>
#Html.LabelFor(m => m[index])
<tr>
}