Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery UI Dialog and Flash in IE

I've been trying to get Zero Clipboard and jQuery UI Dialog to play nice together, and it's proving to be rather difficult.

Zero Clipboard allows copying to clipboard from Javascript by placing a transparent Flash movie over a button, so that the user clicks on the Flash when he tried to click the button. This works nicely and cross-browser as you can see in the demo page.

However, when trying to use this in a jQuery UI Dialog box something seems to go wrong.

First, I discovered that the flash element must be placed inside the dialog element, otherwise Chrome and IE refuse to respond to click events. This means I can't use the glue convenience method, but that's OK.

However, now IE for some reason won't accept the setText method on the Flash element.

An example of what I did is here. My code starts around line 300, and the most relevant lines are:

$("#showme").dialog({autoOpen: false, width: 550, height: 200});
$("#showme").bind("dialogopen", function() {
    if($("#clipflash").length == 0) {
        var btn = $("#d_clip_button");
        $("<div id='clipflash' style='position:absolute; background: #f00; z-index: 9999' />")
            .css(btn.position())
            .width(btn.width())
            .height(btn.height())
            .html(clip.getHTML(btn.width(), btn.height()))
            .appendTo("#showme");
    }
});

I colored the div red so it's easier to spot and set its z-index to 9999, just to be safe. I then set the position and size to cover the "button", and add the HTML for the Flash element with clip.getHTML().

I've been working on this for several hours now, so any help would be greatly appreciated.

Almost forgot: my problem is that IE7 says "Object does not support this property or method" inside the Zero Clipboard code.

UPDATE

powtac's comment points to something that looks really promising:

I forgot the own golden rule: In order for the Flash ExternalInterface to work in IE 7, you have to stuff the EMBED/OBJECT HTML into the DIV element AFTER it gets appended to the DOM. Stupid IE.

However, switching the lines .html(clip.getHTML(btn.width(), btn.height())) and .appendTo("#showme") didn't help. Even doing a setTimeout for adding the flash HTML later did not help. I feel like I'm really close, though...

like image 580
itsadok Avatar asked Oct 08 '09 12:10

itsadok


2 Answers

OK, so powtac did point me in the right direction, but there was one element missing: using the jQuery html() function did not have the same effect as simply setting innerHTML. If would be nice if somebody could explain why.

So, the fixed code looks like this:

$("#showme").bind("dialogopen", function() {
    if($("#clipflash").length == 0) {
        var btn = $("#d_clip_button");
        $("<div id='clipflash' style='position:absolute; background: #f00; z-index: 9999' />")
            .css(btn.position())
            .width(btn.width())
            .height(btn.height())
            .appendTo("#showme")
            [0].innerHTML = clip.getHTML(btn.width(), btn.height());
    }
});

Also, I forgot to put DOCTYPE in the example page, so the offsets are wrong in IE. My bad.

like image 119
itsadok Avatar answered Nov 16 '22 05:11

itsadok


I adapted your answer to a reusable method, and fixed a few position issues (I had to add position:absolute, and use outerWidth() and outerHeight().

Demo.

function setupCopier(selector, buttonSelector, callback, opt_dialogSelector){
  var copiedText = $(selector).text();
  ZeroClipboard.setMoviePath('http://dl.dropbox.com/u/464119/Programming/javascript/libraries/ZeroClipboard/ZeroClipboard.swf');
  var clip = new ZeroClipboard.Client();
  clip.setText(copiedText);
  clip.addEventListener('complete', callback);

  $(buttonSelector).each(function(){
    clip.glue(this);
  });

  // Make sure Zero Clipboard is on top
  $("#ZeroClipboardMovie_1").
    parent().
    css("z-index", 2000);

  if (opt_dialogSelector) {
    $(opt_dialogSelector).bind("dialogopen", function() {
      if($("#clipflash").length === 0) {
        var btn = $(opt_dialogSelector).find(buttonSelector);
        $("<div id='clipflash' style='position:absolute; z-index: 9999' />")
          .css(btn.position())
          .width(btn.outerWidth())
          .height(btn.outerHeight())
          .appendTo(opt_dialogSelector)
          [0].innerHTML = clip.getHTML(btn.outerWidth(), btn.outerHeight());
      }
    });
  }
}

$(function(){
  setupCopier('#copy-div', '.copy-button', function(){
    alert("Copied");
  }, '#dialog');

  $("#open-dialog-button").click(function(){
    $("#dialog").dialog("open");
  });

  $("#dialog").dialog({autoOpen: false, modal: true, resizable: false, draggable: false,
        title: "Create your Free Personal Bar now", height:200, width:300});
});
like image 25
ripper234 Avatar answered Nov 16 '22 06:11

ripper234