views:

25

answers:

1

I am using ValidatorCalloutExtender for different asp controls in 3 different accordian-panes of the accordian. When i get error and i click the other accordian-pane header the error message is showing up on left top corner of the browser. How to hide or fade out this error message?

A: 

I presume you've figured this out by now (4 months?). But I saw this as a fun challenge and I've dealt with validators before.

The solution is to hook into the SelectedIndexChanged event for the accordion control and disable all the validators for the hidden panes.

First, we have to add a hook to the accordion control. This uses jQuery (I don't know of any other way to accomplish this). The variable contains the Client ID of the accordian function.

    var accordianId = 'MyAccordion';
    function pageLoad()  
    {  
        var accCtrl = $find(accordianId + '_AccordionExtender');
        accCtrl.add_selectedIndexChanged(onAccordionPaneChanged);    
    }

This is all client side, of course (javascript).

After that, we need to create the onAccordionPaneChanged method to loop through all the DIVs in the accordian pane and disable all the validators associated with the hidden DIVs (and enable all the validators for the newly opened DIV):

    function onAccordionPaneChanged(sender, eventArgs)  
    {  
       var indexSelectedPane = sender.get_SelectedIndex();
       //   There are two divs per "pane":  1 Header, 1 Content
       //   That would make the DIV odd, but there's an additional
       //   hidden element at the front, so it's the Even item.
       var indexContentDiv = (indexSelectedPane * 2) + 2;
       var accordianControl = document.getElementById(accordianId);
       var i, boolEnable;

       for(i = 0; i < accordianControl.children.length; i++)
       {
            //Odd number, this must be a Content section
            boolEnable = false;
            if (i == indexContentDiv)
            {
                boolEnable = true;
            }
            EnableDisableValidators(accordianControl.children[i], boolEnable);
       }
   }

Note that in the above, it mentions the two DIVs per pane. What happens is that the accordian control creates two DIVs per pane: one for the header and then one for the footer. If you loop through all the children, every other DIV is the one that contains the Content. So, to disable all the validators in only the content sections, above I checked (i%2 == 1) which says this is an "odd" div which are the content divs.

Finally, the EnableDisableValidators function takes the given DIV and checks all the Page's validators to see if they are controls within this DIV. If they are inside this DIV, it will either enable or disable the validator, based on the passed in value (which is determined by whether this DIV is the one that was selected).

Unfortunately, the DIVs that are generated by the Accordion control don't have an ID, so you have to search through all the controls within the div specifically

   function EnableDisableValidators(divParent, setEnabled)
   {
        var childValidator;
        var j;
        var k;

        if (divParent.children == null || divParent.children.length == 0)
        {
            return;
        }
        //  Check all the validators to see if they're one of the children
        for (j = 0; j < Page_Validators.length; j++)
        {
            // Check all the children of the DIV for the given validator
            for (k = 0; k < divParent.children.length; k++)
            {
                if (FindControlRecursive(divParent, Page_Validators[j].id) != null)
                {
                    ValidatorEnable(Page_Validators[j], setEnabled);
                }
            }
        }
   }

Another downfall is that we have to find all the children within the DIV and to do that we have to use recursion. So, here's a "simple" function for that (called above):

   function FindControlRecursive(parentNode, childID)
   {
        var l;
        var retChild;

        for (l = 0; l < parentNode.children.length; l++)
        {
            if(parentNode.children[l].id != null && 
                parentNode.children[l].id == childID)
            {
                return parentNode.children[l];
            }
            else
            {
                retChild = FindControlRecursive(parentNode.children[l], childID);
                if (retChild != null)
                {
                    return retChild;
                }
            }
        }
        return null;
   }

There's a few problems with this approach. First, when you submit the form, only the validators that are visible in the current pane will post an error. All the hidden validators won't be shown. To resolve this, you could add a function "onclick" of the submit button that would loop through all the Page_Validators and enable them all before you submitted. You may (at that point) also have to check the validators. But that's an entirely different question. ;)

Another problem is that the extenders seem to show themselves when you click on the control that they are attached to. You could use this same functionality to call the validators functionality when they are enabled to show which fields are required. (Just a possible solution.) But again, that's a whole separate question!

Hopefully that helps.

Richard

related questions