Validate TextBox based on DropDownList selection - asp.net

I need to validate TextBox based on Value selected in DropDownList controls. I have asp:TextBox and asp:DropDownList controls.
If user selects Yes option from the first dropdown he must type value in text box. How can I validate second box? Thanks for help.

The simplest approach is to set the DropDownList's AutoPostBack property to true and handle it's SelectedIndexChanged event. Then you can Enable/Disable the validator there.
Another approach is to use a CustomValidator. This validator is not dependent on a single control. You must write the validation rules on your own. For example the ClientValidationFunction:
<script type="text/javascript" >
function ClientValidate(source, arguments) {
var txt = document.getElementById('TextBox1');
var ddl = document.getElementById('DropDownList1');
var decision = ddl.options[ddl.selectedIndex].text;
if(decision=='Yes'){
arguments.IsValid = txt.value.length > 0;
}else{
arguments.IsValid = true;
}
}
</script>
<asp:DropDownList id="DropDownList1" runat="server">
<asp:ListItem Selected="True">Yes</asp:ListItem>
<asp:ListItem Selected="False">No</asp:ListItem>
</asp:DropDownList>
<asp:TextBox id="TextBox1" runat="server" />
<asp:Button ID="BtnSubmit" runat="server" Text="Submit" />
<asp:CustomValidator id="CustomValidator1"
ValidateEmptyText="true"
ControlToValidate="TextBox1"
ClientValidationFunction="ClientValidate"
OnServerValidate="ServerValidation"
Display="Static"
ErrorMessage="Please enter text!"
runat="server"/>
Remember to always implement a OnServerValidate because you should not rely on javascript only(can be disabled). This is easy:
void ServerValidation(object source, ServerValidateEventArgs args){
args.IsValid = DropDownList1.SelectedIndex == 1 || TextBox1.Text.Length > 0;
}
VB.NET
Protected Sub ServerValidation(source As Object, args As System.Web.UI.WebControls.ServerValidateEventArgs)
args.IsValid = DropDownList1.SelectedIndex = 1 OrElse TextBox1.Text.Length > 0
End Sub

Add this code to your submit button.
if(DropDownList1.SelectedItem.Text.Equals("Yes") && TextBox1.Text.Length==0)
{
Page.ClientScript.RegisterStartupScript(this.GetType(), "myalert", "alert('Enter data in the textbox !');", true);
}

Add a CustomValidator control, that validates the TextBox, from there you'll have to do something like this (assuming C#) in the CustomValidator_ServerValidate event handler:
bool valid = false;
if (dropDownList.SelectedValue.Equals("yes")) {
valid = !String.IsNullOrEmpty(textBox.Text);
}
return valid;

Related

Iterating through EditItemTemplate textboxes in asp:Gridview

I have a gridview displaying data within a template field which requires more information about the record to be displayed by clicking on a linkbutton. Right now, I have the "details" linkbutton display the information by calling the edit command on the gridview so that it switches to the EditItemTemplate. Within the EditItemTemplate I have a linkbutton for cancel and then an edit button that, when clicked, displays the update button with the update command, but I need it to iterate through that row and set all the textboxes within the EditItemTemplate to ReadOnly=false so as to allow them to be edited before the update command is selected. Here is a summary of the code:
<ItemTemplate>
*basic information displayed*
<asp:LinkButton runat="server" CommandName="Edit" Text="Details"></asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
*A bunch of readonly textboxes that display the extra information*
<asp:LinkButton runat="server" CommandName="Update" Text="Update" Visible="false"></asp:LinkButton>
<asp:LinkButton runat="server" Text="Edit" OnClick="editButton_Click"></asp:LinkButton>
</EditItemTemplate>
And the code for the event which makes the buttons appear the way I want, but I'm not sure how to iterate through the EditItemTemplate, or even if this is what I should do:
Protected Sub editButton_Click(sender As Object, e As EventArgs)
sender.FindControl("updateButton").Visible = True
sender.FindControl("editbutton").Visible = False
For Each t In ?EditItemTemplate?
Dim textbox = TryCast(t, System.Web.UI.WebControls.TextBox)
If textbox IsNot Nothing Then
textbox.ReadOnly = False
End If
Next
End Sub
So my question is either how to get this to work, or how I should set up the GridViewCommands otherwise
You should use a PlaceHolder in your EditItemTemplate. Place all of your Controls/LinkButtons inside this placeholder.
<EditItemTemplate>
<asp:PlaceHolder ID="TestPlaceHolder" runat="server">
// Sample Link Buttons
<asp:LinkButton runat="server" CommandName="Update" Text="Update"
Visible="false"></asp:LinkButton>
<asp:LinkButton runat="server" Text="Edit" OnClick="editButton_Click"></asp:LinkButton>
// Sample Text Box
<asp:TextBox runat="server" ID="FirstName" ...>...</TextBox>
</asp:PlaceHolder>
</EditItemTemplate>
Handle the RowEditing event of GridView. Inside the edit event handler, first find the Placeholder, then use the PlaceHolder's Controls property to iterate over the Controls...
protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
{
// Get the Placeholder for the row being edited.
PlaceHolder testPlacehldr =
GridView.Rows[e.NewEditIndex].FindControl("TestPlaceholder") as PlaceHolder;
// Iterate over the controls
if(testPlacehldr.Controls.Count > 0)
{
foreach (Control ctrl in testPlacehldr.Controls)
{
if (ctrl is LinkButton)
{
LinkButton lnkBtn = ctrl as LinkButton
if(lnkBtn.Text== "Update")
{
lnkBtn.Visible = false;
}
// More IF conditions follow....
}
if (ctrl is TextBox)
{
TextBox txtBox = ctrl as TextBox;
if(txtBox.ID == "FirstName")// use any property of TexBox you prefer
{
txtBox.ReadOnly= true;
}
// More IF conditions follow....
}
}
}
//At the End, set the EditIndex and Bind the data
GridView1.EditIndex = e.NewEditIndex;
BindGridViewData();
}
I hope you can workout the logic yourself now for hiding/showing the controls.
So I figured out how to do it (needed it in vb) by using the placeholder within the EditItemTemplate, here's the code behind it:
Protected Sub editButton_Click(sender As Object, e As EventArgs)
sender.FindControl("editbutton").Visible = False
sender.FindControl("updateButton").Visible = True
Dim testPlacehldr As PlaceHolder = sender.FindControl("TestPlaceholder")
If testPlacehldr.Controls.Count > 0 Then
Dim btn As LinkButton = sender.FindControl("editButton")
If btn.Visible = False Then
For Each ctrl As Control In testPlacehldr.Controls
If ctrl.GetType Is GetType(TextBox) Then
Dim box As TextBox = TryCast(ctrl, TextBox)
box.ReadOnly = False
End If
Next
End If
End If
End Sub
This works fine for what I need it to do. Credit to the user R.C. for the idea about placeholders

CustomValidator - validating against selected index with asp.net ServerValidateEventArgs

I have the following code which works fine if checking whether the selected value of a dropdownlist is greater than 0.
However, I need to check against the selected index of the dropdownlist rather than the value.
Sub selectValidation(source As Object, args As ServerValidateEventArgs)
Try
args.IsValid = args.Value > 0
Catch ex As Exception
args.IsValid = False
End Try
End Sub
Changing .Value to .SelectedIndex creates the following error:
BC30456: 'SelectedIndex' is not a member of 'System.Web.UI.WebControls.ServerValidateEventArgs'.
EDIT:
Here's the validator code...
<asp:DropDownList runat="server" ID="Adults" AutoPostBack="true" />
<asp:CustomValidator id="Req_Adults"
ControlToValidate="Adults"
ClientValidationFunction="selectValidation"
OnServerValidate="selectValidation"
runat="server"
CssClass="errorAsterisk"
Text="*"
ErrorMessage="Select number of adults" />
<asp:DropDownList runat="server" ID="Children" AutoPostBack="true" />
<asp:CustomValidator id="Req_Children"
ControlToValidate="Children"
ClientValidationFunction="selectValidation"
OnServerValidate="selectValidation"
runat="server"
CssClass="errorAsterisk"
Text="*"
ErrorMessage="Select number of children" />
Clientside validation (working fine):
function selectValidation(source, arguments)
{
var selectedValue = $(source).siblings("select").prop("selectedIndex");
if (selectedValue > 0 ){
arguments.IsValid = true;
} else {
arguments.IsValid = false;
}
}
If the DropDownList is directly accessible from the handler, this works:
Sub selectValidation(source As Object, args As ServerValidateEventArgs)
args.IsValid = Me.DropDownList1.SelectedIndex <> -1
End Sub
Otherwise you have to show us where it is. You canot get the reference from source or args.
A CustomValidator is the only validator which does not need to have a ControlToValidate. It can validate multiple controls, hence it wouldn't make sense to pass a control.
Update
I don't like this approach. However, if you really want to use the same handler you can assign a ValidationGroup to all relevant DropDownLists and use a query like this to find them:
Dim ddlNumZero = From ddl In Me.Controls.OfType(Of DropDownList)()
Where ddl.ValidationGroup = "NumberValidation" _
AndAlso ddl.SelectedIndex <= 0
args.IsValid = Not ddlNumZero.Any()

Regular expression for maximum digits excluding comma

I have the below regular expression:
ValidationExpression="[0-9]+(,[0-9]+)*"
It allows numbers in the format: 12,2345 or 231,23454
Now I want to include a condition that will on the whole allow only 7 digits max excluding
comma.
The below is the modified code
The below is in the item template
I also have a radio button in item template
<asp:TextBox runat="server" ID="tbText" CssClass="someclass" MaxLength="11"
%>'></asp:TextBox>
<asp:RegularExpressionValidator ValidationExpression="[0-9]+(,[0-9]+)*" ID="ValComp" runat="server" CssClass="asdf"
ControlToValidate="tbMileage" Text="*" Enabled="false" Display="Dynamic"/>
<asp:CustomValidator ID="cvalMileage" runat="server" CssClass="adsf" Text="*" Display="Dynamic">
</asp:CustomValidator>
<asp:CustomValidator ID="CustomValidator1" ClientValidationFunction="functionName"
runat="server" CssClass="asd" Text="*" Display="Dynamic">
</asp:CustomValidator>
Since I want to validate the radio button checked corresponding textbox in repeater the below is the code I have written
var selText = $(".Class1 input[type=radio]:checked").closest(".Class1").find(".subClassText input[type=text]").val();
alert('Hi');
if (selText.replace(",", "").length <= 7) {
args.IsValid = true;
}
else {
args.IsValid = false;
}
The alert fires twice and based on args is False i have a popup that is firing twice
Thanks.
Regular expressions are not good at this problem, but if you limit your input to a maximum of one comma this expression will fit:
([0-9]{0,0}[,]?[0-9]{0,7})|([0-9]{0,1}[,]?[0-9]{0,6})|([0-9]{0,2}[,]?[0-9]{0,5})|([0-9]{0,3}[,]?[0-9]{0,4})|([0-9]{0,4}[,]?[0-9]{0,3})|([0-9]{0,5}[,]?[0-9]{0,2})|([0-9]{0,6}[,]?[0-9]{0,1})|([0-9]{0,7}[,]?[0-9]{0,0})
You will recognize that this problem is not well suited for regular expression as this expression is fixed to your maximum of 7.
You could use a CustomValidator control with client-side validation like this:
ASPX code:
<asp:CustomValidator id="CustomValidator1" runat="server"
ControlToValidate="YourControlNameHere"
ClientValidationFunction="ClientValidation"
OnServerValidate="ServerValidation"
ErrorMessage="Invalid number." />
JavaScript (uses jQuery):
function ClientValidation(source, arguments)
{
var inputText = arguments.Value;
var expression = /^[0-9]+(,[0-9]+)*$/;
if (expression.test(inputText) && inputText.replace(",", "").length <= 7) {
arguments.IsValid = true;
}
else {
arguments.IsValid = false;
}
}
C# code behind:
public void ServerValidation(object source, ServerValidateEventArgs args)
{
string inputText = args.Value;
Regex regex = new Regex(#"^\d+(,\d+)*$");
if (regex.IsMatch(inputText) && inputText.Replace(",", "").Length <= 7)
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}

Do not fire custom validate on OnChange event of a textbox

I am using a custom validator to validate a textbox content.
Everytime the user leaves this textbox, my client script is called, which is, in my case, a little bit annoying.
I want the validation only to be performed when the user clicks on a button given button (which is already happening).
Is there any way to avoid the validation to be performed on the OnChange event of the TextBox?
My code is here:
function isGroupNameUnique(sender, args) {
var valid = true;
var tokens = $('#hdnGroupNames').val().split(',');
var groupName = $('#<%= txtGroupName.ClientID %>').val();
$.each(tokens, function (i) {
if (groupName == this)
valid = false;
});
args.IsValid = valid;
}
<asp:TextBox ID="txtGroupName" runat="server" />
<asp:Button ID="btnAddGroup" runat="server" Text = "Add" onclick="btnAddGroup_Click" class="bGraySmaller" ValidationGroup="AddGroup"/>
<asp:CustomValidator ID="validatorGroupNameAlreadyExists" runat="server" ControlToValidate="txtGroupName" ErrorMessage="The Group Name has to be unique" ValidationGroup="AddGroup" ClientValidationFunction="isGroupNameUnique" />
Remove the ControlToValidate property on the CustomValidator(what is the only Validator where this property is not mandatory). Set the same ValidationGroup on the TextBox.
<asp:TextBox ID="txtGroupName" ValidationGroup="AddGroup" runat="server" />
<asp:CustomValidator ID="validatorGroupNameAlreadyExists" runat="server" ErrorMessage="The Group Name has to be unique" ValidationGroup="AddGroup" ClientValidationFunction="isGroupNameUnique" />

How to validate a user chose at least one checkbox in a CheckBoxList?

I've got a CheckBoxList control that I want to require the user to check at least ONE box, it does not matter if they check every single one, or 3, or even just one.
In the spirit of asp.net's validation controls, what can I use to enforce this? I'm also using the Ajax validation extender, so it would be nice if it could look like other controls, and not some cheesy server validate method in the codebehind.
<asp:CheckBoxList RepeatDirection="Horizontal" RepeatLayout="Table" RepeatColumns="3" ID="ckBoxListReasons" runat="server">
<asp:ListItem Text="Preliminary Construction" Value="prelim_construction" />
<asp:ListItem Text="Final Construction" Value="final_construction" />
<asp:ListItem Text="Construction Alteration" Value="construction_alteration" />
<asp:ListItem Text="Remodel" Value="remodel" />
<asp:ListItem Text="Color" Value="color" />
<asp:ListItem Text="Brick" Value="brick" />
<asp:ListItem Text="Exterior Lighting" Value="exterior_lighting" />
<asp:ListItem Text="Deck/Patio/Flatwork" Value="deck_patio_flatwork" />
<asp:ListItem Text="Fence/Screening" Value="fence_screening" />
<asp:ListItem Text="Landscape - Front" Value="landscape_front" />
<asp:ListItem Text="Landscape - Side/Rear" Value="landscape_side_rear" />
<asp:ListItem Text="Other" Value="other" />
</asp:CheckBoxList>
It's easy to do this validation server side, but I am assuming you want to do it client side?
JQuery can do this very easily as long as you have something that all checkbox controls have in common to use as a selector such as class (CssClass on your .NET control). You can make a simple JQuery function and connect it to a ASP.NET custom validator. Remember if you do go the custom validator route to make sure you check it server side as well in case javascript is not working, you don't get a free server side check like the other .NET validators.
For more information on custom validators check out the following links: www.asp.net and
MSDN
You don't need to use JQuery, it just makes the javascript function to iterate and look at all your checkbox controls much easier but you can just use vanilla javascript if you like.
Here is an example I found at: Link to original
<asp:CheckBoxList ID="chkModuleList"runat="server" >
</asp:CheckBoxList>
<asp:CustomValidator runat="server" ID="cvmodulelist"
ClientValidationFunction="ValidateModuleList"
ErrorMessage="Please Select Atleast one Module" ></asp:CustomValidator>
// javascript to add to your aspx page
function ValidateModuleList(source, args)
{
var chkListModules= document.getElementById ('<%= chkModuleList.ClientID %>');
var chkListinputs = chkListModules.getElementsByTagName("input");
for (var i=0;i<chkListinputs .length;i++)
{
if (chkListinputs [i].checked)
{
args.IsValid = true;
return;
}
}
args.IsValid = false;
}
Side Note: JQuery is just a little js file include you need to add to your page. Once you have it included you can use all the JQuery you like. Nothing to install and it will be full supported in the next version of Visual Studio I think.
Here's a cleaner jQuery implementation that allows one ClientValidationFunction for any number of CheckBoxList controls on a page:
function ValidateCheckBoxList(sender, args) {
args.IsValid = false;
$("#" + sender.id).parent().find("table[id$="+sender.ControlId+"]").find(":checkbox").each(function () {
if ($(this).attr("checked")) {
args.IsValid = true;
return;
}
});
}
Here's the markup:
<asp:CheckBoxList runat="server"
Id="cblOptions"
DataTextField="Text"
DataValueField="Id" />
<xx:CustomValidator Display="Dynamic"
runat="server"
ID="cblOptionsValidator"
ControlId="cblOptions"
ClientValidationFunction="ValidateCheckBoxList"
ErrorMessage="One selection required." />
And finally, the custom validator that allows the client function to retrieve the target control by ID:
public class CustomValidator : System.Web.UI.WebControls.CustomValidator
{
public string ControlId { get; set; }
protected override void OnLoad(EventArgs e)
{
if (Enabled)
Page.ClientScript.RegisterExpandoAttribute(ClientID, "ControlId", ControlId);
base.OnLoad(e);
}
}
You can use a CustomValidator for that with a little bit of javascript.
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one"
ClientValidationFunction="checkCheckBoxList"></asp:CustomValidator>
<script type="text/javascript">
function checkCheckBoxList(oSrc, args) {
var isValid = false;
$("#<%= CheckBoxList1.ClientID %> input[type='checkbox']:checked").each(function (i, obj) {
isValid = true;
});
args.IsValid = isValid;
}
</script>
And for a RadioButtonList
<asp:CustomValidator ID="CustomValidator1" runat="server" ErrorMessage="Select at least one" ClientValidationFunction="checkRadioButtonList"></asp:CustomValidator>
<script type="text/javascript">
function checkRadioButtonList(oSrc, args) {
if ($("input[name='<%= RadioButtonList1.UniqueID %>']:checked").val() == null) {
args.IsValid = false;
} else {
args.IsValid = true;
}
}
</script>
Here is another solution that may be considered via Dado.Validators on GitHub.
<asp:CheckBoxList ID="cblCheckBoxList" runat="server">
<asp:ListItem Text="Check Box (empty)" Value="" />
<asp:ListItem Text="Check Box 1" Value="1" />
<asp:ListItem Text="Check Box 2" Value="2" />
<asp:ListItem Text="Check Box 3" Value="3" />
</asp:CheckBoxList>
<Dado:RequiredFieldValidator runat="server" ControlToValidate="cblCheckBoxList" ValidationGroup="vlgSubmit" />
Example codebehind.aspx.cs
btnSubmit.Click += (a, b) =>
{
Page.Validate("vlgSubmit");
if (Page.IsValid) {
// Validation Successful
}
};
https://www.nuget.org/packages/Dado.Validators/
Ref: Check if a checkbox is checked in a group of checkboxes in clientside
We can achieve this by C# also
bool Item_selected = false;
foreach (ListItem item in checkbox.Items)
{
if (item.Selected == true)
{
Item_selected = true;
}
}
if (!Item_selected )
{
//your message to user
// message = "Please select atleast one checkbox";
}
Loop through each of the items in ckBoxListReasons. Each item will be of type 'ListItem'.
The ListItem will have a property called 'Selected' that is a boolean. It's true when that item is selected. Something like:
Dim bolSelectionMade As Boolean = False
For Each item As ListItem in ckBoxListReasons.Items
If item.Selected = True Then
bolSelectionMade = True
End If
Next
bolSelectionMade will be set to true if the user has made at least one selection. You can then use that to set the Valid state of any particular validator control you like.

Resources