CustomValidator

M

Morris Neuman

Hi,

I have a GridView1 which contains several fields including 2 template fields
where one edit template contains TextBox3 and the other contains
DropDownList1 with a CustomValidator. They are defined as follows:
<asp:TemplateField HeaderText="Notification Type"
SortExpression="TypeDescription">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID='<%$ AppSettings:MyDataSource2 %>'
DataTextField="TypeDescription"
DataValueField="TypeNumber" SelectedValue='<%# Bind("Type") %>'>
</asp:DropDownList>
<asp:CustomValidator ID="CustomValidator1" runat="server"
ControlToValidate="DropDownList1"
ErrorMessage="CustomValidator"
OnServerValidate =
"CustomValidator1_ServerValidate"></asp:CustomValidator>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%#
Bind("TypeDescription") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>

<asp:TemplateField HeaderText="Record Number"
SortExpression="RecordNumber">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%#
Bind("RecordNumber") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox3" runat="server" Text='<%#
Bind("RecordNumber") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>

In the CustomValidator function I want to check that if DropDowList1 has
value of "6" then the TextBox3.text must equal "0" and visa versa, i.e. If
TextBox3 = 0 then DropDownList1 must be set to "6" (Message Light). I tried
the following in the CustomValidator1_ServerValidate script but get null
exception error on TextBox3, though the field is set to 0.

protected void CustomValidator1_ServerValidate(object source,
ServerValidateEventArgs args)
{
GridView gv1 = GridView1 as GridView;
TextBox tb3 = gv1.FindControl("TextBox3") as TextBox;
string tb3Text = tb3.Text as string;
string ddl1Value = args.Value;
if (ddl1Value == "6")
{
if (tb3.Text == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}

if (tb3.Text == "0")
{
if (ddl1Value == "6")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}


Can you please tell me what I am doing wrong?
 
A

Allen Chen [MSFT]

Hi Morris,

This exception is caused by this line:
TextBox tb3 = gv1.FindControl("TextBox3") as TextBox;

To find a control in GridView we need to get the GridViewRow first. Then
use GridViewRow.FindControl to find the specific control on the row. For
example, if you replace the above code with:

TextBox tb3 = gv1.Rows[gv1. EditIndex].FindControl("TextBox3") as TextBox;

I think it should work.

Regards,
Allen Chen
Microsoft Online Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subscriptions/aa948868.aspx#notifications.

Note: MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 2 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions. Issues of this
nature are best handled working with a dedicated Microsoft Support Engineer
by contacting Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/en-us/subscriptions/aa948874.aspx
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
M

Morris Neuman

That worked. Thanks.

However in debug mode, I see the code goind thru the custom validator script
(CustomValidator1_ServerValidate) 2 times. Why?
 
M

Morris Neuman

Thanks for the explanation. I got the server side validation working but am
having a problem with the client side customvalidator. I have the following
for the GridView1 Edit Template DropDownList:

<asp:TemplateField HeaderText="Notification Type"
SortExpression="TypeDescription">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server"
DataSourceID='<%$ AppSettings:MyDataSource2 %>'
DataTextField="TypeDescription"
DataValueField="TypeNumber" SelectedValue='<%# Bind("Type") %>'>
</asp:DropDownList>
<asp:CustomValidator ID="CustomValidator1" runat="server"
ControlToValidate="DropDownList1"
ErrorMessage="CustomValidator"
OnServerValidate = "CustomValidator1_ServerValidate"
ClientValidationFunction="NotfType_RecNo"
Display="Dynamic"></asp:CustomValidator>


I am trying to recreate the logic below for client side validation:

protected void CustomValidator1_ServerValidate(object source,
ServerValidateEventArgs args)
{
GridView gv1 = GridView1 as GridView;
TextBox tb3 = gv1.Rows[gv1.EditIndex].FindControl("TextBox3") as
TextBox;
CustomValidator cv1 =
gv1.Rows[gv1.EditIndex].FindControl("CustomValidator1") as CustomValidator;
string tb3Text = tb3.Text as string;
string ddl1Value = args.Value;
if (ddl1Value == "6")
{
if (tb3.Text == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
cv1.ErrorMessage = "Record Number MUST be zero if
Notification Type set to Message Light";
}
}
}

I created a jscript function but am having problems referencing the value in
TextBox3.
My script has:

<script type="text/javascript">

function NotfType_RecNo(sender, args)
{
var tb3Value =
document.getElementById("<%=TextBox3.ClientID%>").value;
var ddl1Value = args.Value;

if (ddl1Value == "6")
{
if (tb3Value == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
//cv1.ErrorMessage = "Record Number MUST be zero if
Notification Type set to Message Light";
}
}
}
</script>


I have tried all day to find some type of similar example but just found
simple validations and none trying to validate values inn 2 seperate fields.
 
A

Allen Chen [MSFT]

Hi Morris,

Thanks for the update. I think you can try following steps to solve this
problem:

1. Add the PreRender event handler for TextBox3:
<asp:TextBox onprerender="TextBox3_PreRender" ID="TextBox3" …
protected void TextBox3_PreRender(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
this.hidden1.Value = tb.ClientID;
}

2. Add following code above the <asp:GridView>
<input type="hidden" runat="server" id="hidden1" />
<script type="text/javascript">
function NotfType_RecNo(sender, args) {
var clientid = document.getElementById("hidden1").value;
var tb3 = document.getElementById(clientid);
var tb3Value = tb3.value;
var ddl1Value = args.Value;

if (ddl1Value == "6")
{
if (tb3Value == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;

}
}

}
</script>

Regards,
Allen Chen
Microsoft Online Support
 
M

Morris Neuman

Hi Allen,

Tried as suggested. However I get error during the update process. When I
enter Edit it works, when I select Update I get this error.
error "Microsoft JScript runtime error: Object required"
on line "var clientid = document.getElementById("hidden1").value"

I tried using the gridview1_itemUpdating script similar to the
textbox3_prerender but the update goes directly to the jscript.

What am I doing wrong?

How is validation done normally, custom validating the values between 2 or
more fields? This client side validation seems quite complex for 1 field, I
cannot imaging maintaining for additional fields. Is this complicated as I
have each field in its own template in a gridview? Is a better design to
keep all fields as a single template field (I loose the sorting or would then
have to do some manual work around).

I thought field validations would be so simple. Your help and advice are
much appreciated.

I emailed you the page code.
 
A

Allen Chen [MSFT]

Hi Morris,

Thanks for the update. I think it's still the ClientID issue. You can try
<%=hidden1.ClientID %> to get the ClientID of the hidden input:

function NotfType_RecNo(sender, args) {
var clientid = document.getElementById('<%=hidden1.ClientID
%>').value;

.....

Quote from Morris ==================================================
How is validation done normally, custom validating the values between 2 or
more fields? This client side validation seems quite complex for 1 field,
I
cannot imaging maintaining for additional fields. Is this complicated as I
have each field in its own template in a gridview? Is a better design to
keep all fields as a single template field (I loose the sorting or would
then
have to do some manual work around).

I thought field validations would be so simple. Your help and advice are
much appreciated.
==================================================

We need to write additional code when using CustomValidator, especially
when it's placed in the GridView and we need client validation. Your design
is good that to keep each field in its own template. You don't have to
change it.

In general we have two options to do the client side validation for
CustomValidator in GridView.

" Store the client id of the control in a hidden input, as I suggested.
Then get it in the ClientValidationFunction to do the client side
validation.

" Navigate in the DOM to find the element. It's even more complicated and
hard to maintain comparing to the above option.

Validation would be simple if you use other validation controls such as
RequiredFieldValidator. However, as the name indicates the CustomValidator
control provides more flexibility but requires us to write more code.

Regards,
Allen Chen
Microsoft Online Support
 
M

Morris Neuman

Hi Allen,

Thanks. That worked. And for responses to my questions.

One more question:
How do I display a custom error message in the client validation? On the
server side I have the following that works.

protected void CustomValidator1_ServerValidate(object source,
ServerValidateEventArgs args)
{
GridView gv1 = GridView1 as GridView;
TextBox tb3 = gv1.Rows[gv1.EditIndex].FindControl("TextBox3") as
TextBox;
CustomValidator cv1 =
gv1.Rows[gv1.EditIndex].FindControl("CustomValidator1") as CustomValidator;
string tb3Text = tb3.Text as string;
string ddl1Value = args.Value;
if (ddl1Value == "6")
{
if (tb3.Text == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
cv1.ErrorMessage = "Record Number MUST be zero if
Notification Type set to Message Light";
}
}

if (tb3.Text == "0")
{
if (ddl1Value == "6")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
cv1.ErrorMessage = "Notification Type MUST be set to Message
Light if Record Number is zero";
}

}
}


My client script is now:

<script type="text/javascript">
function NotfType_RecNo(sender, args)
{
var clientid = document.getElementById('<%=hidden1.ClientID
%>').value;
var tb3 = document.getElementById(clientid);
var tb3Value = tb3.value;
var ddl1Value = args.Value;

if (ddl1Value == "6")
{
if (tb3Value == "0")
{
args.IsValid = true;
}
else
{
args.IsValid = false;
}
}
}
</script>
 
A

Allen Chen [MSFT]

Hi Morris,

If you want to show the error message in the <span> that is generated by
the CustomValidator control you can try the same way suggested in my
previous post to get the element:

1. Add another hidden input to store the ClientID of the CustomValidator:
<input type="hidden" runat="server" id="hidden2" />

2. Store the ClientID:
aspx.cs:

protected void CustomValidator1_PreRender(object sender, EventArgs e)
{
CustomValidator cv = (CustomValidator)sender;
this.hidden2.Value = cv.ClientID;

}

aspx:

<asp:CustomValidator onprerender="CustomValidator1_PreRender" ...

3. Test script:
<script type="text/javascript">

function NotfType_RecNo(sender, args)
{
var clientid = document.getElementById('<%=hidden1.ClientID
%>').value;
var validatorspanid =
document.getElementById('<%=hidden2.ClientID %>').value;

var tb3 = document.getElementById(clientid);
var v = document.getElementById(validatorspanid);
var tb3Value = tb3.value;
var ddl1Value = args.Value;

if (ddl1Value == "6") {
if (tb3Value == "0") {
args.IsValid = true;
}
else {
args.IsValid = false;
v.innerHTML = "Erro 1";
}
}
//test
else if (ddl1Value == "1") {
args.IsValid = false;
v.innerHTML = "Erro 2";
}

}

</script>

Regards,
Allen Chen
Microsoft Online Support
 
A

Allen Chen [MSFT]

Hi Morris,

Can my code work?


Regards,
Allen Chen
Microsoft Online Community Support
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top