Question

Im trying to append some JSON data from the last.fm API,

I have been using alert() at several stages to verify the API is being parsed correctly and it is,

This has led me to the conclusion that getElementById().appendChild() doesn't work, below is the URL to the test page I have set up:

http://mutant-tractor.com/tabtest.html

So moving from this straight JS to JQuery I have been advised is the best way to go, That said I have NO clue about anything JQuery and my JS knowledge is based on some basic Java I have done...

How simple/not simple is it to convert this to working JQuery? I would put a bounty on this but I have no idea how to.

function calculateDateAgo(secAgo) {
 var agoString, agoRange, agoScaled;
 if(secAgo >= (agoRange = 60*60*24)) 
   agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"days":"day") + " ago";
 else if(secAgo >= (agoRange = 60*60))
   agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"hours":"hour") + " ago";
 else if(secAgo >= (agoRange = 60))
   agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"minutes":"minute") + " ago";
 else if(secAgo >= -60)
   agoString = "blastin' out now";
 else
   agoString = "soon ;)";
 return agoString;
}

function truncateName(name, l) {
return name.length > l ? name.substr(0,l-2) + "\u2026" : name;
}

function lfmRecentTracks(JSONdata) {

try { 
 var eImg, eLink, eSpan, divTag, eWrapper;
 var oTracks = new Array().concat(JSONdata.recenttracks.track);
 for (var i = 0; i < oTracks.length; i++) {
  //insert coverart image
  var spanTag  = document.createElement("span");
  document.body.appendChild(spanTag);
  spanTag.className = "lfmTrackImageCell tab_item";
  if(oTracks[i].image[1]["#text"] != "") {
   eImg = document.createElement("img");
   spanTag.appendChild(eImg);
   eImg.src = oTracks[i].image[1]["#text"];
   eImg.className = "lfmTrackImage";
  }else{
    eImg = document.createElement("img");
    spanTag.appendChild(eImg);
    eImg.src = "http://cdn.last.fm/flatness/icons/res/3/track.png";
    eImg.className = "lfmTrackImageNotFound";
  }
 }
for (var i = 0; i <>[lessthanhere] oTracks.length; i++) {
  //insert track link
  spanTag = document.createElement("span");
  spanTag.className = "lfmTrackInfoCell tabslider";
  eLink = document.createElement("a");
  eLink.appendChild(document.createTextNode( truncateName(oTracks[i].name, 25) ));
  //alert(truncateName(oTracks[i].name, 25));
  spanTag.appendChild(eLink);
  eLink.href = oTracks[i].url;
  //alert(oTracks[i].url);
  eLink.target = "new";
  eLink.className = "lfmTrackTitle";
  document.body.appendChild(spanTag);

  //insert artist name
  eSpan = document.createElement("span");
  eSpan.appendChild(document.createTextNode(truncateName(oTracks[i].artist["#text"], 22) ));
  //alert(truncateName(oTracks[i].artist["#text"], 22));
  eSpan.className = "lfmTrackArtist";
  document.body.appendChild(eSpan);

  //insert date
  eSpan = document.createElement("span");
  spanTag.appendChild(eSpan);
  eSpan.appendChild(document.createTextNode(   (typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts))  )); 
  //alert((typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts))); 
  eSpan.className = "lfmTrackDate"; 
  document.body.appendChild(eSpan);
 }  
} catch(e) {}
}

The only way the above code works is by using document.body.appendChild()

I have tried calling the script at the bottom of the body and inline so to allow the DOM to be loaded fully but these didn't work.

The div I'm trying to attach them to are 4 different divs i.e. in the for loop each loop needs to reference a different element,

Thanks in advance! Myles

EDIT:

HTML code:

    <link href='css/style.css' rel='stylesheet' type='text/css' />
    <script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js'></script>
    <link rel="stylesheet" type="text/css" media="all" href="http://beta.mutant-tractor/wp-content/themes/toolbox/style.css" />
    <link href='/css/tabbedContent.css' rel='stylesheet' type='text/css' />
    <script src="/scripts/JQuery/tabbedContent.js" type="text/javascript"></script>
    <script type="text/javascript" src="/scripts/General/lastfmtest.js"></script>
</head>
<body>
    <aside class="widget">
    <h3>I'm listening to...</h3>

    <div class="tabbed_content">
        <div id="lfmArtRow" class="tabs">
            <div class="moving_bg">
                &nbsp;
            </div>
            <script type="text/javascript" src="http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&amp;user=mutant_tractor&amp;api_key=6b85edc3841f3d0935d9dfed9c556634&amp;limit=4&amp;format=json&amp;callback=lfmRecentTracks"></script>
        </div>
    </aside>
    <div id="lfmRecentTracks" style='padding: 15px;'>
        <div class="content">
            <div class="tabbed_content">
                <div class="slide_content">                     
                    <div class="tabslider">
                        <div class="sliding_info">Test 1
                        </div>
                        <div class="sliding_info">Test 2
                        </div>
                        <div class="sliding_info">Test 3
                        </div>
                    <div class="sliding_info">Test 4
                        </div>
                    </div>
                    <br style="clear: both" />
                </div>
            </div>
        </div>
    </div>
    <div id="test">
        </div>
</body>

Was it helpful?

Solution

Instead of

document.body.appendChild( ... );

have your function locate the <div> where you want the content added, like this:

var targetDiv = document.getElementById('lfmRecentTracks');

(Do make sure that there's only one element on the page with that "id" value!! Also, for the sake of IE, make sure that name isn't a "name" attribute on anything either.)

Then you should be able to do this:

targetDiv.appendChild( whatever );

OTHER TIPS

document.getElementById() and appendChild() in general work fine in all major browsers, apart from a (likely irrelevant) issue with IE using id and name interchangeably. jQuery isn't necessary here.

There's no reason to do this. jQuery is JavaScript, but with added functionality. If it doesn't work in JavaScript, the translated jQuery wont work either. That's not even mentioning the added (unnecessary) work to translate it.

I wont argue whether you need jQuery or not. It's not a necessity. However, if you do want to use it, this is how you'd do the same code with jQuery:

            function calculateDateAgo(secAgo) {
             var agoString, agoRange, agoScaled;
             if(secAgo >= (agoRange = 60*60*24)) 
               agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"days":"day") + " ago";
             else if(secAgo >= (agoRange = 60*60))
               agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"hours":"hour") + " ago";
             else if(secAgo >= (agoRange = 60))
               agoString = (agoScaled = Math.floor(secAgo/agoRange))+" "+(agoScaled>1?"minutes":"minute") + " ago";
             else if(secAgo >= -60)
               agoString = "blastin' out now";
             else
               agoString = "soon ;)";
             return agoString;
            }

            function truncateName(name, l) {
            return name.length > l ? name.substr(0,l-2) + "\u2026" : name;
            }

            function lfmRecentTracks(JSONdata) {
                try { 
                    var eImg, eLink, eSpan, divTag, eWrapper, date;
                    var oTracks = new Array().concat(JSONdata.recenttracks.track);
                    for (var i = 0; i < oTracks.length; i++) {
                        //insert coverart image
                        var spanTag  = $('<span class="lfmTrackImageCell tab_item"></span>');
                        $("body").append(spanTag);
                        if(oTracks[i].image[1]["#text"] != "") {
                            eImg = $('<img src="'+oTracks[i].image[1]["#text"]+'" class="lfmTrackImage" />');
                            spanTag.appendChild(eImg);
                        }else{
                            eImg = $('<img src="http://cdn.last.fm/flatness/icons/res/3/track.png" class="lfmTrackImageNotFound" />');
                            spanTag.appendChild(eImg);
                        }
                     }
                    for (var i = 0; i <>[lessthanhere] oTracks.length; i++) {
                      //insert track link
                        spanTag = $('<span class="lfmTrackInfoCell tabslider"><a href='+oTracks[i].url+' target="new" class="lfmTrackTitle">'+truncateName(oTracks[i].name, 25)+'</a></span>');
                        //alert(truncateName(oTracks[i].name, 25));
                        //alert(oTracks[i].url);
                        $("body").append(spanTag);

                        //insert artist name
                        eSpan = $('<span class="lfmTrackArtist">'+truncateName(oTracks[i].artist["#text"], 22)+'</span>');
                        //alert(truncateName(oTracks[i].artist["#text"], 22));
                        $("body").append(eSpan);

                        //insert date
                        date = (typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts));
                        eSpan = $('<span class="lfmTrackDate">'+ date +'</span>');
                        spanTag.append(eSpan);
                        //alert((typeof oTracks[i].date=="undefined"?"now playing":calculateDateAgo(new Date().getTime()/1000 - oTracks[i].date.uts))); 
                        $("body").append(eSpan);
                     }
                } catch(e) {}
            }

Now, I offer no warranty to whether this works or not in production, but it looks right. Also, I wasn't sure what you were doing with the i <>[lessthanhere] oTracks.length; section, so I left it in. Normally, it'd be i < oTracks.length;.

It should be pretty simple. If there is one thing jQuery is good at (and there are many), it is DOM manipulation (ie exactly what you're trying to do.) Start with these tutorials

http://docs.jquery.com/Tutorials:How_jQuery_Works

http://docs.jquery.com/Tutorials:Getting_Started_with_jQuery

The second one will give you a good introduction to inserting HTML into a document. After that just check out the manipulation section of the documentation.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top