Sunday 29 January 2012

Hide/Show validator callout control using javascript

Hide/Show validator callout control using javascript

In my previous blog we saw how to call validation controls from javascripts. This blog we will see how to show and hide a ASP.NET AJAX’ (AJAXControlToolkit) ValidatorCalloutExtender control using javascript. Below is an aspx page with a validator callout control.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="AJAXControls" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <!--ASP.NET Drop down control-->
        <asp:DropDownList ID="status" runat="server" >
            <asp:ListItem Selected="True" Text="Select" Value="0" />
            <asp:ListItem Text="One" />
            <asp:ListItem Text="Two" />
            <asp:ListItem Text="Three" />
        </asp:DropDownList>
        <!--ASP.NET Required Field Validator to validate the drop down.-->
        <asp:RequiredFieldValidator ID="statusValidator" runat="server" ErrorMessage="Please choose a value other than 'Select'"
            ControlToValidate="status" InitialValue="0" Visible="true">
        </asp:RequiredFieldValidator>
    <!--Validator callout control-->
        <AJAXControls:ValidatorCalloutExtender ID="statusValidator_ValidatorCalloutExtender"
            runat="server" TargetControlID="statusValidator">
        </AJAXControls:ValidatorCalloutExtender>
        <asp:Button ID="submit" Text="Submit" OnClientClick="javascript:return ValidatePage();"
            runat="server" />
    </div>
    <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    </form>
</body>
</html>
The above code has a dropdown control with an ASP.NET required field validator control and a validator callout control attached to it. As soon as you click the submit button and if there is a validation error the error will be popped out in the validator callout control as shown below.
Error in Validator callout control
Popping of the error message in a validator callout control happens automatically. But there may be scenario where you would like to hide or show the validator control using javascript. The below sample code does exactly that.
<script language="javascript" type="text/javascript">
function ValidatePage()
{        
    //Function which calls the whole validation for the page.
    if (Page_ClientValidate())       
    {
        return true;
    }
    else
    {       
        hideValidatorCallout();
        return false;
    }
}
//User defined method which hides the AjaxControlToolkit ValidatorCalloutExtender control
function hideValidatorCallout()
{
    //Below code hides the active AjaxControlToolkit ValidatorCalloutExtender control.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
    setTimeout(showValidatorCallout, 3000);   
}
function showValidatorCallout()
{
    //Gets the AjaxControlToolkit ValidatorCalloutExtender control using the $find method.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout = $find('<% =statusValidator_ValidatorCalloutExtender.ClientID %>');
    //Below code unhides the AjaxControlToolkit ValidatorCalloutExtender control.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.show(true);
}
</script>
From the above code we can see that there is a code something like this “AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout”. The _currentCallout property will hold the current validator callout control. Whenever there is a validation failure and if there is validator callout control associated with validator control, the _currentCallout property will be assigned the validator callout control. To hide the validator callout control you need to use the “hide”  javascript function along with the _currentCallout property as shown below.
AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
At any given point the _currentCallout property will have only one validator callout assigned, this is to avoid the confusion or dirtiness which can arise by showing all the validator callout control. If all the validator callouts are shown when multiple validation fails then the screen will be cluttered with all the validator callouts popping here and there. To avoid this cluttered view this approach of showing only one validator callout control has been taken.
Similarly to show the validator callout control you can use the “show” javascript method along with _currentCallout property as shown below.
//Gets the AjaxControlToolkit ValidatorCalloutExtender control using the $find method.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout = $find('<% =statusValidator_ValidatorCalloutExtender.ClientID %>');
    //Below code unhides the AjaxControlToolkit ValidatorCalloutExtender control.
    AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.show(true);
But the above code if used just like that can throw the following error.
Microsoft JScript runtime error: 'this._popupBehavior' is null or not an object
The reason why this happens is that we have not called either ValidatorEnable or ValidatorValidate javascript functions. These two functions set the necessary things, like _popupBehavior property, for the validator control to work properly. Validator callout controls are not meant to be shown directly they are actually extender controls which extend the functionality of the validation control and these controls are shown automatically when a validator control’ validation condition fails. So if you want to show a validator callout function just call ValidatorEnable or ValidatorValidate javascript function.
That’ about it, on how to hide and show validator callout controls using javascript. I know I have not mentioned anything about “$find” javascript function. We will have a discussion on this in my subsequent blog. For the time being just understand it as a shortcut method to find a component. In our next blog we will see how to set focus to a particular tab in the AjaxControlToolkit’ tab container control.
Some important methods of ValidatorCallout controls
Methods/Properties Description
_getErrorMessage() Gets/returns the error message
get_closeImageUrl() Gets/returns the close image url at the top rightmost corner of the validator callout control. Default is an x mark.
get_isOpen() Gets/returns a boolean value indicating whether the validator callout is opened or not.
get_warningIconImageUrl() Gets/returns the warning icon image’ url. Default is an exclamation mark inside a triangle.
get_width() Gets/returns the width of the validator callout control.
hide() Function to hide the validator callout control.
set_closeImageUrl(imageUrl) Function to set the close image url. One can use this method to change the default X mark.
set_warningIconImageUrl(imageUrl) Function to set the warning image. One can use this function to change the default exclamation image used for warning.
set_width(int) Function used to set the width of the validator callout control.
show() To show the validator callout control.
_closeImageUrl Property to get/set the close image.
_warningIconImageUrl Property to get/set the warning image.
_width Property to get/set the width of the validator callout control
_popupBehavior Property using which one can work with the pop up behaviour of the validator callout control.
_errorMessageCell Property using which one can modify the error message.
Some methods of ValidatorCallout._popupBehavior property
Below are listed few of the _methods of _popupBehavior property of validator callout function. These methods are available with only _popupBehavior property. If one wants use these methods then one has retrieve the _popupBehavior property from  validator callout control by any of the following two means shown below.
//Retrieving the validator callout control using the $find helper method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Get the _popupBehavior property in a variant object and then
//use the required methods.
var popUpBehavior = valCallout._popupBehavior;
popUpBehavior.set_x(10);
popUpBehavior.set_y(20);
//Directly use the methods along with the _popupBehavior property as shown below.
valCallout._popupBehavior.set_x(20);
valCallout._popupBehavior.set_y(30);
After retrieving the _popupBehavior property by any of the above means you can use the following methods.
Methods/Properties Description
get_x() Method to get the X coordinates of the validator callout control
get_y() Method to get the Y coordinates of the validator callout control.
get_visible() Methods that returns a boolean value specifying whether the validator callout control is visible or not.
set_x(x_coordinate) Method to set the X coordinate for the validator callout control. Method takes an integer value as an argument.
set_y(y_coordinate) Method to set the Y coordinate for the validator callout control. Method takes an integer value as an argument.
Some methods of ValidatorCallout._errorMessageCell property
Since _errorMessageCell returns a TD (cell) object there is nothing much new it has all the methods/properties corresponding to a cell object. One use of this property is to change the error message of the validator callout extendor control using javascript. To change the error message using javascript see the code below.
//Retrieving the validator callout control using the $find helper method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Get the error message cell.
var messageCell = valCallout._errorMessageCell;
//Changing the error message.
messageCell.innerHTML = "Changed:)";
Mail from my blog reader
Recently one of my blog reader mailed me across some problems he was facing with validator callout control. For the benefit of the readers I am pasting the mail chain discussion here, with prior permission from the reader who mailed me.
Hey Sandeep, how are you?
I've read your amazing article on:
http://sandblogaspnet.blogspot.com/2009/04/
setting-focus-to-particular-tab-in.html
thank you very much, it really help me!
So, I want to call all validators, and them call the specific callout,
since we can access  Page_Validators[validatorIndex]...
I could execute all the validators, but now I need to know the name of
validator to call the callout.
var validator = Page_Validators[validatorIndex];
do you know how to get the id of the validator?
validator.Id ? validator.ClientId ?
thank you !
this is my solution for now:
<script language="javascript" type="text/javascript">
    var Page_Callout = new Array("<%
=statusValidator_ValidatorCalloutExtender.ClientID %>");
    function ValidatePage() {
        if (typeof (Page_Validators) == "undefined") return;
        var noOfValidators = Page_Validators.length;
        for (var validatorIndex = 0; validatorIndex < noOfValidators;
validatorIndex++)
        {
            var validator = Page_Validators[validatorIndex];
            ValidatorValidate(validator);
            if (!validator.isvalid) {
                var tabPanel = validator.parentElement.control;
                var tabContainer = tabPanel.get_owner();
                tabContainer.set_activeTabIndex(tabPanel.get_tabIndex());
                showValidatorCallout($find(Page_Callout[validatorIndex]));
                return false;
            }
            return true;
        }
    }
    function hideValidatorCallout() {
        AjaxControlToolkit.ValidatorCalloutBehavior._currentCallout.hide();
    }
    function showValidatorCallout(currrentCallout) {
        AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout =currrentCallout;
        AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout.show(true);
    }
</script>
-- My reply--
Hi XYZ,
If I am not wrong when you are calling the function "showValidatorCallout" it doesn't show the validator callout in the tab? Am I right? If yes I have also faced the same problem. I solved this by a dirty hack. So what I did is something like this.
ValidatorEnable(dropDownValidator); //Calling the validator callout for the first time. Just a dummy call.
if (!dropDownValidator.isvalid)
{
     setActiveTabIndex(0); //Method which sets the active index.
     hideCurrCallout(); //Method which hide the current validator callout
     ValidatorEnable(dropDownValidator); //Calling ValidatorEnable method for the second time.
}
Hope this helps. So when you work with tab you have to use the above hack to display validator callout control. I didn't get much time to find out the reason behind but will try find out.
--Response from the reader--
Hey Sandeep, thanks...
I've another problem with the callout's... Please, take a loot in that
image attached.. do you have this problem ?
When the field is in the right side... the callout create scrolls and
expand the width of the page :(
Do you know how to avoid this ?
--My reply-- Hope your previous problem has been solved. This is the auto behaviour of the browser where if something is dynamically created and it exceeds the width of the browser it will give you a scroll bar. For this you can set the X and Y coordinates of the callout control so that they won't exceed the width of the browser. To set the X and Y coordinates you can use the following code.
//Retrieving the validator callout control using the $find shortcut method.
var valCallout = $find('<%=statusValidator_ValidatorCalloutExtender.ClientID %>');
//Setting the X coordinates
valCallout.validatorCallout._popupBehavior.set_x(xCordinates);
//Setting the X coordinates
valCallout.validatorCallout._popupBehavior.set_y(yCordinates)
or you can use the below code.
AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout._popupBehavior.set_x(xCordinates);
AjaxControlToolkit.ValidatorCalloutBehavior.
_currentCallout._popupBehavior.set_y(yCordinates)
Hope this solves your problem.
--Reader response--
Hi Sandeep,
Yeah... you solve the problems :)
thank you again.
cheers,

No comments:

Post a Comment