CustomValidator - validating against selected index with asp.net ServerValidateEventArgs - asp.net

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()

Related

How to require checkboxes be checked in vb.net

Can someone please help me figure out how to require more than one checkbox to be checked on my aspx page? I have found a few articles that show how to do this with JavaScript, but I use VB and I am not sure how to apply it.
What I would like to do is once the user clicks the submit button it will display an error if enough checkboxes have not been checked. These are not in a checkbox list but rather individual checkboxes.
You can use a CustomValidator for this purpose.
Within your ASPX page, you put it in your controls and the validator.
<asp:CheckBox ID="CheckBox1" runat="server" />
<asp:Label AssociatedControlID="CheckBox1" runat="server">Check this box!</asp:Label>
<asp:CheckBox ID="CheckBox2" runat="server" />
<asp:Label AssociatedControlID="CheckBox2" runat="server">And this box!</asp:Label>
<asp:CustomValidator ID="CustomValidator1" runat="server"
ErrorMessage="You must check all of the boxes"
OnServerValidate="CustomValidator1_ServerValidate">
</asp:CustomValidator>
After this, you can check they click Submit by checking the ServerValidate event.
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
args.IsValid = True ' set default
If Not CheckBox1.Checked Then
args.IsValid = False
End If
If Not CheckBox2.Checked Then
args.IsValid = False
End If
End Sub
The ServerValidateEventArgs will allow you to specify if the user has met your criteria.
At the end of ServerValidate event, it will return the value set in the property IsValid to determine if it's valid or not.

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

check if certain textboxes are empty

ok, I needed to check if only 4 out of 15 textboxes were empty, but with no luck. I tried:
if txtbox1.text = "" then
lblerror1.visible=true
exitsub
else
bla bla
end if
But that left error text and didn't see the user entering the text in the textbox, so I looked and found string.isnullorwhitespace(string.value)...
well, that didn't tell me how to use it so I searched more and found this:
if string.isnullorwhitespace(textbox.text) then..
well that was it and here is the outcome. now if I could only get a for-next or do -while to only chaeck the 4 text fileds I need to check and not all textboxes.
ASPX page code:
<asp:Label ID="lblerror" runat="server" Text="Page error" Visible="false" forecolor="red"/><br />
<asp:TextBox ID="txtName" runat="server" Width="100px" /><asp:Label ID="nameblankerror" runat='server' Text="cannot be blank" ForeColor="Red" Visible="false" /><br />
<asp:TextBox ID="txtcompname" runat="server" Width="100px" /><asp:Label ID="compblankerror" runat='server' Text="cannot be blank" ForeColor="Red" Visible="false" /><br />
<asp:Button ID="btnSubmit" runat="server" Text="submit" /><br />
<asp:Label ID="lbl1" runat="server" Visible="true" Text="TextBox 1: " /><asp:label ID="lblname" runat="server" /><br />
<asp:Label ID="lbl2" runat="server" Visible="true" Text="TextBox 2: " /><asp:label ID="lblCompName" runat="server" />
and for the backend code:
Protected Sub btnSubmit_Click(sender As Object, e As EventArgs) Handles btnSubmit.Click
'test to see if certain the fields are blank
Dim str1 As String = txtName.Text
Dim str2 As String = txtcompname.Text
Dim CatchMe As Integer = 0
If String.IsNullOrWhiteSpace(txtName.Text) Then
nameblankerror.Visible = True
CatchMe += 1
Else
nameblankerror.Visible = False
lblname.text = str1.Trim()
CatchMe += 0
End If
If String.IsNullOrWhiteSpace(txtcompname.Text) Then
compblankerror.Visible = True
CatchMe += 1
Else
compblankerror.Visible = False
lblCompName.Text = str2.Trim()
CatchMe += 0
End If
If CatchMe = 0 Then
'do something like process SQL Command
lblerror.Visible = False
Exit Sub
ElseIf CatchMe <> 0 Then
'return to page and process nothing
lblerror.Visible = True
Exit Sub
End If
End Sub
so that is it. a simple, easy to follow check for certain textboxes out of a bunch.
Like I stated above if I could figure out how to check only certain textboxes and not all textboxes, that and make the code shorter would be great. I put in a catchme so that if one box was filled in it wouldn't show the user that they need to fill that one also (in Error), but would catch the other empty textboxes.
to make it clear, if I have 15 textboxes, but only care that 4 of them are not empty, this is what I do for the check. I don't do this for every textbox as it is not needed
Add unique CssClass to all 4 TestBox.
Find the parent control which holds all 4 TextBox.
And then try the following code.
If you have applied validateempty as CssClass for TextBox and if Ctrl1 is the parent control which holds the textboxes then.
For Each ctrl as Control In Ctrl1.Controls
Dim txt as TextBox = TryCast(ctrl, TextBox)
If txt IsNot Nothing And txt.CssClass = "validateempty" And txt.Text.Trim() = "" Then
'Your choice of code hear.
End If
Next
Using JQuery you can find an element by its cssclass name.
First add the JQuery reference to your page You can find it hear.
Second add the following function to OnClientClick attribute of the submit button.
function validate(){
//Since you have added cssclass for the textboxes as "validateempty" then
var ret = true;
$.find(".validateempty").each(function(){
if(ret){
if($(this).val().trim() == ""){
alert("Enter the value.");
$(this).focus();
ret = false;
}
}
});
return ret;
}
$.find() will find all elements with the provided filter parameter. In this case css class. If there are more than one value is returned as there are 4 text boxes, then loop through the result and check individual found element which can be found in $(this) element. If you specify return directly inside the $.find(), then it will return from the loop not from function.
You can maintain an array of Id's you want to validate.
String[] txtboxToValidate = { "txtb1", "txtb2", "txtb4", "txtb8" };
foreach (Control c in Page.Controls)
{
if (c is TextBox)
{
int pos = Array.IndexOf(txtboxToValidate, c.ID);
TextBox txtBox = (TextBox)c;
if (pos > -1)
{
if (String.IsNullOrEmpty(txtBox.Text))
{
//Write your logic how you want to throw your error.
}
}
}
}
It's in c# but logic remains same. You can convert it to VB using online code converters etc.

Validate TextBox based on DropDownList selection

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;

Checkboxes in usercontrol won't check although they say they are

I have a simple usercontrol, with a datalist, and checkboxes inside.
<asp:DataList ID="DataListDroits" runat="server" DataKeyField="droit_id" DataSourceID="SqlDroits">
<ItemTemplate>
<asp:HiddenField ID="HiddenFieldDroitID" runat="server" Value='<%# Eval("droit_id") %>' />
<asp:CheckBox ID="CheckBoxDroit" runat="server" Text='<%# Eval("droit_label") %>' />
</ItemTemplate>
</asp:DataList>
I check them using code behind in the usercontrol :
Public Sub CheckRole(ByVal role As Integer)
For Each dliOrganisme As DataListItem In Me.DataListOrganismes.Items
Dim DataListDroits As DataList = dliOrganisme.FindControl("DataListDroits")
If DataListDroits IsNot Nothing Then
For Each dliDroit As DataListItem In DataListDroits.Items
If role = CInt(CType(dliDroit.FindControl("HiddenFieldDroitID"), HiddenField).Value) Then
Dim CheckBoxDroit As CheckBox = dliDroit.FindControl("CheckBoxDroit")
CheckBoxDroit.Checked = True
End If
Next ' DataListDroits
End If
Next ' DataListItem
End Sub
And in the page_load of the calling webform :
Dim CheckBoxesRoles1 As ASP.organisme_checkboxesroles_ascx = Me.FormViewRubrique.FindControl("CheckBoxesRoles1")
Dim rolesCoches As New List(Of Integer)
Dim cmdRoles As New SqlCommand("SELECT droit_id FROM o_droit_rubrique WHERE rubrique_id = #rubrique", conn)
cmdRoles.Parameters.AddWithValue("rubrique", Request.QueryString("rid"))
Dim rdrRoles As SqlDataReader = cmdRoles.ExecuteReader
While rdrRoles.Read
CheckBoxesRoles1.CheckRole(rdrRoles("droit_id"))
End While
rdrRoles.Close()
... and yet, they are not checked.
But if I do this :
Protected Sub Page_LoadComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LoadComplete
Dim CheckBoxesRoles1 As ASP.organisme_checkboxesroles_ascx = Me.FormViewRubrique.FindControl("CheckBoxesRoles1")
If CheckBoxesRoles1 IsNot Nothing Then
For Each role As Integer In CheckBoxesRoles1.CheckedRoles
Response.Write("role : " & role & "<br>")
Next
End If
End Sub
I tells me they are...
I'm going mad here ! Why does it tells me they are checked while they obviously are not ?
Well... for one thing, you aren't checking if your checkboxes are checked, all you're doing is outputting the value of "role". What exactly are you expecting here?
Two suggestions:
1) Set the Checked property of your CheckBox in the aspx like so:
<asp:CheckBox ID="CheckBoxDroit" runat="server" Text='<%# Eval("droit_label") %>' Checked='<%# (Eval("droit_id") > 0).ToString()' />
2) Set the property in OnItemDataBound in code-behind
One of two things is happening: Either the code you expect to be executing is not really executing (ie, is your if block ever true? Is the control not being found? Try a breakpoint), OR you are doing it at the wrong time -- after the page has already been rendered.

Resources