I have this HTML
<div class="Radio">
<label>
<input class id="checkbox" name="category" type="radio" value="1">
<strong> TONY STARK </strong>
</label>
<label>
<input class id="checkbox" name="category" type="radio" value="2">
<strong> IRON MAN </strong>
</label>
<label>
<input class id="checkbox" name="category" type="radio" value="3">
<strong> ROBERT DOWNEY </strong>
</label>
I need to select radio buttons based on TONY STARK , IRON MAN , ROBERT DOWNEY as the user passes it as a flexible parameter
I tried this, but any other easy way would definitely help me!
driver.FindElement(By.Id("checkbox"));
for(WebElement radiobutton: radiobuttons)
{
if(radiobutton.getAttribute("value").equals("TONY STARK"))
radiobutton.click();
}
You should try using Xpath to get single radio button and avoid looping as below :-
string Xpath = ".//input[following-sibling::strong[contains(.,'TONY STARK')]]";
Or
string Xpath = ".//label[contains(.,'TONY STARK')]/input";
Use any one of these Xpath to find radio button as :
var radio = driver.FindElement(By.Xpath(Xpath));
radio.Click();
You can use xpath to do that. Try the below xpath .//label[contains(text(),'TONY STARK')]/input[#id='checbox']
Create a class to wrap up radios from now on:
public class RadioButtons
{
public RadioButtons(IWebDriver driver, ReadOnlyCollection<IWebElement> webElements)
{
Driver = driver;
WebElements = webElements;
}
protected IWebDriver Driver { get; }
protected ReadOnlyCollection<IWebElement> WebElements { get; }
public void SelectValue(String value)
{
WebElements.Single(we => we.GetAttribute("value") == value).Click();
}
}
Then you can use it like this:
RadioButtons categories = new RadioButtons(Driver, driver.FindElements(By.Name("category")));
categories.SelectValue("TONY STARK");
I have this other solution:
public void RadioButtonClickByNameAndValue(string name, string val)
{
ScreenComponent.Wait.WaitVisibleElement(By.Name(name));
ScreenComponent.Script.ExecuteJavaScriptCode($"$('[name={name}][value={val}]').click();");
}
In another class I say what value I want to click and in another class I say what is the element.
in my case the radio options value are "True" and "False".
Identify a radio button using XPath with index
IWebElement radioButton = driver.FindElement(By.XPath("//*[#type='radio'][1]");
radioButton.Click();
where:
Asterisk * means wildcard character.
[1] is the position of radio button options ("TONY STARK")
Related
I have a set of radio buttons on a razor page, and I want to get and use the selected value of these radio buttons in my server-side code once the form has been submitted. HTML for radio buttons:
<label><input class="boost_radio" onclick="boostNo(1)" asp-for="Boost_No.Number" type="radio" name="boostno" value=1 checked="checked" disabled="disabled" />1</label>
<label><input class="boost_radio" onclick="boostNo(2)" asp-for="Boost_No.Number" type="radio" name="boostno" value=2 disabled="disabled" />2</label>
<label><input class="boost_radio" onclick="boostNo(3)" asp-for="Boost_No.Number" type="radio" name="boostno" value=3 disabled="disabled" />3</label>
<label><input class="boost_radio" onclick="boostNo(4)" asp-for="Boost_No.Number" type="radio" name="boostno" value=4 disabled="disabled" />4</label>
<span asp-validation-for="Boost_No.Number"></span>
I am using model binding to get the value on the server-side:
public class BoostNo
{
[Required(ErrorMessage = "Select Number of Boost Units!")]
public int Number { get; set; }
}
This class is instantiated as follows:
[BindProperty]
public BoostNo Boost_No { get; set; }
Unfortunately, every time I run the code, I get a Boost_No.Number = 0. I tried changing the data type to a string, but I just get string = null.
I am trying to use the model-bound variable in the handler method assigned to the form the radio buttons are contained in.
I'd really appreciate it if someone could help me out. Thanks.
Edit:
Here is the handler method in which the model binding is used:
public IActionResult OnPostSubmit()
{
//save data to sql db
SaveData();
//then some other unrelated stuff
}
And the SaveData() method:
public void SaveData()
{
//stuff
//now how the radio button values are actually used
for (int param_i = 1; param_i <= Boost_No.Number; param_i++)
{
//...
}
//then a paramaterized sql database query
}
All of your radio inputs are set to disabled so no value will be passed in the form collection when the form is submitted. Remove the disabled (and the name) attributes from the inputs:
<label><input class="boost_radio" onclick="boostNo(1)" asp-for="Boost_No.Number" type="radio" value=1 checked="checked" />1</label>
<label><input class="boost_radio" onclick="boostNo(2)" asp-for="Boost_No.Number" type="radio" value=2 />2</label>
<label><input class="boost_radio" onclick="boostNo(3)" asp-for="Boost_No.Number" type="radio" value=3 />3</label>
<label><input class="boost_radio" onclick="boostNo(4)" asp-for="Boost_No.Number" type="radio" value=4 />4</label>
Here is a minimal Example I setup to make it work.
Here is my razor page handle and I use the same class implementation as you.
[BindProperty]
public BoostNo Boost_No { get; set; }
public IActionResult OnPost()
{
return Page();
}
Now in the HTML
<label><input asp-for="Boost_No.Number" type="radio value=1 checked="checked"/>1</label>
<label><input asp-for="Boost_No.Number" type="radio" value=2/>2</label>
<label><input asp-for="Boost_No.Number" type="radio" value=3/>3</label>
<label><input asp-for="Boost_No.Number" type="radio" value=4/>4</label>
Changes:
First remove the name attribute. Why? because the asp-for tag helper will create a name attribute for you. In addition to providing a name attribute you give it a value of boostno, the name attribute is used to bind the value to the Model, in other words your OnPost handle doesn't have a boostno parameter anywhere to get bound to.
Secondly if an input field is disabled the input value will be ignored. I would double check that before you submit the form open developer tools (F12) and double check your input field elements to make sure they are not disabled, even though the UI might suggest otherwise.
if these are individual radio buttons, you should have individual binding for each of those, for now you are using same for each of the radio button. (Boost_No.Number).
Either create a list of List and then bind individual radio button lik
"Boost_No[0].Number" or create different properties for each of those (your choice)
i'm trying to use a asp-for and a condition inside a component but i can't find a way to do that.
Here's my code
<label asp-for="#Model.Selected">
#Model.Nome
<input type="checkbox" asp-for="#Model.Selected" />
</label>
and I wanna some like
<label asp-for="#Model.Selected">
#Model.Nome
<input type="checkbox" asp-for="#Model.Selected" #((Model.Unlucky) ? "disabled") />
</label>
How can i do this in ASP.Net Razor
I think you can add a new variable after that one and build the string to disable the input:
#{
var disabledTag = Model.Unlucky == null ? "disable" : "";
}
<input type="checkbox" asp-for="#Model.Selected" #disabledTag) />
Assumed that you're using Core MVC, you have two options to set disabled attribute conditionally inside <input> tag helper. Here are those options:
Option 1 - Using HTML helper
Create a static class which returns HtmlString to set disabled attribute with ternary operator:
public static class HtmlExtensions
{
public static IHtmlContent SetDisabled(this IHtmlHelper helper, bool value)
{
return new HtmlString(value ? #"disabled=""disabled""" : "");
}
}
And then use that helper inside Razor view:
<input type="checkbox" asp-for="#Model.Selected" #Html.SetDisabled(Model.Unlucky) />
Option 2 - Create Tag Helper Attribute
You can build a custom class derived from TagHelper instance and specify target element to add disabled attribute:
[HtmlTargetElement("checkbox")]
public class DisabledCheckBox : TagHelper
{
[HtmlAttributeName("asp-disabled")]
public bool IsDisabled { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
if (IsDisabled)
{
var d = new TagHelperAttribute("disabled", "disabled");
output.Attributes.Add(d);
}
base.Process(context, output);
}
}
Then you could use that attribute inside tag helper:
<input type="checkbox" asp-for="#Model.Selected" asp-disabled="#Model.Unlucky" />
Notes:
1) For both options, make sure that you've tag helper support enabled inside _ViewImports.cshtml, by checking existence of these lines below:
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#addTagHelper *, YourProjectNamespace
2) disabled attribute is a boolean attribute which when exist, it disabled the input element no matter what value it has. Therefore, disabled attribute must be absent if you want to keep it enabled.
You need a ternary operator. You can use it like this. Assuming Model.Unluck is a string, otherwise you need to use ToString() on it because both results must be of the same datatype.
<input type="checkbox" asp-for="#(Model.Selected ? Model.Unluck : "disabled")" />
If Model.Unluck is the boolean for the operator, then you do this.
<input type="checkbox" asp-for="#(Model.Unluck ? "enabled" : "disabled")" />
<input type="checkbox" asp-for="#(Model.Unluck ? "true" : "false")" />
You don't need any ternary operations or custom tag helpers to make element disabled in razor.
You can just use:
<input disabled="#Model.Unlucky" />
It will render <input disabled="disabled" /> if Model.Unlucky is true, and will omit disabled attribute completely if Model.Unlucky is false.
It also can be used with readonly or any other attributes where you need such behavior.
The trick here is that attribute value should have boolean type to be interpreted this way. For example if #Model.Unlucky is a string "true", it will just render as is disabled="true".
In a view I have two <input type="radio">, combine they make a radio group.
I want to bind them with a field of Model, in a way if value is true it should bind first radio button if false it should bind the other.
Please guide how it can be achived. I tried below code but it always checked the second radio no matter what value model has.
<div class="radiobuttons">
<input type="radio" name="LenderType" checked="#Model.Filter_Value" id="rbtnAllLenders" class="cb">
<input type="radio" id="rbtnMajorLendersOnly" checked="!#Model.Filter_Value" name="LenderType" class="cb">
</div>
The input typed as radio needs to have a value set. If the radio is checked, then the value is what is sent for the name in the model.
view model
public class SomeViewModel
{
public int MyRadioValue { get; set; }
}
input element
<input type="radio" value=1 name="MyRadioValue" />
<input type="radio" value=2 name="MyRadioValue" />
<input type="radio" value=3 name="MyRadioValue" />
Create Html Helper ....
public static HtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, IEnumerable<SelectListItem> selectListItems, RadioButtonListLayout layout)
{
var sb = new StringBuilder();
foreach (var item in selectListItems)
{
var itemId = string.Format(
CultureInfo.InvariantCulture,
"{0}_{1}",
helper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression)),
item.Value);
var itemHtml = string.Format(
CultureInfo.InvariantCulture,
"{0} <label for=\"{1}\">{2}</label>",
helper.RadioButtonFor(expression, item.Value, new { id = itemId }),
itemId,
item.Text);
if (layout == RadioButtonListLayout.Horizontal)
{
sb.Append("<span class=\"radiobuttonlist-horizontal\">");
sb.Append(itemHtml);
sb.AppendLine("</span>");
}
else
{
sb.Append("<div class=\"radiobuttonlist-vertical\">");
sb.Append(itemHtml);
sb.AppendLine("</div>");
}
}
return new HtmlString(sb.ToString());
}
Use it ...
#Html.RadioButtonListFor(x=>x.Id,Model.ListItem,RadioButtonListLayout.Horizontal)
You manual code is adding the selected attribute to both radio buttons. All the following are equivalent:
<input type="radio" ... checked />
<input type="radio" ... checked="selected" />
<input type="radio" ... checked="true" />
<input type="radio" ... checked="false" />
Note the last 2 are invalid values for the checked attribute, but still check the radio button. Since you have a group name, and only one button can be visually checked, the last one rendered is selected. Refer W3C specifications.
Use html helpers to bind to your model. If the model contains property string LenderType then
#Html.RadioButtonFor(m => m.LenderType, "All lenders", new { id = "All"})<label for="All">All lenders</label>
#Html.RadioButtonFor(m => m.LenderType, "Major lenders", new { id = "Major"})<label for="Major">Major lenders</label>
If the value of LenderType is "All lenders" the first option will be selected. If the value is "Major lenders", then the second option will be selected
I have written some code to parse the name from some radio buttons.
<div id="First" class="Size-Inputs">
<input rel="8" type="radio" value="13051374" name="idProduct-13051359"/> <span rel="L">L</span>
<input rel="8" type="radio" value="13051373" name="idProduct-13051359"/> <span rel="M">M</span>
<input rel="8" type="radio" value="13051372" name="idProduct-13051359"/> <span rel="S">S</span>
<input rel="8" type="radio" value="13051375"name="idProduct-13051359"/> <span rel="XL">XL</span> </div>
The problem which I am having when I try to parse the span rel to get the size names eg L,M,S,XL it is only coming up with the value L four times.
The code I am using is;
HtmlNodeCollection link = doc.DocumentNode.SelectNodes("//*[#id='First']/input");
if (link != null)
{
foreach (HtmlNode item in link)
{
string name = item.SelectSingleNode("//*[#id='First']/span").InnerText;
Console.WriteLine(name);
}
Console.ReadLine();
}
I was just wondering why the it is only picking up one value and printing it four times and how can you make it pick up the span rel for each of the variant input. Thanks for any help which you can provide
It seems that you don't need <input> element but <span> element. And <span> is not child of <input>. So assuming that it isn't typo or paste error, you can select <span> directly without selecting <input> element first :
HtmlNodeCollection link = doc.DocumentNode.SelectNodes("//*[#id='First']/span");
if (link != null)
{
foreach (HtmlNode item in link)
{
string name = item.InnerText;
Console.WriteLine(name);
}
Console.ReadLine();
}
I have searched all the topics discussing this issue and cant seem to find one that explains the issue using Asp.net C#, everything is either javascript or MVC or PHP my reasoning for opening a new question regarding this.
I have 2 input control type checkbox
<input runat="server" type="checkbox" name="chkChildSexMale" id="chkChildSexMale" />
<input runat="server" type="checkbox" name="chkChildSexFemale" id="chkChildSexFemale"/>
<asp:Button ID="btnSaveCheckBoxes" runat="server" Text="Save CheckBox" OnClick="btnSaveCheckBoxes_Click" />
*EDITED**
protected void SaveCheckBoxes()
{
if (chkChildSexMale.Checked)
{
do something
}
else if (chkChildSexFemale.Checked)
{
do something else
}
}
Then in my button click event I call this method
protected void btnSaveCheckBoxes_Click(object sender, EventArgs e)
{
SaveCheckBoxes();
}
You should be using input type radio, not checkbox, for two mutually exclusive selections:
<input runat="server" type="radio" name="chkChildSex" value="male" id="chkChildSexMale" />
<input runat="server" type="radio" name="chkChildSex" value="female" id="chkChildSexFemale" />
When you use the same name attribute for two checkboxes, the second overrides the first. When you use the same name attribute for two radio buttons, it associates them and the value is the value of the checked item.
Although the id attribute is different for both checkboxes the name attribute is the same.
Also, the suggestion about using radio buttons makes the most sense based on what it looks like you're trying to do.
<input runat="server" type="radio" name="rdoChildSex" value="Male" />
<input runat="server" type="radio" name="rdoChildSex" value="Female" />
Again, I would recommend going with the radio button example above when you need to pick between one of two options. But if you want to get radio-like functionality for checkboxes you can try this...
<input runat="server" type="checkbox" name="chkChildSexMale" value="Male" OnCheckedChanged="Check_Clicked" />
<input runat="server" type="checkbox" name="chkChildSexFemale" value="Female" OnCheckedChanged="Check_Clicked"/>
void Check_Clicked(Object sender, EventArge e)
{
var checkbox = ((CheckBox)sender);
if (checkbox.Value == "Male")
{
chkChildSexFemale.Checked = false;
chkChildSexMale.Checked = true;
do something...
}
else
{
chkChildSexMale.Checked = false;
chkChildSexFemale.Checked = ;
do something else...
}
}
The code above should REALLY cover all your bases. It is even somewhat overkill. But is should work.
Try changing your code to the following:
if (chkChildSexMale.Checked == true)
{
do something
}
else if (chkChildSexFemale.Checked == false)
{
do something else
}
My issue was on page load I was using my data reader to set the checkboxes based on certain values. Which when I clicked my button click it was over writing my selected values with values from the database. So I Had to add the if (!Page.IsPostBack)
Giving the information I provided it would have been really hard to figure out that so I thank all for trying to help