Friday, May 15, 2009

Custom Validators: How to have Custom Validation and Required Field Validation

JavaScript functions will show the error message always in the same label, that will be placed somewhere in the screen, as the user wants and not in the custom validator place.

JavaScript Functions to be called from a DataGrid or RadGrid
function ClientValidateIni(source, arguments) {
if (arguments.Value.length == 0) {
arguments.IsValid = false;
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'I';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('I', '');
displayMessage(arguments)
}
}
function ClientValidateWeight(source, arguments) {
if ((arguments.Value.length == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else {
if ((parseInt(arguments.Value) == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else
{ arguments.IsValid = IsNumeric(arguments.Value); }
}
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'W';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('W', '');
displayMessage(arguments)
}
}
function ClientValidateQty(source, arguments) {
if ((arguments.Value.length == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else {
if ((parseInt(arguments.Value) == 0) && (document.getElementById("ctl00_ContentPlaceHolder1_txtUsine").value == '600')) {
arguments.IsValid = false;
}
else
{ arguments.IsValid = IsNumeric(arguments.Value); }
}
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'Q';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('Q', '');
displayMessage(arguments)
}
}

function ClientValidateTemp(source, arguments) {
arguments.IsValid = IsNumeric(arguments.Value);
if (arguments.IsValid == false) {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value += 'T';
displayMessage(arguments)
}
else {
document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value = document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.replace('T', '');
displayMessage(arguments)
}
}
function IsNumeric(input) {
var RE = /^-{0,1}\d*\.{0,1}\d+$/;
return (RE.test(input));
}
function displayMessage(arguments) {
document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = '';
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('I') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtInitial").value + '
'; }
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('W') >= 0) {
document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtWeight").value + '
';
}
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('Q') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtQty").value + '
'; }
if (document.getElementById("ctl00_ContentPlaceHolder1_txtValidation").value.indexOf('T') >= 0)
{ document.getElementById("ctl00_ContentPlaceHolder1_lblErrorGrid1").innerHTML = document.getElementById("ctl00_ContentPlaceHolder1_cvtTemp").value + '
'; }
}


ASPX - HTML portion code


The output message label:



The Custom Validator and the ControltoValidate (portion of a Grid)


' MaxLength="5">
ClientValidationFunction="ClientValidateTemp"
ControlToValidate="txtTemp" ValidateEmptyText="True" SetFocusOnError="True"
CssClass="error2" Display="Dynamic" ErrorMessage="*">



The hidden controls needed for the example:











Master Page - Comunication between Contents - VB

Example:

MasterPage.aspx


#Region "Public Delegates"

' Expose delegates for Master Page Events
Public Delegate Sub MasterPageMenuClickHandler(ByVal sender As Object, ByVal e As System.EventArgs)

#End Region

#Region "Public Properties"

Private _currentButton As String

Public Property CurrentButton() As String
Get
Return _currentButton
End Get
Set(ByVal value As String)
_currentButton = value
End Set
End Property
#End Region

#Region "Public Events"
Public Event MenuButton As MasterPageMenuClickHandler
#End Region

#Region "Page Events"
Protected Sub cboLang_Click(ByVal sender As Object, ByVal e As System.EventArgs)
_currentButton = cboLang.SelectedValue

Select Case cboLang.SelectedValue
Case "fr"
Call DLLLallemand.WriteCookies(strGlobalUser, "fr", strAppName)
Case Else
Call DLLLallemand.WriteCookies(strGlobalUser, "en", strAppName)
End Select

OnMenuButton(e)
End Sub
#End Region


#Region "Virtual Methods"
Protected Sub OnMenuButton(ByVal e As EventArgs)
'Invokes the delegates
RaiseEvent MenuButton(Me, e)
End Sub
#End Region



ContentPage.aspx

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
AddHandler Master.MenuButton, New Master_Synergy1.MasterPageMenuClickHandler
(AddressOf Master_MenuButton)

Catch ex As Exception

Finally
End Try
End Sub



Public Sub Master_MenuButton(ByVal sender As Object, ByVal e As System.EventArgs)
strLang = Master.CurrentButton.ToString()
Call MultiLanguage(strLang)
wdgInactiveYeast.Rebind()
End Sub



Reference
http://blogs.claritycon.com/blogs/steve_holstad/archive/2006/03/04/266.aspx

AJAX - Panel

There is no doubt that the easiest way to implement AJAX in a Web Page is by using UpdatePanel, but is this way efficient? If you have a simple page, then you can use UpdatePanel and maybe you will have no issue on ussing that - DO NOT say it is fine to use it, I just said you will find no javascript error; However, nowadays most of us use MasterPages to build complete applications and there you will find issues. Let's see an example:

MasterPage.aspx

<asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
</asp:ContentPlaceHolder>

<asp:ContentPlaceHolder ID="ContentPlaceHolder2" runat="server">
</asp:ContentPlaceHolder>




This master page has two ContentPlaceHolder, so the Page that will use it will have two Contents too.




Default.aspx


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">



</asp:Content>



<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">

</asp:Content>








Now, if we try to put one Panel Control for both Content, we realize almost inmediately that we are not allowed to do so. No other alternative, just put a PanelControl in the first Content, now our code will look like this:


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">


            <ContentTemplate>



            </ContentTemplate>

           </asp:UpdatePanel>                 
</asp:Content>








Everything works fine except that you have no control on the other content controls, so we add a new Panel for the the second Content.


<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">

            <asp:UpdatePanel ID="UpdatePanel1" runat="server">


            <ContentTemplate>



            </ContentTemplate>

           </asp:UpdatePanel>                 
</asp:Content>




<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="Server">



    <asp:UpdatePanel ID="UpdatePanel2" runat="server">



    <ContentTemplate>

    <asp:Button ID="cmdQuit" runat="server" OnClick="cmdQuit_Click"


        Style="position: static; height: 28px;" Text="Quit" UseSubmitBehavior="True"


        Width="100px" />

             </ContentTemplate>


           </asp:UpdatePanel>                 


</asp:Content>







Now, you have control on the other content's controls. That was pretty easy!, However, Imagine you have a Quit button in the second content, and it needs to do a redirect to another page in order to quit the option, but not the application. Sooner you will realize that;

Response.redirect doesn't work now, there is a JavaScript issue, so our Response.redirect which is in the server side never gets executed. That has also a solution. You just need to add this into your config.web page.



<httpModules>

  <add type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" name="ScriptModule" />


</httpModules>




Now it works. However, there is something that cannot convince me at the end. The reason is here: http://encosia.com/2007/07/11/why-aspnet-ajax-updatepanels-are-dangerous/
and I pretty agree with this, so now I will be working on find a more efficient way of doing the same.