Link to home
Start Free TrialLog in
Avatar of JaeWebb
JaeWebb

asked on

Spry Widget Styles Lost After HTML Reloaded by AJAX Method: How Do I Fix It?

Please check the URL above to get a visual for what I'm referring to.  Visit the 'parade sponsors' link, scroll down the page once it loads, then test the widget on that page.  Next, click the parade sponsors link again and scroll down...

As you can see, the widget lost its' styles  after I did an Ajax transfer on the left column area, aka 'main content'.  I originally thought that having the stylesheets linked in the head tags would be enough but apparently Spry needs to run its JavaScript before displaying its widgets each time.  While debugging using Google Chrome (and Firefox), I noticed there is a Spry property called 'Spry.Widget.SlidingPanels.onloadDidFire' that seems to relate to the problem I'm having.  After Ajax transfers to another page with widgets, like 'sponsorship', the property is false.   This is because the Spry objects are called at the bottom of the DOM elements, as suggested by Adobe, and when the main content is ajax-transfered in, the widgets on that page are not instantiated.  Widgets are instantiated dynamically based on the loaded page at the bottom, not on the Ajax-loaded sub-pages (in the middle, above the bottom).

How do I fix this?  Any ideas?

Note:

  +  I assume that you have a browser inspection/debugging tool like Google Chrome or Firefox that will let you see the code at it happens.  I pasted the Ajax class below.

  +  I'd like to use JavaScript or back-end code (PHP) to fix this.  No iFrames and no bad HTML markup like style tags loaded right into the sub-page.

  +  Hopefully I can use some functionality inside the Spry framework to trigger the event that adds the styles when objects are first instantiated.

  +  JavaScript doesn't fire onload when sent into the page through the sub-pages.  To compensate, I use a JavaScript callback function called 'doAjaxByFlash()', called by the Flash animation just after the Ajax callback method returns successful.  JavaScript is meant to be fired once the sub-page content arrives in the browser can be placed here; that's where the alert that pops up when you click 'parade sponsors' link is located.


Thanks for your help!



// JavaScript Document
 
var _activeRequestPage = '';
 
function Ajax( _id )
{
	this.id = _id;
	this.toString = function()	{		return "Ajax";	}
	this.ftype = ".inc.php";
	this.isFlashEnabled = true;
	this.mastHeadAnimeReady = true;
	
	//Create HTTPRequest object, add listener (callback) method, and send request
	this.makeRequest = function( _method, _url, _callbackMethod )
	{
		_activeRequestPage = _url;
 
		var targetURL = _url + this.ftype;
		this.request = ( window.XMLHttpRequest )? new XMLHttpRequest() : new ActiveXObject( "MSXML2.XMLHTTP" );
		this.request.onreadystatechange = _callbackMethod;
		this.request.open( _method, targetURL, true ); 
		this.request.send( targetURL ); 
	}
	
	/*
		Wrapper methods for makeRequest'
	*/
	this.doRequest = function( urlRequest )
	{
		this.makeRequest( "POST", urlRequest, this.doPageTransfer );
	}
	
	/*
		Callback methods for HTTPRequest object
	*/
	//attached via doRequest wrapper method
	this.doPageTransfer = function( )
	{
		//alert( "Ajax status: " +  this.readyState ); //Fires four times, once for each status
		switch( this.readyState )
		{
			//case 'zero' is "uninitialized"	
			//Loading...
			case 1:
				break;
			
			//Loaded.
			case 2:
				break;
			
			//Interactive.
			case 3:
				break;
			
			//Complete.
			case 4:
				var isFlashOn = true;
				 
				 //activate Toy Solidier animation
				 if ( isFlashOn )
				 {
					var anime = window.document.OHPHeaderAnime;		//attatch Flash masthead animation
					anime.toySoldierCaneTwirl() ;												//do callback method inside animation
					anime.browserAjaxReinstantiation() ;								//do callback method inside animation
				 }
				document.getElementById( "pageHub" ).innerHTML = this.responseText;
		}
	}//End doPageTransfer method
}
 
//method is called whenever the animation needs to speak to the browser
function doAlertFromFlash( message )
{
	var errorMessage = message;
	alert( message );
}
//Flash animation JS methods
function doAjaxByFlash()
{	
	switch (  _activeRequestPage )
	{
		case "pages/parade_participants" :
			alert( Spry.Widget.SlidingPanels.onloadDidFire );
			break;
		
		default:
		
	}
}

Open in new window

Avatar of Jason C. Levine
Jason C. Levine
Flag of United States of America image

JaeWebb,

Can't navigate the site using the menu.  Do you have a better link for us?
Avatar of JaeWebb
JaeWebb

ASKER

I forgot to specify that the Flash movie that triggers the ajax transfer method, doAjaxByFlash(), requires Flash Player 10.  Have you upgraded yet? I didn't enable express install yet... Here's the upgrade link:

http://www.adobe.com/products/flashplayer/

If you need to uninstall Flash, let me know and I'll get you the links from the adobe site.
>> Have you upgraded yet?

No, I haven't.  I tend to not jump to the next version of Flash right away (as many people do) so you may want to consider a different method on the site unless you also are going to include a detect and upgrade function...
Avatar of JaeWebb

ASKER

I will be including the detect and upgrade function.  I have a demo version that works but it includes an image.  I don't have time to integrate that into the design yet but trust me, it will be there before it goes live.

If you or anyone else is interested it checking it out, you can install FlashPlayer 10 at the link above, then uninstall it here if you like:

http://www.adobe.com/go/tn_14157

You can get any of the FlashPlayer versions here:

http://www.adobe.com/go/tn_14266

--------------------------------------------------

I've upgraded the JavaScript running in the background.  I realized the script is terminated somwhere in inside the SpryTabbedPanel.js file's "attach Behaviors()" method.  The Ajax class is below; it has one alert.  There is another alert in the SpryTabbedPanels.js just after the "attachBehaviors()" method.
// JavaScript Document
 
var _activeRequestPage = '';
 
function Ajax( _id )
{
	this.id = _id;
	this.toString = function()	{		return "Ajax";	}
	this.ftype = ".inc.php";
	this.isFlashEnabled = true;
	this.mastHeadAnimeReady = true;
	
	//Create HTTPRequest object, add listener (callback) method, and send request
	this.makeRequest = function( _method, _url, _callbackMethod )
	{
		_activeRequestPage = _url;
 
		var targetURL = _url + this.ftype;
		this.request = ( window.XMLHttpRequest )? new XMLHttpRequest() : new ActiveXObject( "MSXML2.XMLHTTP" );
		this.request.onreadystatechange = _callbackMethod;
		this.request.open( _method, targetURL, true ); 
		this.request.send( targetURL ); 
	}
	
	/*
		Wrapper methods for makeRequest'
	*/
	this.doRequest = function( urlRequest )
	{
		this.makeRequest( "POST", urlRequest, this.doPageTransfer );
	}
	
	/*
		Callback methods for HTTPRequest object
	*/
	//attached via doRequest wrapper method
	this.doPageTransfer = function( )
	{
		//alert( "Ajax status: " +  this.readyState ); //Fires four times, once for each status
		switch( this.readyState )
		{
			//case 'zero' is "uninitialized"	
			//Loading...
			case 1:
				break;
			
			//Loaded.
			case 2:
				break;
			
			//Interactive.
			case 3:
				break;
			
			//Complete.
			case 4:
				var isFlashOn = true;
				 
				 //activate Toy Solidier animation
				 if ( isFlashOn )
				 {
					var anime = window.document.OHPHeaderAnime;		//attatch Flash masthead animation
					anime.toySoldierCaneTwirl() ;												//do callback method inside animation
					anime.browserAjaxReinstantiation() ;								//do callback method inside animation
				 }
				document.getElementById( "pageHub" ).innerHTML = this.responseText;
		}
	}//End doPageTransfer method
}
//Spry Ajax fix   instantiateSpryObjects
 
 
//method is called whenever the animation needs to speak to the browser
function doAlertFromFlash( message )
{
	var errorMessage = message;
	alert( message );
}
//Flash animation JS methods
function doAjaxByFlash()
{	
	var request = new String( _activeRequestPage );
	request = request.replace( "pages/", "" );
	instantiateSpryObjects( request );
	
	/*
	alert( "Spry.Widget.TabbedPanels.onloadDidFire:\n" + Spry.Widget.TabbedPanels.onloadDidFire  + "\n\n"
		  + "Spry.Widget.SlidingPanels.onloadDidFire:\n" + Spry.Widget.SlidingPanels.onloadDidFire );
	*/
	var tempNum = Math.floor( Math.random() );
	switch (  request )
	{		
		case "parade_background" :
			
			//Spry.Widget.SlidingPanels.processLoadQueue(); 
			break;
 
		case "sponsorship" :
			var tp = document.getElementById( "TabbedPanels1" );
			tp.attachBehaviors();
			//The Alert won't fire after this point because the script is terminated somwhere in inside
			//The SpryTabbedPanel.js file's "attach Behaviors()" method
			alert( "AJAX attachBehaviors Target ID: " + tp.id + ", style: " + TabbedPanels1.className );
			
 
			break;
		
		default:
			
	}
	/**/
}

Open in new window

Avatar of JaeWebb

ASKER

I've added alerts to the code.  If you press each alert slowly, you'll be able to see the styles appear and then disappear.  I think I'm having a scope issue inside my Ajax class.

Anyone out there with FlashPlayer 10?
ASKER CERTIFIED SOLUTION
Avatar of JaeWebb
JaeWebb

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial