Dynamically Set list item Id - asp.net-mvc-4

This seems like it should be really easy, but I cannot get this to work.
I have a collection of strings in my view model that's being outputted as list items :
<ul class="dropdown-menu" id="genreDropDown">
#foreach (string subject in Model.SuggestSubjects)
{
<li id="listItem'#subject'"><a onclick="LoadSuggestTitles_BySubject('#subject');">#subject</a></li>
}
</ul>
When the page renders I'm seeing the id of the list items are being formatted as :
<li id="listItem'Mystery'">
My question :
Is there any way I can format the ID without the single quotes, so Razor can still pick up the value and append it to id?
Ultimately I'd like for it to read <li id="listItemMystery">.

Replace:
<li id="listItem'#subject'">
With:
<li id="listItem#(subject)">

Try this:
#foreach (string subject in Model.SuggestSubjects)
{
var id = "listItem" + #subject;
<li id="#id"><a onclick="LoadSuggestTitles_BySubject('#subject');">#subject</a></li>
}

Related

How to render the value of v-for based on the condition(v-if) provided in vue.js

I'm trying to implement the condition provided in the code. My last attempt was like in the one in the code.
<ul class = "details" v-for = "(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="{{propertyName}} == 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{value}}</li>
</ul>
How can the following be implemented:
v-if="{{propertyName}} == 'IndustryIdentifiers'"
The {{ }} syntax is used to wrap a JavaScript expression that should be output as text. It isn't necessary to use the braces to access data in other contexts. In the case of a v-if the attribute value is already an expression and there's no need to include any special characters to pull in data values.
So it'd be just v-if="propertyName === 'IndustryIdentifiers'":
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li v-if="propertyName === 'IndustryIdentifiers'">Data not available</li>
<li v-else>{{ value }}</li>
</ul>
Here I'm assuming that item[this.index] is an object rather than an array, which is implied by the way you've written your loop.
You could also write it like this:
<ul class="details" v-for="(value, propertyName) in items[this.index]" :key = "value.id">
<li>{{ propertyName === 'IndustryIdentifiers' ? 'Data not available' : value }}</li>
</ul>
You should also be able to remove the this. from the index unless it's also declared locally.
I also wonder whether you're intentionally creating a separate list for each value, with each list only containing a single item. Difficult to know exactly what you're trying to achieve but I would guess that you want the loop inside the <ul> rather than on the <ul>. If you only have a single <li> (as in my second example) then you could move the v-for onto the <li>. If you want to stick to having two <li> elements with v-if/v-else then you'll need to wrap them in a <template> tag to hold the v-for.

I am facing an issue in retrieving all the list items using selenium webdriver

Problem : I have a list of items inside a div class msb-container.
.There are 162 items in the list .I want to click the 150th item from the list .There also a scroll bar through which we can go doen to other elemenst and select it
How the html looks like :
<div class="mCSB_container" style="position:relative; top:0;">
<ul id="ul-countries">
<li>
<input id="country-3" type="checkbox" name="c:3">
<label for="country-3">Afghanistan</label>
</li>
<li>
<input id="country-6" type="checkbox" name="c:6">
<label for="country-6">Albania</label>
</li>
---other countries
</li>
</ul>
</div>
How my code looks like :
IList<IWebElement> countryList = driver.FindElements(By.XPath("//*[#id='ul-countries']/li"));
for (int i = 0; i <= countryList.Count; i++)
{
string temp = countryList.ElementAt(i).Text;
if (countryList.ElementAt(i).Text == "Brazil")
{
//do something
}
}
I am getting a correct count of 162 countries but i think they are not filled correctly .As when I try to retrieve the text from even the 15th country it gives me empty result .It only fills the text for those list item which can be seen on the screen .Although when I inspect element I can see all the required data in list item through html but not through my code .I tried to put the sleep to but no luck .
Please provide your inputs to solve the above issue.
|
Kindest Regards
IList<IWebElement> countryList = driver.FindElements(By.XPath("//*[#id='ul-countries']/li"));
for (int i = 0; i <= countryList.Count; i++)
{
string temp = countryList.ElementAt(i).findElement(By.CSS("label")).getText();
if (temp.equals("Brazil"))
{
//do something
}
}

Identifying the Web element with same class name in Selenium

I have tried to get the number of tweets(tweet count) through selenium
Here is the page source:
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="1 Tweet"
href="/saisiva14"
data-element-term="tweet_stats">
<span class="DashboardProfileCard-statLabel u-block">Tweets</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">1</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="38 Following"
href="/following"
data-element-term="follower_stats">
<span class="DashboardProfileCard-statLabel u-block">Following</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">38</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="4 Followers"
href="/followers"
data-element-term="following_stats">
<span class="DashboardProfileCard-statLabel u-block">Followers</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">4</span>
</a>
</li>
I could not able to locate the web element for getting Tweets,Followers & following. The reason is span class names are common for all these elements.Please help me .
To get number of Tweets/ Following/ Followers, You can try the below statements:
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Following')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Followers')]/span[2]")).getText());
To click on the Tweets/ Following/ Followers links, You can try the below statements:
driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Following')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Followers')]")).click();
or
driver.findElement(By.xpath("//a[./span[text()='Tweets']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Following']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Followers']]")).click();
The above statements are working fine for me.
try this
IList<IWebElement> elements = driver.FindElements(By.ClassName("DashboardProfileCard-stat"));
foreach (IWebElement element in elements)
{
IWebElement ele = element.FindElement(By.ClassName("DashboardProfileCard-statLabel"));
if (ele.Text == "Tweets")
{
return element.FindElement(By.ClassName("DashboardProfileCard-statValue")).Text;
}
}
this is using C#, you can modify accordingly if anyother language is used.
The selector .DashboardProfileCard-stat span:nth-child(2) should give you the collection of web elements pointing to the count. For example in Java:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"))
Then you can use elements.get(0).getText() for tweets. elements.get(1).getText() for following. elements.get(2).getText() for followers. So:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"));
int tweets = elements.get(0).getText();
int following = elements.get(1).getText();
int followers = elements.get(2).getText();
Of course, do your appropriate safety checks, etc. Check the length of the array before access.
This code is in Java :)
capture all the parents of the "SPAN" into a collection item.
Iterate on the collection to find the span elements (which are child of <a> tag) and capture text based on the class name variation statLabel / statValue".
List<WebElement> webElement = driver.findElements(By.xpath("//li[#class='DashboardProfileCard-stat Arrange-sizeFit']//a"));
for (WebElement element : webElement) {
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statLabel')]")).getText());
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statValue')]")).getText());
}

Uncaught TypeError on second onclick event using this.innerHTML

Everyone, I have a rather weird problem.
In an HMTL unordened list I have several list elements with onClick events, and they all call the same function.
<ul>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">1</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">2</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">3</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">4</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">5</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">6</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">7</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">8</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">9</li>
<li onClick="Javascript:show(this.innerHTML); alert(this.innerHTML);">0</li>
</ul>
This is the Javascript function:
function show(ID){
show = document.getElementById(ID);
notShow = document.getElementsByClassName("visible")[0];
if (typeof notShow !== "undefined"){
notShow.classList.toggle("hidden");
notShow.classList.toggle("visible");
}
show.classList.toggle("hidden");
show.classList.toggle("visible");
}
for some unknown reason, the function works fine when I click one of the <li> elements first, but the second time I do that I get an error:
Uncaught TypeError: object is not a function ACNL.php:31
I think the error is not inside the javaScript function, but in the HTML-element that calls the function.
Any help would be appreciated!
I see a few problems here. In no particular order:
It would probably be safest to change the inner variable name show to something else since your function is also called show(...).
Declare variables with the var keyword to avoid populating the top namespace.
You're retrieving DOM elements by ID, but none of your DOM elements (in the above example) have ID attributes. You'll want to add them to your li items at least, e.g. id="1"
If these elements don't have visible to start off with, you'll add both visible and hidden when you "toggle".
If you toggle visible and hidden on the li items, then notShow = document.getElementsByClassName("visible")[0]; should probably change, as you will be retrieving the li items once they have visible in them. Try using other class names or element types.
Here is a jsFiddle to get you started (ignore the window.show definition that's specific to jsFiddle).

Dojo 1.8: join list domConstruct.toDom

Hi I have problem joining two lists together before applying domConstruct.toDom.
I understand that it can be done that way ie:,
require(["dojo/text!, myListHtml.html", "dojo/domReady!"],
function(myListHtml){
var list = domConstruct.toDom(myListHtml);
});
However, i would like to know how two lists should be coded ie:-
require(["dojo/domReady!"], function(){
var list = domConstruct.toDom
('<ol>\
<li class="odd">\
<div class="bold">\
<a class="odd">Odd</a>\
</div>\
</li>\
<li class="even">\
<div class="italic">\
<a class="even">Even</a>\
</div>\
</li>\
</ol>\
<ol id="list2">\
<li class="odd">Odd</li>\
</ol>');
Please advise. Thanks in advance
Clement
Why are you trying to join the two lists? domConstruct.toDom() returns a single domNode, but what you are trying above would be two domNodes.
If you really want to "combine" them, you can nest them inside another domNode, like this:
var lists = domConstruct.toDom(
'<div>\
<ol>\
<li class="odd">\
...
</ol>\
<ol id="list2">\
<li class="odd">Odd</li>\
</ol>\
</div>');
If you want to "combine" them on the page, consider creating them separately and adding them to the page using domConstruct.place(), like this:
domConstruct.place('<ol>\
<li class="odd">\
...
</ol>', "idOfWhateverYouWantToContainIt");
domConstruct.place('<ol id="list2">\
...
</ol>', "idOfWhateverYouWantToContainIt");