/    Sign up×
Community /Pin to ProfileBookmark

Creating Nested layout DIV’s for Tabs

Hi Guys!
I’ve been developing my beta site (not yet live) and I am integrating a live last.fm stream of the songs I am listening to by using javascript to parse the API’s JSON and then place into tables (works very well):
[url]http://beta.mutant-tractor.com[/url]

Now, the trouble begins,
I currently have the data layed out all nice and neat in a table:
[URL=”http://dl.dropbox.com/u/17927147/Screen%20shot%202011-01-04%20at%2020.36.40.png”]Screenshot[/URL]

The “I’m Listening To” section is the section I wish to tab out like this:
[url]http://www.gayadesign.com/scripts/tabbed/[/url]

So that on hover over the Image the relevant meta data will move in,

The problem I’m now having is that apparently JQuery wont let me do this with tables, thus completely nullifying most of my scripting and I need to reformat the parsed data into nested DIVs rather than tables, and maintain the same layout…

The problem is, I CAN manage to create the parent DIVs that contain the images but cannot get the JSON data to be parsed into the child DIVs,

All DIVs are being created dynamically,

My code so far:

[CODE]
//Calculates date text
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 = “listening just now”;
else
agoString = “soon ;)”;
return agoString
}

//Shortens name to make it fit without multiple lines
function truncateName(name, l) {
return name.length > l ? name.substr(0,l-2) + “u2026” : name
}

//Parses and prints JSON
function lfmRecentTracks(JSONdata) {

try {
var eRow, eCell, eImg, eLink, eSpan, eNew;
//Master DIV
var eMain = document.getElementById(“lfmRecentTracks”);
//DIV containing artwork
var eArt = document.getElementById(“lfmArtRow”);
//Stores and passes JSON data to loops
var oTracks = new Array().concat(JSONdata.recenttracks.track);

//THIS WORKS
for (var i = 0; i < oTracks.length; i++) {
//insert coverart image
var divTag = document.createElement(“div”);
divTag.setAttribute(“align”,”center”);
divTag.style.margin = “0px auto”;
divTag.className =”dynamicDiv”;
divTag.innerHTML = “This HTML Div tag created using Javascript DOM dynamically.”;
document.body.appendChild(divTag);
divTag.className = “lfmTrackImageCell”;
if(oTracks[i].image[1][“#text”] != “”) {
eImg = document.createElement(“img”);
divTag.appendChild(eImg);
eImg.src = oTracks[i].image[1][“#text”];
eImg.className = “lfmTrackImage”;
}else{
eImg = document.createElement(“img”);
divTag.appendChild(eImg);
eImg.src = “http://cdn.last.fm/flatness/icons/res/3/track.png”;
eImg.className = “lfmTrackImageNotFound”;
}
}

//THIS DOESNT
for (var i = 0; i < oTracks.length; i++) {
//FROM HERE
var innerDiv = document.createElement(“div”);
eCell.appendChild(innerDiv);
//TO HERE DOESNT WORK
eCell.className = “lfmTrackInfoCell”;
//insert track link
eLink = document.createElement(“a”);
eLink.appendChild(document.createTextNode( truncateName(oTracks[i].name, 25) ));
eCell.appendChild(eLink);
eLink.href = oTracks[i].url;
eLink.target = “new”;
eLink.className = “lfmTrackTitle”;

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

//insert date
eSpan = document.createElement(“span”);
eCell.appendChild(eSpan);
eSpan.appendChild(document.createTextNode( (typeof oTracks[i].date==”undefined”?”now playing”:calculateDateAgo(new Date().getTime()/1000 – oTracks[i].date.uts)) ));
eSpan.className = “lfmTrackDate”;
}
} catch(e) {}
}[/CODE]

My idea would have a layout somewhat like this, then as they hover over the images the track name, artist and time are swapped to the relevant one as in the link to gayadesign above ?


———————————————–

|[Image1]|[Image2]|[Image3]|[Image4]|

|[Image1]|[Image2]|[Image3]|[Image4]|
———————————————–

[Track Name]
[Artist]

[How long ago it was played]
———————————————–

Any help would be greatly appreciated!
Thanks!
Myles

to post a comment
JavaScript

10 Comments(s)

Copy linkTweet thisAlerts:
@Mutant_TractorauthorJan 07.2011 — No one knows how to create nested divs?
Copy linkTweet thisAlerts:
@janusmccarthyJan 08.2011 — That which you're asking for, is not that which you're asking.

A nested div is just a div within another div

[CODE]
<div id="1">
<div id="2">
</div>
</div>
[/CODE]


It's not jquery that's not letting you do it, it's the script you're copying.

Look at the source on the page at Gaya you linked to, there's an example there.
Copy linkTweet thisAlerts:
@Mutant_TractorauthorJan 08.2011 — I am looking for a div within a div,

So then I can create a master div with the JSON generated divs within it side-by-side:

[CODE]
<div id="Artwork-Container">
<div class="lfm-Artwork"></div>
<div class="lfm-Artwork"></div>
<div class="lfm-Artwork"></div>
<div class="lfm-Artwork"></div>
</div>
[/CODE]


I plan to use these as the elements that are hovered over to switch the content elements...
Copy linkTweet thisAlerts:
@janusmccarthyJan 08.2011 — You could have done it with a table as well. Table cell supports on mouse over and inner html setting.
Copy linkTweet thisAlerts:
@Mutant_TractorauthorJan 08.2011 — I have tried setting the javascript up to target both class names and table data cells:

[CODE]
//tab effects

var TabbedContent = {
init: function() {
$("td.lfm-Artwork").mouseover(function() {

var background = $(this).parent().find("td.blank");

$(background).stop().animate({
left: $(this).position()['left']
}, {
duration: 300
});

TabbedContent.slideContent($(this));

});
},

slideContent: function(obj) {

var margin = $(obj).parent().parent().find("td.lfm-TrackInfo").width();
margin = margin * ($(obj).prevAll().size() - 1);
margin = margin * -1;

$(obj).parent().parent().find(".tabslider").stop().animate({
marginLeft: margin + "px"
}, {
duration: 300
});
}
}

$(document).ready(function() {
TabbedContent.init();
});
[/CODE]


It refuses to work on hover over though,

I am trying to debug it using alert("here"); bringing up a popup every time hover is activated but this never happens!

Thanks for your help so far Janus!
Copy linkTweet thisAlerts:
@janusmccarthyJan 09.2011 — Okay, the html of your example sets up four blocks next to each other

block1|block2|block3|block4

now the text within these 4 blocks have a high z-index (think of it as height, so they're on top of whatevers behind them).

there's also a div that just holds an image that serves as the "selected" index, as each blocks 'onmouseover' fires, the div that holds the selected image just animates to the new position

So what you'd want to do is to kind of keep that same method instead trying to animate a cell, it might be easier to just use divs because of the separation, but here goes

  • 1. Place the text in the 'td' tags in spans, and give them a high z-order do not change the z-order of the table, tr, or td, only the text

  • 2. Keep the "selector" as a div, and animate the div, basically just using the table to layout the text, you may need to reposition the div to place it over the table, you may also need to change the z-order so it lays between the table and the text


  • in theory, your code should look similar to the example given on their webpage, but your actual data (not the "selector div") should be in the table, you may even want to keep the container grid (relative positioning helps)

    it should look something like...

    [CODE]
    <div id='container'>
    <div id='selector'></div>
    <table>
    <tr>
    <td><span style='z-index: 100'>Text1</span></td> (or however they do it!)
    <td><span style='z-index: 100'>Text2</span></td>
    <td><span style='z-index: 100'>Text3</span></td>
    <td><span style='z-index: 100'>Text4</span></td>
    </tr>
    </table>
    </div>
    [/CODE]


    Personally, now that I've gotten a chance to look again, I think I'd stick with their example code, you're not doing things that are that different.

    Just look at the html of the page with their example, and copy and fill in to your page as necessary.
    Copy linkTweet thisAlerts:
    @janusmccarthyJan 09.2011 — If you look at their example, this is what they have:

    <div class="tabs">

    <div style="left: 0px;" class="moving_bg">&nbsp;</div>

    <span class="tab_item">Latest posts</span>

    <span class="tab_item">Top posts</span>

    <span class="tab_item">Partners</span>

    <span class="tab_item">Links</span>

    </div>

    Seems easier than a table solution
    Copy linkTweet thisAlerts:
    @Mutant_TractorauthorJan 10.2011 — Hi Janus,

    Thanks for the help but that is what I have been aiming for the whole time:

    [CODE]
    <div class="tabs">
    [B][COLOR="Red"]<div style="left: 0px;" class="moving_bg">[/COLOR][/B]&nbsp;</div>
    <span class="tab_item">Latest posts</span>
    <span class="tab_item">Top posts</span>
    <span class="tab_item">Partners</span>
    <span class="tab_item">Links</span>
    </div>
    [/CODE]


    My problem is I don't know how to create the second div marked in red above as it is nested within the other (I want JS to do all of this dynamically)

    EDIT:

    Got the above by just adding it as static HTML

    But the Spans are not contained within the slider thing

    This is what I have managed so far:

    [CODE]
    <div class='tabbed_content'>
    <div class='tabs'>
    <!-- I have managed to get this generated successfully -->
    <div class='moving_bg'>
    &nbsp;
    </div>
    [B][COLOR="SeaGreen"]<span class='tab_item'>
    Image1
    </span>
    <span class='tab_item'>
    Image2
    </span>
    <span class='tab_item'>
    Image3
    </span>
    <span class='tab_item'>
    Image4
    </span>[/COLOR][/B]
    </div>
    <div class='slide_content'>
    <div class='tabslider'>
    [B][COLOR="Red"][All Content in example is in <ul>'s here][/COLOR][/B]
    </div>
    <br style='clear: both' />
    </div>
    </div>
    [/CODE]


    If you got here:

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

    You will see my problem,

    Thanks!

    Myles
    Copy linkTweet thisAlerts:
    @Mutant_TractorauthorJan 10.2011 — Another update:

    I have managed to get all the styling etc 100&#37; perfect and added the alert("here"); to the script in the for loop that adds the text to the page, it displays 4 times which is correct but there is no text on the page!

    Even though it goes through the scripting fine...

    (Sorry for DP couldn't edit previous post)
    ×

    Success!

    Help @Mutant_Tractor spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 5.7,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @AriseFacilitySolutions09,
    tipped: article
    amount: 1000 SATS,

    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,
    )...