views:

611

answers:

2

Hey everyone,

I am trying to create an interface to the swfobject found at http://code.google.com/p/swfobject/. I am building the needed alternate content for when the user does not have flash player installed. This is working fine in FF, but not in IE for some reason. I have done this the same way a million times before and it has always worked, I can not figure out why I am getting this error this time.

Basically, when the page loads, it calls a function $.SWFObject.embedSWF() which builds the alternate content, and calls the swfobject.embedSWF function. The alternate content is built with a ready function like the following.

When the setupAlternateContent function is called the error occurs at the ('#' + containerID).

embedSWF: function(flashFilename, containerID, width, height, minFlashVersion, flashvars, params, attributes) {
   //If the flashvars, params, or attributes variables were passed in and are objects, then save them, otherwise they will be empty.
   settings.flashvars = (flashvars && typeof(flashvars) == 'object') ? flashvars : {};
   settings.params = (params && typeof(params) == 'object') ? params : {};
   settings.attributes = (attributes && typeof(attributes) == 'object') ? attributes : {};

   //Setup the alternate content that will be used if the user does not have flash installed
   $(document).ready(function() { setupAlternateContent(containerID); });

   //Call the embedSWF function which is found in the swfobject core file
   swfobject.embedSWF(flashFilename, containerID, width, height, minFlashVersion, flashUpdater, settings.flashvars, settings.params, settings.attributes);
}

function setupAlternateContent(containerID) {
    //Create the innerContainer div element
    var innerContainer = $.create('div', {
    }).appendTo('#' + containerID).css({
        font: '18px Arial, Verdana, sans-serif',
        height: '130px',
        width: '240px',
        paddingTop: '35px',
        margin: '0px auto'
    });

    //Put the flash image inside the innerContainer
    $.create('img', {
        src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
        alt: 'Install Flash'
    }).appendTo(innerContainer).css({cursor: 'pointer'}).click(function() { window.location = 'http://get.adobe.com/flashplayer'; });

    //Add a message bellow the flash icon
    $.create('p', {}, 'Install Adobe Flash Player').appendTo(innerContainer);
}

IE does not like the ('#' + containerID) argument which does not make any sense because i have done this before without problems. Also, I am using jQuery DOMEC extension which is where the $.create comes from.

Any help is appreciated. Thanks!

Metropolis

A: 

It looks like in your document ready handler you are calling setupAlternateContent with a variable called containerID - is this variable ever defined anywhere? If not then inside the function you will be doing appendTo('#') which I wouldn't be surprised at if it caused an error. What is the id of the container and where is it set before the document ready fires?

You could try an alert(containerId) inside setupAlternateContent to see that you are passing what you think you are to the function...


(Editing after new information added)

I don't know that the $.create method does but if you could try using jQuerys built in DOM creation: var innerContainer = $('<div />').appendTo(.... Or:

var innerContainer = $('<div />').css({
    font: '18px Arial, Verdana, sans-serif',
    height: '130px',
    width: '240px',
    paddingTop: '35px',
    margin: '0px auto'
});
$('#' + containerID).append(innerContainer);

Or even all at once:

$('#' + containerID).append(
    $('<div />').css({
        font: '18px Arial, Verdana, sans-serif',
        height: '130px',
        width: '240px',
        paddingTop: '35px',
        margin: '0px auto'
    }),
    $('<img />').attr({
        src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
        alt: 'Install Flash'
    }).css({
        cursor: 'pointer'
    }).click(
        function() { 
            window.location = 'http://get.adobe.com/flashplayer'; 
        }
    )
);
vitch
Yes the containerID is being passed to the embedSWF function. I will post this function so you can see. And yes, the correct value is being passed to the setupAlternateContent function.
Metropolis
I added a different implementation of your `setupAlternateContent` function which uses jQuery's built in DOM creation and append instead of appendTo, hopefully it helps...
vitch
Thanks a lot for the help vitch. I tried changing the code to what you had above. It looked promising, but unfortunately I am receiving the same error. Here it is in IE:Message: Invalid argument.Line: 12Char: 2305Code: 0URI: http://10.1.100.201/library/javascript/global/JQuery.core.js
Metropolis
+1  A: 

You may want to rethink your approach. If you need to display JS-generated alternate content when Flash Player is not available, I suggest doing a swfobject.hasFlashPlayerVersion("9") check before attempting to create the alt content. This check can be performed before the DOM loads.

Note that swfobject.embedSWF is wrapped in its own domready-style event, and therefore doesn't need to be wrapped in jQuery's $(document).ready event.

Simple example:

var hasFlash = swfobject.hasFlashPlayerVersion("9");
if(hasFlash){
   swfobject.embedSWF( ... ); 
} else {
   //Create alt content right away (no need to wait for dom to load)
   var altcontent = setupAlternateContent();
   //When DOM is ready, append alt content to page
   $(document).ready(function () { altcontent.appendTo("mycontainer") });
}

This approach speeds things up (no sitting around waiting for DOM to load just to figure out what needs to be done), and also prevents the alt content from being generated if it isn't needed.

Following this logic, I'd refactor your code to something like this (please forgive any typos):

embedSWF: function(flashFilename, containerID, width, height, minFlashVersion, flashvars, params, attributes) {

   if(swfobject.hasFlashPlayerVersion(minFlashVersion)){

      //If the flashvars, params, or attributes variables were passed in and are objects, then save them, otherwise they will be empty.
      settings.flashvars = (flashvars && typeof(flashvars) == 'object') ? flashvars : {};
      settings.params = (params && typeof(params) == 'object') ? params : {};
      settings.attributes = (attributes && typeof(attributes) == 'object') ? attributes : {};

      //Call the embedSWF function which is found in the swfobject core file
      swfobject.embedSWF(flashFilename, containerID, width, height, minFlashVersion, flashUpdater, settings.flashvars, settings.params, settings.attributes);

    } else {

       //Create alt content right away (no need to wait for dom to load)
       var altcontent = setupAlternateContent();

       //When DOM is ready, append alt content to page
       $(document).ready(function() { altContent.appendTo(containerID); });

    }

    function setupAlternateContent(containerID) {

        //Create the innerContainer div element
        var innerContainer = $.create('div').css({
            font: '18px Arial, Verdana, sans-serif',
            height: '130px',
            width: '240px',
            paddingTop: '35px',
            margin: '0px auto'
        });

        //Put the flash image inside the innerContainer
        $.create('img', {
            src: SWFOBJECT_FOLDER_LOCATION + 'flash_icon.png',
            alt: 'Install Flash'
        }).appendTo(innerContainer).css({cursor: 'pointer'}).click(function() { window.location = 'http://get.adobe.com/flashplayer'; });

        //Add a message bellow the flash icon
        $.create('p', {}, 'Install Adobe Flash Player').appendTo(innerContainer);

        return innerContainer;

    }
pipwerks
Awesome idea. Thanks pipwerks, that works great. Theres only one change I had to make for it to work the way I wanted. It needed to be if(!swfobject.hasFlashPlayerVersion(minFlashVersion)) { create alternate content } otherwise do everything else. This allows the swfobject.embedSWF function to be called still which gives the automatic update player in case the user has flash installed but the wrong version.
Metropolis
The thing i still do not understand though is, why I am getting that error. All I am doing is adding elements to the DOM on ready. It has always worked for me in the past, and even this is working in FF.
Metropolis
Dunno... maybe it doesn't like the empty object in the arguments? $.create('div', {}).appendTo('#' + containerID). I removed the empty object in my code, I don't know if you kept it in your revised version. Glad you got it working, though!
pipwerks