Get text of the node - c#

In an ASP.NET application I have a IreeView.
Here is one of the nodes in the view:
<td style="white-space: nowrap;">
<input id="TreeView1n10CheckBox" type="checkbox" checked="checked" name="TreeView1n10CheckBox">
<a id="TreeView1t10" onclick="TreeView_SelectNode(TreeView1_Data, this,'TreeView1t10');" href="javascript:__doPostBack('TreeView1','sPreAnalytical\\Test Requisitions\\2 Specimens: 1 Req')" class="TreeView1_0">2 Specimens: 1 Req</a>
As you can see it is a checkbox and there is text after it 'TreeView1','sPreAnalytical\\Test Requisitions\\2 Specimens: 1 Req'
How do I get the text 2 Specimens: 1 Req' on the client side, and how do I modify this text using JavaScript and display the modified TreeView to the client?
this works beautifully:
function check_OnTreeNodeChecked(event) {
var TreeNode = event.srcElement || event.target;
if (TreeNode.tagName == "INPUT" && TreeNode.type == "checkbox") {
if (TreeNode.checked) {
var elNode = document.getElementById("TreeView1t10");
var sText = elNode.innerText || elNode.innerHTML;
alert(sText);
elNode.innerHTML = "Whatever you want";
}
}
}
however since i need to modify the specific text next to the checkbox i need to be able to know which element id it was instead of implicitly specifying var elNode = document.getElementById("TreeView1t10");
Question how do i get the element id of the box that was checked?

The text can be retrieved using:
var elNode = document.getElementById("TreeView1t10");
var sText = elNode.innerText || elNode.innerHTML;
Modify it using:
elNode.innerHTML = "Whatever you want";
To get the ID of the tree node in your click handler:
From the top of my head, untested, something like this will get you the tree node from the checkbox ID:
Checkbox ID = "TreeView1n10CheckBox"; replace "CheckBox" with nothing, so we have
"TreeView1n10". Then replace the "n" with "t" and we have "TreeView1t10", which is
the ID of the corresponding anchor tag.
var sTreeID = TreeNode.id.replace("CheckBox", "").replace("n", "t");
var elTreeNode = document.getElementById(sTreeID);

With jQuery, it's quite simple...
var oldText = $('.TreeView1_0').text();
$('.TreeView1_0').text('new text here');
EDIT :
example here : http://jsfiddle.net/shaneblake/ZG888/

With a tree view the class is probably utilized multiple times so accessing the specific element would be of more use.
var oldText = $('#TreeView1t10').html();
If you need to update all the trees text you can loop through them pretty simply as well.
$('.TreeView1t10').each(function() {
var oldText = $(this).find('a').html();
});

Related

How to collect a Value out of multiple div elements in a list with Selenium in C#?

i have a list on a website that stores the part number and the order number.
in this list are different div elements and i would like to export every part number in this list.
The list looks like this:
<div class="spareValue">
<span class="label">OrderNumber:</span>
<span class="PartNumber">180011</span>
</div>
<div class="spareValue">
<span class="label">SparePartNumber:</span>
<span class="PartNumber">01002523</span>
</div>
How can i export every OrderNumber and put them into a list in c# that i can work with the values??
lot of ways to do that:
var spans = driver.FindElements(By.CssSelector("div.spareValue span"));
var nbrspans = spans.Count;
var Listordernumber = new List<string>();
for(int i = 0; i < nbrspans; i +=2)
{
if (spans[i].GetAttribute("textContent") != "OrderNumber:") continue;
Listordernumber.Add(spans[i + 1].GetAttribute("textContent"));
}
so Listordernumber contains the result
if you prefer linq, you could use that:
string path = "//div[#class='spareValue' and ./span[text()='OrderNumber:']]/span[#class = 'PartNumber']";
var Listordernumber = driver.FindElements(By.XPath(path)).Select(s => s.GetAttribute("textContent")).ToList();
Oke, you want every partnummer, that belongs to an ordernummer. That leads me to this xPath, find the div that has a ordernumber in it, than find the partnumber element inside.
Then to find them all (or none).
Last put them all in a neat list, selecting the partnumber text:
string path = "//div[#class='spareValue' and ./span[text()='OrderNumber:']]/div[#class='PartNumber']"
var elements = driver.findElements(By.XPath(path));
var listOrderNumber = elements.Select(e=>e.Text);
var els = driver.FindElements(By.XPath("//*[text()='OrderNumber:']"));
foreach(var el in els){
var el = els.FindElement(By.XPath("./../span[#class='PartNumber']"));
console.writeline("OrderNumber: "+el.Text());
}
first, you have to find all elements that have "OrderNumber:" text on it and eliminate all elements that don't.
now, iterate through all elements that have "OrderNumber:" we have found from step above and go to its parent node, then find all element inside the parent node that the class name is "PartNumber".

Check what value selected in a DropDownList and check it against XML value

what I'm essentially trying to do is check to see if the value selected in my dropDownList1 is in my XML document, and if so print out it's fat content. Otherwise I return the string "Sorry we can't find your food!". As it stands I'm only getting the else scenario. Any help would be fantastic
my code is as follows:
XmlDocument xDoc = new XmlDocument();
xDoc.Load("the xml address");
// go through each food name (this works)
foreach (XmlNode name in xDoc.SelectNodes("Web_Service/Food/Name"))
{
//grab the string
string foodName = name.InnerText;
// what I'm tring to here is loop through the items in the dropdown list
// and check it against foodName
foreach (ListItem li in DropDownList1.Items)
{
if (li.Value == foodName)
{
// print the value fat value of that particular foodName
// address is ("Web_Service/Food/Fat")
}
else
{
TextBox2.Text = "sorry we could not find your food!";
}
}
}
Hopefully I explained it well enough, thanks guys.
Replace your foreach loop with the following:
string nodeSelect = String.Format("Web_Service/Food/Name[#Value='{0}']",foodName);
XmlNodeList nodes = xDoc.SelectNodes(nodeSelect);
if (nodes.Count == 0)
{
TextBox2.Text = "sorry we could not find your food!";
}
else
{
//print the value fat value of that particular foodName
// address is ("Web_Service/Food/Fat
}
You can use XPath expression to get <Food> node having child node <Name> equals selected food, then get the <Fat> child node. All in one XPath expression so you can accomplish this without manually looping through each <Food> nodes. For example :
string foodName = DropDownList1.SelectedValue;
string xpath = String.Format("Web_Service/Food[Name='{0}']/Fat", foodName);
XmlNode fatNode = xDoc.SelectSingleNode(xpath);
if(fatNode != null)
{
TextBox2.Text = fatNode.InnerText;
}
else
{
TextBox2.Text = "sorry we could not find your food!";
}
The property to know the selected value of a dropdownlist is SelectedValue like:
DropDownList1.SelectedValue == foodName
I do not see the need of your second loops as it does not even verify if the item is selected.
Alternatively you could use LINQ to get the list of food items in your XML doing something like:
XDocument doc=XDocument.Load(Server.MapPath("the xml address"));
var items = (from item in doc.Root.Elements("Web_Service/Food")
select new {
name=c.Element("Name"),
};
Then you can benefit from different array functions like:
Array.Exists(items, DropDownList1.SelectedValue)
Or using it as possible filter in your LINQ Query using where and let keywords:
var items = (from item in doc.Root.Elements("Web_Service/Food")
let name = c.Element("Name")
where DropDownList1.SelectedValue == name
select new {
name=name,
};

Autocomplete box error

I have a xml file and I want to search in it with an autocomplete box.
I use code below but the it crashed. How can I fix it or is there a way better?
XDocument loadedData = XDocument.Load("BankCode.xml");
var data = from query in loadedData.Descendants("BankCode")
select new BankData
{
BankName= (string)query.Element("Bank"),
};
this.acBox.ItemsSource = data;
XDocument loadedCustomData = XDocument.Load("BankCode.xml");
var filteredData = from c in loadedCustomData.Descendants("Bank")
where c.Attribute("Code").Value == acBox.Text
select new BankData()
{
Code= c.Attribute("Code").Value
};
listBox1.ItemsSource = filteredData;
I want to create an app that when the user type the bank name in autocomplete box after pressing the search button the bank code has shown to him/her. (!!The acBox is an autocomplete box.)
It seems 1 of your Bank nodes does not have a Code attribute.
You should add a NULL check:
var filteredData = from c in loadedCustomData.Descendants("Bank")
where c.Attribute("Code") != null && c.Attribute("Code").Value == acBox.Text
select new BankData()
{
Code= c.Attribute("Code").Value
};

Name cannot begin with the '1' character, hexadecimal value 0x31. while reading from an xml file

I am using an xml file to read the contents and display it in a tree view list with checkboxes. The condition for this is that the contents should be displayed on the basis of what the user selected in combo box. Suppose the user selected 2 in combo box, then the treeview list should display the contents of 2(from xml file). I have tried like:
private void pjctsel_cmbbox_SelectedIndexChanged(object sender, EventArgs e)
{
var xmldoc = File.ReadAllText(#"D:\\test.xml");
var str = XElement.Parse(xmldoc);
cmbbox_val = pjctsel_cmbbox.SelectedIndex.ToString();
*** var res = str.Elements(cmbbox_val).Where(x => x.Element("general").Value.Equals(cmbbox_val)).ToList();
MessageBox.Show(res.ToString());
}
cmbbox_val = user selected value from combobox.
The xmlfile content is:
<serv>
<general name="one">
<server name="oneone">
<service name="1143"/>
<service name="1142"/>
</server>
</general>
<general name="two">
<server name ="twoone">
<service name="2143"/>
<service name="2142"/>
</server>
</general>
</serv>
In my c# code, where I marked * I am getting the following exception "Name cannot begin with the '1' character, hexadecimal value 0x31."
Googled it, but I could find only those starting their xml files with tag string 1.
Any ideas on this?
Any thoughts would be really appreciated..
EDIT:
My combo box has values like one,two.
What I am trying is that if the user selects the value two in combo box, then my application needs to check for an entry with the name two in the xml file and if found any match, then the "server name" node and "service name"nodes corresponding to two, must be displayed in the treeview list.
Hope this makes sense..
cmbbox_val = pjctsel_cmbbox.SelectedIndex.ToString(); // SelectedIndex is an integer
var res = str
.Elements(cmbbox_val) // so this will fail
.Where(x => x.Element("general")
.Value.Equals(cmbbox_val)).ToList();
This might work:
cmbbox_val = pjctsel_cmbbox.SelectedItem.ToString(); // or SelectedItem.SomeProperty
But I also note that you are looking for cmbbox_val 2 times and that Element("general") already is the root of your XML. So this can't work but we don't have the information to fix it.
After the edit:
My combo box has values like one,two.
needs to check for an entry with the name two in the xml file
then the "server name" node and "service name"nodes must be displayed in the treeview list.
Step 1) and 2)
var str = XElement.Parse(xmldoc);
IEnumerable<XElement> generals = str
.Elements("general")
.Where(g => g.Attribute("name") == cmbbox_val);
and because that result is hierarchical, I would use it with foreach() instead of Linq, like so:
foreach(var general in generals) // probably only 1
{
foreach (var server in general.Elements("server"))
{
string serverName = server.Attribute("name").value;
foreach(var service in server.Elements("service"))
{
// etc
}
}
}
According to MSDN XElement.Elements() takes as a parameter a string that represents the name of the element to be selected. Names can't begin with 1 and you get that error because you're passing cmbbox_val for Elements().
You are using that cmbbox_val for both the Value.Equals and as the node selector: I bet it contains the string "1143"
The problem is that you are passing an integer as XElement name. The name should not begin with a digit. Possible mistake is that in your code you pass combobox.SelectedIndex. If you have configured the combobox properly(i.e 1,"one" 2,"two) you should pass combobox.SelectedValue. If you don't fill the value list of the combobox you can change the code as:
private void pjctsel_cmbbox_SelectedIndexChanged(object sender, EventArgs e)
{
var xmldoc = File.ReadAllText(#"D:\\test.xml");
var str = XElement.Parse(xmldoc);
string cmbbox_val = pjctsel_cmbbox.SelectedIndex==0 ? "one" : "two";
var res = str.Elements(cmbbox_val).Where(x => x.Element("general").Value.Equals(cmbbox_val)).ToList();
MessageBox.Show(res.ToString());
}

handle multiple controls with same name in form collection

I have a form in my asp.net mvc(C#) application which handles some dynamic controls.
On a button click "Add Row", i will add a row dynamically to the existing table as:
$('#btnAddMore').click(function() {
var _userBodyHtml = '';
_userBodyHtml += '<tr><td><input type="text" name="UserName" id="UserName' + _userDynId + '" size="10" /></td>';
_userBodyHtml += '<td><textarea name="UserComments" id="UserComments' + _userDynId + '" cols="60" rows="1"></textarea></td>';
_userBodyHtml += '</tr>';
_userDynId += 1;
$('#UserBody').append(_userBodyHtml);
});
Then the admin adds the username and comments and submits it.
On submit, i am handling it in controller's action as:
var _frmUserNames = new List<String>(form["UserName"].ToString().Split(','));
var _frmUserComments = new List<String>(form["UserComments"].ToString().Split(','));
if (_frmUserNames.Count > 0 && _frmUserComments.Count > 0)
{
List<UserComments> _userComments = Enumerable.Range(0, _frmUserNames.Count)
.Select(i => new UserComments
{
UserName = _frmUserNames[i],
UserComment = _frmUserComments[i]
}).ToList();
}
From the above code, the _frmUserComments returns the comma separated value when there are more than one textbox with the same name as i am differentiating the textboxes only with different ids.
The problem is when the admin enters the usercomments which has a comma(,) within that comment, then the form value _frmUserComments has the comma separated value and it gives invalid data to the List.
When Admin enters(Case 1) which is fine:
Sam Logged on 12/10/2010
David Looking for enhancement
the form values returns:
_frmUserNames = "Sam,David"
_frmUserComments = "Logged on 12/10/2010,Looking for enhancement"
When Admin enters(Case 2) which is problem causing:
Sam Logged on 12/10/2010
David Logged on 03/01/2011, Looking for enhancement
the form values returns:
_frmUserNames = "Sam,David"
_frmUserComments = "Logged on 12/10/2010,Logged on 03/01/2011, Looking for enhancement"
How can i handle the scenario like this.
Looks like you want to bind collection to model. I recommend to do it as Phil Haack does
Try to set dynamic controls name attributes same as IDs (with index - yours's _userDynId). You'll be able to iterate through form collection in controller, something like that (using LINQ):
foreach (var key in form.AllKeys.Where(k => k.StartsWith("UserName")))
{
var index = key.Replace("UserName", "");
var userName = form[key];
var userComment = form["UserComments" + index];
}

Categories

Resources