Search code examples
jqueryasp.netupdatepanelinitobject-literal

Elements keeping original values in jQuery objects after PostBack


I am using ASP.NET 3.5 combined with the atrocious UpdatePanel, jQuery.delegate(), and JavaScript object literals.

I use jQuery.delegate() to persist the event handlers, which do get triggered after the PostBack, as expected.

The issue is with the jQuery objects stored in object literal properties on init() where they keep the values they had prior to the ASP.NET PostBack.

Here is my JavaScript :


SFAIC


SFAIC = 
{
    masterPages: { cs: "CS_", cp: "CP_" },
    contentPages: { cs: "CSContent_", cp: "CPContent_" },
    
    isSecurePage  : false,

    $body         : undefined,
    $container    : undefined,
    $updatePanel  : undefined,

    $textBox      : undefined,
    $errorLabel   : undefined
};

SFAIC.init()


SFAIC.init = function () 
{ 
    log( "--> SFAIC.init() fired" );

    var self = this; 

    self.$body        = $( "body" );
    self.$container   = self.$body.find( "#container" );
    self.$updatePanel = self.getCSMasterElement( "UpdatePanel1", self.$container );
    self.$textBox     = self.getContentElement( "TextBox1" );
    self.$errorLabel  = self.getContentElement( "ErrorLabel1" );
     
    self.$updatePanel.delegate( self.$textBox.selector, "blur", function () 
    { 
       self.validateRequired( self.$textBox, self.$errorLabel ); 
    });
    
    self.$textBox.focus();
};

SFAIC.validateRequired()


SFAIC.validateRequired = function ( $element, $errorLabel ) 
{
    if ( $element.val().length === 0 ) { $errorLabel.text( "Required" ); }
    else { $errorLabel.text( "" ); }
};


Given the above, when SFAIC.init() is fired, self.textBox is assigned to its jQuery object. I guess herein lies my confusion. I thought that when you call .val(), it would return the value of what's in that element right then. In the case where you make a call to the server and change the value of the control which then comes back rendering the changed value of the element, it seems that the jQuery object doesn't know about that change?

Am I wrong here?

What do I need to do to keep a real-time reference to the element, so that I can get the current value after the page is posted back?


Edit request per @DaveLong :


SFAIC.getCSMasterElement()


SFAIC.getCSMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cs, id, $context ); 
};

SFAIC.getCPMasterElement()


SFAIC.getCPMasterElement = function ( id, $context ) 
{ 
    return SFAIC.getElement( SFAIC.masterPages.cp, id, $context ); 
};

SFAIC.getContentElement()


SFAIC.getContentElement = function ( id, $context ) 
{ 
    return SFAIC.getElement
    ( 
        ( SFAIC.isSecurePage ) ? SFAIC.contentPages.cp : SFAIC.contentPages.cs, 
        id, 
        $context 
    ); 
};

SFAIC.getElement()


SFAIC.getElement = function ( page, id, $context ) 
{
    selector = SFAIC.getElementIdSelector( page, id );
    
    return ( selector ) 
        ? ( $context && $context.length ) 
            ? $context.find( selector ) 
            : SFAIC.$body.find( selector )
        : undefined;
};

SFAIC.getElementIdSelector()


SFAIC.getElementIdSelector = function ( page, id ) 
{ 
    var prefix = SFAIC.getElementPrefix( page );
    return ( prefix && id ) ? "#" + prefix + id : undefined;
};

SFAIC.getElementPrefix()


SFAIC.getElementPrefix = function ( page ) 
{   
    switch ( page ) 
    {
        case SFAIC.masterPages.cs : return SFAIC.masterPages.cs;
        case SFAIC.masterPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs;
        case SFAIC.contentPages.cs : return SFAIC.masterPages.cs + SFAIC.contentPages.cs;
        case SFAIC.contentPages.cp : return SFAIC.masterPages.cp + SFAIC.masterPages.cs + SFAIC.contentPages.cs + SFAIC.contentPages.cp;                
    }
};

Solution

  • The UpdatePanel removes the entire target from the DOM and replaces it with new markup from the response. It isn't that your vars are holding old values, it is that they are holding references to the original markup. You need to "reinitialize" in order to obtain references to the new nodes in the DOM.