Get the selected value of a group of HtmlInputRadioButton controls - c#

When using the RadioButtonList control, I can access the selected value in my codebehind with the following:
rbMyButtons.SelectedValue
However, I'd like to use HtmlInputRadioButton controls instead as these give me greater control over the rendered markup. If I'm using a list of <input type="radio" runat="server" /> then, as far as I know, I have to do something like this:
if (rbMyButtonsOption1.Checked)
{
...
}
else if (rbMyButtonsOption2.Checked)
{
...
}
else if ...
Is there a way I can mimic the behaviour of RadioButtonList.SelectedValue without using Request.Form["name"]?

Here's how I would do it:
First, wrap the Html Controls inside a panel or similar grouping object (the panel will be rendered as a div):
<asp:Panel runat="server" ID="ButtonList" ClientIDMode="Static">
<input type="radio" name="seasons" value="Spring" runat="server" />Spring <br/>
<input type="radio" name="seasons" value="Summer" runat="server" /> Summer <br/>
<input type="radio" name="seasons" value="Fall" runat="server" /> Fall <br/>
<input type="radio" name="seasons" value="Winter" runat="server" /> Winter <br/>
</asp:Panel>
Then, create an extension method to access the ControlCollection property of the panel and iterate through the collection:
public static class HelperFunctions
{
public static string GetRadioButtonValue(this ControlCollection collection)
{
foreach (var control in collection)
{
if (control is HtmlInputRadioButton)
{
var radioControl = ((HtmlInputRadioButton)control);
if (radioControl.Checked)
{
return radioControl.Value;
}
}
}
//If no item has been clicked or no Input Radio controls are present we return an empty string
return String.Empty;
}
}
Finally you can get the value with ease:
var selectedValue = ButtonList.Controls.GetRadioButtonValue();

I did some searching to find this, so thought it may be useful even though the question is over 1 year old...
I've just come across this issue. I needed to use use [input type="radio" runat="server" ...] as I had to include additional HTML "data-*" attributes against each selection.
I've used a composite of the two answers here to come with a solution that helped me.
My HTML looks like:
<div id="pnlOpts" runat="server">
<input type="radio" name="rblReason" runat="server" value="1" /> <label>Opt 1</label><br />
<input type="radio" name="rblReason" runat="server" value="3" data-att="1" /> <label>Supplied Reason 1 </label><br />
<input type="radio" name="rblReason" runat="server" value="3" data-att="2" /> <label>Supplied Reason 2 </label><br />
<input type="radio" name="rblReason" runat="server" value="3" data-att="3" /> <label>Supplied Reason 3 </label><br />
</div>
My Code-behind looks like:
if(pnlOpts.Controls.OfType<HtmlInputRadioButton>().Any(a=>a.Checked))
{
HtmlInputRadioButton selected = pnlOpts.Controls.OfType<HtmlInputRadioButton>().Where(a => a.Checked).FirstOrDefault();
var btnValue = selected.Value;
var dataAttVal = selected.Attributes["data-att"];
...
}

You can mimic this behavior using LINQ:
var radioButtons = new[] { rbMyButtonsOption1, rbMyButtonsOption2 };
var checkedRadioButton = radioButtons.FirstOrDefault(i => i.Checked);
if (checkedRadioButton != null)
{
// do something...
}

Related

not wrap ListItem Text in Horizontal CheckBoxList

I have Dynamic CheckBoxList :
<%# Control Language="C#" AutoEventWireup="true" CodeFile="ProjectOrigin.ascx.cs" Inherits="UserControl_PEM_ASPX_ProjectOrigin" %>
<div style="display:block;">
<asp:CheckBoxList ID="CheckBoxList1" runat="server" RepeatDirection="Horizontal" >
</asp:CheckBoxList></div>
and add ListItems in my function
private void ChkListBoxInit()
{
if (CheckBoxList1.Items.Count != 0) return;
CheckBoxList1.Items.Clear();
DesProvider p = new DesProvider();
List<tblDes> list = p.GetByDesGrpId(grpid).OrderBy(a => a.DesId).ToList();
ListItem li;
foreach (var l in list)
{
li = new ListItem(l.DesF, l.val);
CheckBoxList1.RepeatLayout = RepeatLayout.Flow;
CheckBoxList1.Items.Add(li);
}
}
The Html generated by this is:
<div style="display:block;">
<span id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1">
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_0" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$0" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_0">بهبود فرآیند کار</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_1" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$1" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_1">بهبود محیط کار</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_2" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$2" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_2">ایمنی و بهداشت</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_3" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$3" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_3">رفاهی</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_4" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$4" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_4">فروش و مشتریان</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_5" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$5" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_5">کاهش هزینه ها</label>
<input id="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_6" type="checkbox" name="ctl00$MainContent$FormView1$ProjectOrigin1$CheckBoxList1$6" />
<label for="ctl00_MainContent_FormView1_ProjectOrigin1_CheckBoxList1_6">سایر موارد</label>
</span>
</div>
How can i avoid ListItem text wrapping at end off line and keep checkbox and this text together?
Make sure that the <label> elements have the css setting display: block;. This should ensure that the label text all stays on the same line.
You can see this in this jfiddle. The example where the labels have display:inline; shows the same wrapping that you are seeing. The example where the labels have display:block; shows the text staying on the same line.
Update after html was posted in question:
Because the CheckBoxList is producing <input> separate from each related <label>, there is no easy way that I can see to keep them in flow, and guarantee that labels do not wrap and that labels and checkboxes stay on the same row. You could set label, input { float: right; display: block; } in your css, but this would allow labels to be on separate rows from their related inputs.
Best solution that I can see is to not use CheckBoxList. Instead, use a Repeater, with something like the following for layout:
<asp:Repeater id="checkboxes" runat="server">
<ItemTemplate>
<div class="checkboxItem">
<asp:CheckBox runat=server />
</div>
</ItemTemplate>
</asp:Repeater>
You would then data bind the repeater in a similar way, populating the value of CheckBox in each _ItemDataBound event.
Enclosing each CheckBox in a <div> and adding label, .checkboxItem { float: left; } in your css should force the checkboxes and labels to stay on the same line, per the technique showed in this answer.

Input control type Checkbox always true

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

Prevent full postback for UserControl with ValidationProperty attribute

I have an ASP.NET usercontrol that implements the ValidationProperty attribute. This attribute successfully makes it possible for me to use a RequiredFieldValidator for my custom control, however on validation it causes a full postback rather than using client side javascript based validation.
Is there a way to prevent this and enable client side validation without using a custom validator?
This is the what my UserControl looks like.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>
<div class="BooleanRadio">
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
[ValidationProperty("Checked")]
public partial class ucBooleanRadio : System.Web.UI.UserControl
{
public Nullable<bool> Checked
{
get
{
if (radTrue.Checked || radFalse.Checked)
return radTrue.Checked;
else
return null;
}
set
{
radTrue.Checked = value != null ? value.Value : false;
radFalse.Checked = value != null ? !value.Value : false;
}
}
}
And this is how it is being used
<uc1:ucBooleanRadio ID="ucAgree" runat="server" />
<asp:RequiredFieldValidator ID="RequiredFieldValidator6" runat="server" CssClass="Validator" Display="Dynamic" ControlToValidate="ucAgree" InitialValue="" ErrorMessage="You must agree to continue."></asp:RequiredFieldValidator>
Page.Validate();
if (Page.IsValid)
{
//Do stuff
}
Turns out, ASP.NET don't event care about element tag.
I've just looked through validation code and found this
function ValidatorGetValue(id) {
var control;
control = document.getElementById(id);
if (typeof(control.value) == "string") {
return control.value;
}
return ValidatorGetValueRecursive(control);
}
So
<div class="BooleanRadio" id="<%= ClientID %>" value="<%= radTrue.Checked? "true" : radFalse.Checked? "false" : "" %>">
<% radTrue.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='true'"; %>
<% radFalse.Attributes["onclick"] = "document.getElementById('" + ClientID + "').value='false'"; %>
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
actually works :\, as does
<div class="BooleanRadio" id="<%= ClientID %>">
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
</div>
And there is events autohooking - validated element (one with ClientID) and its children are wired to cause validation automatically (look ValidatorHookupControl).
That may result in:
1. user does something
2. validation is performed
3. value to validate is updated (after validation!)
First example with value on div behaves this way.
For a simple client-side validation there should be an input element with corresponding name which value is to be validated. Example of how it could be done in your case:
<div class="BooleanRadio">
<% radTrue.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='+'"; %>
<input runat="server" id="radTrue" type="radio" name="BooleanRadio" value="True" /> Yes
<% radFalse.Attributes["onclick"] = "document.getElementsByName('" + UniqueID + "')[0].value='-'"; %>
<input runat="server" id="radFalse" type="radio" name="BooleanRadio" value="False" /> No
<input name="<%= UniqueID %>" type="hidden" value="<%= radTrue.Checked? "+" : radFalse.Checked? "-" : "" %>" />
</div>
OK, So after significant digging around in the architecture of the ASP.NET field validators and some guidance from the poster above I have finally found the solution.
Basically the answer above is correct barring a couple of changes.
Firstly the id that is set for the hidden text should not be in the Name field but rather the ID field. Further the ID that is populated inside of the Hidden field should not be the Page.UniqueID but rather the Page.ClientID for the UserControl in question.
The reason for this is that when a page that contains validators is loaded the following function is called by the ASP.NET framework.
function ValidatorHookupControlID(controlID, val) {
if (typeof (controlID) != "string") {
return;
}
var ctrl = document.getElementById(controlID); //NOTE THIS LINE
if ((typeof (ctrl) != "undefined") && (ctrl != null)) {
ValidatorHookupControl(ctrl, val);
}
else {
val.isvalid = true;
val.enabled = false;
}
}
What the framework attempts to do is retrieve a control that has the same ID as the ControlToValidate property as set in the required field validator (which is actually Page.ClientID). It then uses this control in its validation functions (whether they be RequiredField, Compare, Regex and so on). If it finds such a control it enables the validator and performs validation against its value, if it doesn't it simply sets the validator to disabled.
In the end my code looks like this.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="ucBooleanRadio.ascx.cs" Inherits="MyCompany.Web.UserControls.ucBooleanRadio" %>
<input id="<% =this.ClientID %>" type="hidden" value="" />
<asp:RadioButton runat="server" ID="radTrue" Text="Yes" GroupName="radio" />
<asp:RadioButton runat="server" ID="radFalse" Text="No" GroupName="radio" />
<script language="javascript" type="text/javascript">
$(function (e) {
$("#<% =radTrue.ClientID %>").click(function (e) {
$("#<% =this.ClientID %>").val("true");
});
$("#<% =radFalse.ClientID %>").click(function (e) {
$("#<% =this.ClientID %>").val("false");
});
});
</script>
And the code behind remains unchanged. Hopefully this explains some of the mystery of whats going on to anyone who runs into the same problem.
Maxim, I've just been working on a similar problem.
I've found that you don't need the JavaScript the Validators will automatically iterate through the controls looking for a "value" that is set.
You must be using server side RadioButtons rather than HTML
If you're using CompositeControls then it will work automatically
If you're using Web User Controls (ascx files) it doesn't wrap the control with an ID so you need to add the following code to your control.
<div id='<%=ClientID %>'>
Your radio button controls here...
</div>
Edit: I've just uploaded some quick sample code. Hope this helps!
Sample Code

Get posted value In C# ASP.NET

I have a dynamic form that allow to add many fields dynamically,
I Know how to get the value of single field in aspnet using : Request.Form["myField"],but here i have more than field and i dont know the count of these fields since these are dynamic
the fields name is "orders[]"
ex:
<form>
<input type="text" name="orders[]" value="order1" />
<input type="text" name="orders[]" value="order2" />
<input type="text" name="orders[]" value="order3" />
</form>
In php,
i get the values as an array by accessing $_POST['orders'];
ex:
$orders = $_POST['orders'];
foreach($orders as $order){
//execute ...
}
how can I do this in c# ?
Use Request.Form.GetValues.
Request.Form is a NameValueCollection, an object that can store a collection of items under the same key and the ToString displays the values in CSV format.
Markup:
<input type="text" name="postField[]" />
<input type="text" name="postField[]" />
<input type="text" name="postField[]" />
<input type="text" name="postField[]" />
<asp:Button Text="text" runat="server" OnClick="ClickEv" />
Code behind:
protected void ClickEv(object sender, EventArgs e)
{
var postedValues = Request.Form.GetValues("postField[]");
foreach (var value in postedValues)
{
}
}
You would use Request.Form[]. Or if your form and fields had runat="server" and ids, you could just use the id in the codebehind and the .Text() method to access its value.
You can access everything that gets sent back to the server by using the Request object.
Request.Form.Items
Is a collection that will contain the item you are looking for.

C# ASPX - Form Submission Query

I have a C# aspx form in which I need to input it's data into an SQL database and then return a response saying successful or not. I have no idea how to get the form data that is sent from the Default.aspx page. My basic code structure is below:
Default.aspx
<form runat="server" name="aForm" action="Results.aspx" method="post" onsubmit="ValidateForm()">
<input name="firstname" type="text" />
<input name="surname" type="text" />
<input type="submit" value="Submit" />
</form>
Results.aspx.cs
public partial class AwardsForm : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!this.IsPostBack){
Response.Redirect("Default.aspx");
} else (this.IsPostBack) {
writeResults(FormSubmit());
}
protected boolean FormSubmit() {
// get form data and insert it into SQL
// return true/false based on success
}
protected void writeResults(boolean results) {
if (results == true) {
Response.Write ("Success");
} else {
Response.Write ("Failed");
}
}
}
You can get the posted form data through Request.Form["key"], or, if your form elements are decorated with runat="server" then you should be able to grab them by id right in your code behind
<asp:TextBox id="yourTb" runat="server"></asp:TextBox>
string postedText = yourTb.Text;
Or you can do (though this is much less common)
<input type="text" runat="server" id="yourOtherTb" />
string otherPostedText = yourOtherTb.Value;
Or if you're working with purely html form inputs:
<input type="text" id="clientTb" name="clientTb" />
string clientText = Request.Form["clientTb"];
You can try by the following code.
string firstname = Request.Form["firstname"]
string surname = Request.Form["surname"]
Since you are doing something like this
<input name="firstname" type="text" />
<input name="surname" type="text" />
<input type="submit" value="Submit" />
the name attribute of the input controls are posted back to the server(IIS). Hence you would do this.
If(IsPostBack)
{
string firstName = Request.Form["firstname"];
string surName = Request.Form["surname"];
if(string.IsNullOrEmpty(firstName))
{
Response.Write("Firstname is required this form");
}
}

Categories