0

I realize that this posting is possibly a repeat of this one: Using Javascript to dynamically create links that trigger popup windows

But I'm not good enough at JavaScript to understand how to apply it to the context in which I'm trying to do it.

I'm creating a javascript snippet that could possibly be called multiple times from within a CMS (Umbraco ) that generates webpages.

An id (variable name: mediaid) is passed into this context and I want to dynamically create a link that has an onclick event to launch a popup. I take the ID passed into the context I'm working in (Umbraco calls them "macros") and append the id as a query string to a different URL (same domain) so that the resultant page can do some stuff with the id.

What I have works, but only for one instance on a page. I need a user to be able to insert multiple dynamic links on a page. Right now, the last link generated uses the onclick event for all instances on the page.

<script>
    var linkWithQueryParam = 'http://www.mydomain.org/test2?yourkey=<xsl:value-of  select="$mediaid" />';
    var element = document.createElement("a");
    element.id = '<xsl:value-of select="$mediaid" />';
    element.href = '#';
    element.onclick = function() {
        setLink(linkWithQueryParam);
    }
    function setLink(value) {
        window.open(value, 'player',    'width=775,height=520,location=0,directories=0,status=0,menubar=0');
    }
    document.body.appendChild(element);
    element.appendChild(document.createTextNode('Listen To This Audio'));
</script>

So, for example, I have a template elsewhere, that calls this macro I created, twice:

<umbraco:Macro mediaid="4107" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>
<umbraco:Macro mediaid="26502" Alias="audioPlayerPopUp" runat="server"></umbraco:Macro>

The links are generated, but when I click on them, the link generated above in "linkWithQueryParam" is always whatever the last one was, for all links.

I thought maybe if I set the "id" attribute of the link to make it unique, it would work. But that doesn't work. How can I make the dynamically generated onclick event unique?

Community
  • 1
  • 1

2 Answers2

0

I ended up changing my approach and using an event delegate per unclenorton's response in this s.o. post

http://davidwalsh.name/event-delegate

I used a variation on the example to only disable the default link behavior, first checking to see that the link class is matched. This script relies on a named div that is available sitewide and is placed at the bottom of a master template so it is available:

<script>
document.getElementById("main").addEventListener("click", function(e) { 
    if(e.target) 
    { 
        if(e.target.nodeName == "A")
        {
            if(e.target.className == "miniplayer")
            {

                if(e.preventDefault) { 
                    e.preventDefault();
                }
                else
                {
                    e.returnValue = false;
                }
                var target = e.target;
                var popupWindows = window.open(target.href, 'player', 'width=775,height=520,location=0,directories=0,status=0,menubar=0');
            }
        }
    }
});
</script>

I then edited my user macro to simply place the class "miniplayer" on each link it creates and include the media id as a query parameter to another url which provides the media player. That other url resource then pulls the query param id out of the url and looks up the link to the media item. But the .js above launches the pop-up the way that I want.

One challenge I had was on how to dynamically assign the resultant media resource to the player (in this case, jPlayer). I found that if I write the media url to a hidden div, I can then just tell the jPlayer to read the value from it.

So I have a second macro which gets the query param and writes it to a hidden div:

<div style="display:none" id="audioUrl"><xsl:copy-of select="$mediaNode/audioUrl" /></div>

Finally, I adjust the jPlayer jQuery to read the url from the hidden div:

$(this).jPlayer('setMedia', {mp3: $("#audioUrl").text() }).jPlayer("play");

It doesn't seem like the best solution. I don't like passing the mediaid through the url, but it fulfills all my other requirements

Community
  • 1
  • 1
0

The issue here is with globals and closures. The linkWithQueryParam variable is a global that is updated each time that script is added. When you click on the link it goes and fetches the url from the variable which is of course the last one.

You can fix this a few ways,

  1. Wrap this code in an immediate anonymous function. This will reduce the scope of the variables to within the anonymous function.

  2. Set the URL when the script is run instead of when the link is clicked.

Matt R
  • 724
  • 5
  • 14