Find Html Checkboxes - c#

How can I find dynamically generated Html Checkboxes from C#.
Need to find them by id and mark them as checked.
This code generates the HTML first:
StringBuilder sbHtml = new StringBuilder("");
sbHtml.Append("<div class=\"checkboxBtn\">");
sbHtml.Append("<input type=\"checkbox\" runat=\"server\"
class=\"chkBx\" id=\"" +
Convert.ToString(someid) + "\" />");
sbHtml.Append("<label>Compare</label>");
sbHtml.Append("</div>");
and the rendered HTML is
<div class="checkboxBtn">
<span class="uncheked"></span>
<input type="checkbox" runat="server" class="chkBx" id="23"></input>
<label>Compare</label>
</div>
There are many such checkboxes and I would like to find them by IDs
string[] PhoneIds = {"11","23","43"};
foreach(string id in PhoneIds)
{
HtmlInputCheckBox cBox = form1.FindControl(id) as HtmlInputCheckBox;
if(cBox!=null)
{
//cb.checked = true;
}
}
The if condition always fails as if the checkboxes dont exist. What should be done here.

you are assigning only one number to your string-arrey PhoneIds:
string[] PhoneIds = ["11,23,43"];
instead you need to use:
string[] PhoneIds = {"11","23","43"};
Then you will find them.
Because otherwise you would assign one string to your array, and thisone would be 11,23,43 and as far as you have no checkbox with that string, the if-condition fails.
Also you should not use numbers as ID's, as you can check out in this answer, where it states that until HTML5
ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
you must start with a letter. Maybe your browser doesn't support HTML5 ?

Element IDs in HTML must not start with a number. That may be why ASP.NET can't find it either. I would put a prefix on it, such as cbox11.
To fix the HTML:
StringBuilder sbHtml = new StringBuilder("");
sbHtml.Append("<div class=\"checkboxBtn\">");
sbHtml.Append("<input type=\"checkbox\" runat=\"server\"
class=\"chkBx\" id=\"cbox" +
Convert.ToString(someid) + "\" />");
sbHtml.Append("<label>Compare</label>");
sbHtml.Append("</div>");
And for the loop
string[] PhoneIds = {"11", "23", "43"};
foreach(string id in PhoneIds)
{
HtmlInputCheckBox cBox = form1.FindControl("cbox" + id) as HtmlInputCheckBox;
if(cBox!=null)
{
//cb.checked = true;
}
}

You don't need to check these in the code behind, it can be done in jQuery:
<div class="checkboxBtn">
<span class="uncheked"></span>
<input type="checkbox" runat="server" class="chkBx" id="23"></input>
<label>Compare</label>
</div>
<script type="text/javascript">
$(function(){
$('div.checkboxBtn input[type="checkbox"]').prop('checked', true);
});
</script>
This will check all child checkboxes of div.checkboxBtn.

Related

XPath, select multiple elements from multiple nodes in HTML

I just can't figure this one.
I have to search through all nodes that have classes with "item extend featured" values in it (code below). In those classes I need to select every InnerText of <h2 class="itemtitle"> and href value in it, plus all InnerTexts from <div class="title-additional">.
<li class="item extend featured">
<div class="title-box">
<h2 class="itemtitle">
<a target="_top" href="www.example.com/example1/example2/exammple4/example4" title="PC Number 1">PC Number 1</a>
</h2>
<div class="title-additional">
<div class="title-km">150 km</div>
<div class="title-year">2009</div>
<div class="title-price">250 €</div>
</div>
The output should be something like this:
Title:
href:
Title-km:
Title-year:
Title-Price:
--------------
Title:
href:
Title-km:
Title-year:
Title-Price:
--------------
So, the question is, how to traverse through all "item extend featured" nodes in html and select items I need above from each node?
As I understand, something like this should work but it breaks halfway
EDIT: I just noticed, there are ads on the site that share the exact same class and they obviously don't have the elements I need. More problems to think about.
var items1 = htmlDoc.DocumentNode.SelectNodes("//*[#class='item extend featured']");
foreach (var e in items1)
{
var test = e.SelectSingleNode(".//a[#target='_top']").InnerText;
Console.WriteLine(test);
}
var page = new HtmlDocument();
page.Load(path);
var lists = page.DocumentNode.SelectNodes("//li[#class='item extend featured']");
foreach(var list in lists)
{
var link = list.SelectSingleNode(".//*[#class='itemtitle']/a");
string title = link.GetAttributeValue("title", string.Empty);
string href = link.GetAttributeValue("href", string.Empty);
string km = list.SelectSingleNode(".//*[#class='title-km']").InnerText;
string year = list.SelectSingleNode(".//*[#class='title-year']").InnerText;
string price = list.SelectSingleNode(".//*[#class='title-price']").InnerText;
Console.WriteLine("Title: %s\r\n href: %s\r\n Title-km: %s\r\n Title-year: %s\r\n Title-Price: %s\r\n\r\n", title, href, km, year, price);
}
What you are trying to achieve requires multiple XPath expressions as you can't return multiple results at different levels using one query (unless you use Union perhaps).
What you might be looking for is something similar to this:
var listItems = htmlDoc.DocumentNode.SelectNodes("//li[#class='item extend featured']");
foreach(var li in listItems) {
var title = li.SelectNodes("//h2/a/text()");
var href = li.SelectNodes("//h2/a/#href");
var title_km = li.SelectNodes("//div[#class='title-additional']/div[#class='title-km']/text()");
var title_... // other divs
}
Note: code not tested

how to select by text using selenium and c#

I need to select the value (hours) related to an specific date. For example in the html below I need to read the number 24:20 based on the number 6;
this is the html:
<div class="day-ofmonth">
<div class="day-ofmonth">
<span class="day-num">6</span>
<span class="available-time">24:20</span>
</div>
<div class="day-ofmonth">
<span class="day-num">7</span>
<span class="available-time">133:50</span>
</div>
<div class="day-ofmonth">
<div class="day-ofmonth">
if I use:
IWebElement t_value = d.FindElement(By.XPath(".//* [#id='calinfo']/div[9]/span[2]"));
var t_again2 = t_value.GetAttribute("textContent");
i will get 24:20; but i need to get the value 24:20(in this case) based on number 6 (6 refers to day of the month) and not the Xpath (everyday will be a different date). If anyone can point me in the right direction, Thanks
string availableTime = null;
// Find all elements with class = 'day-num'
var dayNums = d.FindElements(By.XPath("//span[#class='day-num']"));
foreach (IWebElement dayNum in dayNums)
{
// check if text is equal to 6
if (dayNum.Text == "6")
{
// get the following sibling with class = 'available-time', then get the text
availableTime = dayNum.FindElement(By.XPath("following-sibling::span[#class='available-time']")).Text;
break;
}
}
A one liner solution:
string availableTime = d.FindElement(By.XPath("//span[#class='day-num' and text()='6']/following-sibling::span[#class='available-time']")).Text;
xpath=//span[text()='6')]/following-sibling::span[1]

How Can DeActivate Razor Html Encoding ?

In Razor view I have a Javascript function. This function take 2 URLS String in arguments and call AJAX to do operation.
When I generated Url string in Razor, Razor change the URLS. Like changed & to & and damage my query strings which used in my URL address. Also Html.Raw() has not work in this case.
What can I do ?
EXAMPLE:
In my Razor editor:
<a href="#" style="color:#0564c1;" onclick="PopUpStart('POST','','',200,100,'#(Html.Raw(address+"/index/?id="+baseObject.Id+"&"+"type="+dataTypeInt))','#Html.Raw(address + "/cancel/?id="+baseObject.Id+"&type="+dataTypeInt )','ReloadPage',true);return false;">
Edit
</a>
In result :
<a href="#" style="color:#0564c1;" onclick="PopUpStart('POST','','',200,100,'/PdfInstanceEdit/index/?id=1&type=270','/PdfInstanceEdit/cancel/?id=1`&`type=270','ReloadPage',true);return false;">
Edit
</a>
The URL address like :
address+"/index/?id="+baseObject.Id+"&"+"type="+dataTypeInt
Change to :
/PdfInstanceEdit/index/?id=1&type=270
In other world character & => &
Its usually a bad idea to try and combine server code and client strings inside the quotes of a property (ie onclick="something#(something())" )
Its better to just return the entire lot in a server side function
Here's how I would rework your code:
<a href="#" style="color:#0564c1;"
onclick="#Html.Raw(
String.Format(
"PopUpStart('POST','','',200,100,'{0}','{1}','ReloadPage',true);return false;"
, Url.Action("index",address,new{id = baseObject.Id, type = dataTypeInt})
, Url.Action("cancel",address,new{id = baseObject.Id, type = dataTypeInt})
)
)"/>
Edit
</a>
Also note the difference between #(Html.Raw()) and #Html.Raw() - you should use the latter!
As direct assignment of events such as onClick is frowned on these days, a better way to accomplish then may be through js:
Add a hidden field for Id and dataTypeInt to your page:
#Html.HiddenFor(model=> model.Id)
#Html.Hidden("dataTypeInt ", dataTypeInt)
Add an id to your anchor:
Edit
Then your script:
<script>
$(document).ready(function () {
readyLinks();
});
readyLinks = function(){
var id = $('#Id).val();
var dataType = $('#dataTypeInt').val();
var indexUrl = '/PdfInstanceEdit/index?id=' + id + '&type=' + dataType;
var cancelUrl = '/PdfInstanceEdit/cancel?id=' + id + '&type=' + dataType;
$('#editLink).on('click', function(){
PopUpStart('POST','','',200,100,indexUrl, cancelUrl,'ReloadPage',true);
return false;
});
};
</script>
You should use Html.Raw() as suggested in the comments, see the documentation.
As described in this thread, if you have a particular problem with the output encoded format, you could use the HttpUtility.HtmlDecode() function, see documentation.
#Html.Raw(HttpUtility.HtmlDecode(address+"/index/?id="+baseObject.Id+"&"+"type="+dataTypeInt))
But since this could be a solution I cannot address you problem precisely...
A friendly reminder: if you're trying to put a Javascript string inside an HTML attribute, the value must be encoded twice. It must first be Javascript-encoded, then that result must be HTML-encoded. You could inadvertently open an XSS hole in your site if you don't perform both encodings in the correct order.
Say you have a string s that you want to display to the client. You'd write your Razor markup as:
Click me
Note the explicit call to JavaScriptStringEncode. Then Razor's # syntax will auto-HtmlEncode this value before writing it to the response.

Mutliple checkbox with same name attribute looping

I have a html form that submits to a C# ashx handler that i'm hoping will insert/update the database
I've written this in PHP and Coldfusion, but I cannot figure out how to do this in C#
HTML form
<form id="copyto">
<input type="hidden" name="operation" value="update" />
<label><input type="checkbox" name="children[]" checked="checked" value="001">
Andrew Regan</label>
<label><input type="checkbox" name="children[]" checked="checked" value="101">
Arthur Regan, III</label>
<input type="checkbox" name="children[]" checked="checked" value="968">
Tim Reagan
</form>
C# ASHX handler
foreach(string key in context.Request.Params["children"])
{
ListDictionary updateParams = new ListDictionary();
updateParams.Add("rowid", key);
string sSql = #"insert into temp select * from children where c.id = :rowid";
dbi.ExecuteNonQuerySql(sSql, updateParams);
}
Typically i would iterate over the $_POST['children'] in php , and execute the sql
How exactly does this translate?
EDIT
ok ive almost gotten this, however my iterator goes over ALL of the request collection variables, i want it to go over only a specific named variable, in this case "children"
i.e localhost/page?operation=update&children=9&children=8&children=17
foreach(string key in context.Request.QueryString)
{
ListDictionary updateParams = new ListDictionary();
updateParams.Add("row_id", context.Request.QueryString[key]);
string sSql = #"insert into dug select :row_id from dual";
dbi.ExecuteNonQuerySql(sSql, updateParams);
}
i want it to ignore everything but the specific var
If you are doing a post. I think something like this would work.
<input type="checkbox" name="children" value="108"/>
<input type="checkbox" name="children" value="109"/>
<input type="checkbox" name="children" value="110"/>
<input type="checkbox" name="children" value="111"/>
The browser will send all of the values comma seperated to the server when the form is submited
Then on your server side you can do this:
var selected = context.Request.Form["children"].Split(',');
Selected will be an array of strings for each value that was passed in by the browser. You can then loop over them and do whatever you need to.
Hope this helps some.
I was just working on this yesterday. I ended up using a hidden field that will hold the multiple checked checkbox id's. So, if that route works for you, you could create a checkboxlist editor template or control. This could have a script such as:
(tempId will hold the common "name" attribute's value for your checkbox/checkboxlist, and we have the "somehiddenfield" hidden field to hold the selected values)
<script>
$(function () {
var arrTmp = [];
//Update array on selection change
$('input[name="#String.Format("{0}[]", tempId)"]').change(function () {
arrTmp = [];
$('input:checked[name="#String.Format("{0}[]", tempId)"]').each(function () { arrTmp.push($(this).val()); });
$('input[id="somehiddenfield"]').val(arrTmp.join(','));
});
});
</script>
Then, on postback on the server-side the form collection will simply have the hidden field we wrote the checked values into. Split that in whatever way works for you (like comma separated in my example) and you're good to go. My server-side is implemented in MVC but for WebForms you can pull the elements from the Request.Form dictionary (Request.Form["somehiddenfield"].ToString()) or even Request.Params as you are using.
Right after i put out the bounty of course -_-
foreach (string k in context.Request.QueryString)
{
if (k.StartsWith("children")){
foreach (string v in context.Request.QueryString.GetValues(k)){
ListDictionary updateParamss = new ListDictionary();
updateParamss.Add("row_id", v);
string Sql = #"insert into dug select :row_id from dual";
dbi.ExecuteNonQuerySql(Sql, updateParamss);
}
}
}

Show a checkbox for true value

I have a WebGrid that shows value from my table and an edit button. when a user clicks this button a pop up form or dialog form comes out and its populated with values from the same table I mentioned earlier.
I have managed to format date values and now interested in formatting the boolean value (true/false ) from my table to be displayed in a checkbox. At the moment its displayed as a textbox with value true or false.
Below is part of my code:
$('#dialog-form2-edit').dialog(
{
//dialog form code .. this is fine
$.getJSON('/Methods/GetCertificate/' + $(this).attr('id'), function (data)
{ var certificate = data;
$('#edit-paid').val(certificate.Paid);
$('#edit-mark').val(certificate.Mark);
var date = new Date(parseInt(certificate.MarkDate.substr(6)));
var year = date.getFullYear();
var month = date.getMonth() + 1;
var day = date.getDate();
$('#edit-markdate').val(year + '-' + month + '-' + day);
$('#edit-markdate').datepicker({ dateFormat: 'yy-mm-dd' });
Below is part of my html
<div id="dialog-form2-edit" title="Edit Certificate">
<form id="edit-certificate-form" action="#Href("~/Methods/UpdateCertificate")">
<div class="row">
<span class="label"><label for="markdate">Mark Date :</label></span>
<input type="text" name="markdate" id="edit-markdate" size="20"/>
</div>
<div class="row">
<span class="label"><label for="mark">Mark :</label></span>
<input type=text" name="mark" id="edit-mark" size="15"/>
</div>
The value Mark and Paid are boolean. Now I intend to have the type changed to text and need help to format the boolean value to checkbox.
If you have a server-side bool value, you can use conditional attributes in Web Pages 2 to manage checkboxes. You provide the bool to the checked attribute of the checkbox using Razor:
#{ var myBool = true; }
<input type="checkbox" name="mark" id="mark" checked="#myBool" />
If the bool is true, checked="checked" is rendered. If it is false, the checked attribute is not rendered at all.
Use this code to display your boolean value in checkbox.
$.getJSON('/Methods/GetCertificate/' + $(this).attr('id'), function (data)
{
var certificate = data;
if(certificate.Pass == true){
$('#edit-pass').attr('checked', 'checked')}
else {$('#edit-pass').removeAttr('checked', 'checked')};
// your other json data
})
The removeAttr is necessary since I am using jquery-1.4.2.min.js. Tested and its working

Categories