grooble
grooble

Reputation: 657

CSS doesn't work when dynamically adding elements to page using javascript

I want to dynamically add news updates to a page. When you log in, you get 20 news items. Scroll down to the bottom and there's a "more" button. Click it and some ajax fetches 20 more in json form from the server. Javascript parses the json into name, date, comment, pic etc.

the good news is that it kind of works. I can make text nodes for each name date comment etc. and add them to a id="more" div, and it all comes out in a blurb.

how do I get it into the same format as the surrounding divs? I'll make this as brief as possible...

three column layout, inside three column layout...

<div class="wrapper threecol">
<div class="colmid">
    <div class="colleft">
        <div class="col1">
            <div class="friends">   
            <div class="colwrap st-leftmenu">
                <c:forEach var="st" items="${news}">
                <div class="st-colleft">
                <div class="st-col1">
                <div class="statusName">
                    ${st.name}
                </div>
                        <%-- date, comment, pic etc. omitted --%>

                </div> <%-- end st-col2 --%>
                </div> <%-- end div class st-colleft --%> 
                </c:forEach>
                </div> <%-- end div class colwrap st leftmenu --%>

                        <%-- add new stuff here dynamically --%>
                <div id="showExtra"></div>

                <a href="javascript:void(0)" onclick="moreStatus()">get more</a>
            </div> <%-- end div class friends --%>
            </div> <%-- end col1 --%>

I'm trying to add to the id="showExtra" div, which partly works as above. I tried creating a complicated nested div structure in js. that got me part of the way there, but that can't be the way to do it... it's a bit of a mess, sorry...

function showMoreStatus(){
var moreDiv = document.getElementById('showExtra'); 

var moreJSON = new Array();

if(request.readyState == 4) {
    if (request.status == 200) {
        moreJSON = eval('(' + request.responseText + ')');
        for(var i=0; i<moreJSON.length; i++) {              
            //get values from JSON
            var JSONName = moreJSON[i][2];
                            // and others...

            //create text nodes, a href and img
            var nameTextNode = document.createTextNode(JSONName);
                            // and other nodes, imgs, hrefs etc...

                            // surely this is NOT the way to do it!             
            //column divs
            var outColDiv = document.createElement("div");
            outColDiv.setAttribute("class", "col1");
            var friendsDiv = document.createElement("div");
            friendsDiv.setAttribute("class", "friends");
            var colLeftDiv = document.createElement("div");
            colLeftDiv.setAttribute("class", "st-colleft");
            var col1Div = document.createElement("div");
            col1Div.setAttribute("class", "st-col1");
            var col2Div = document.createElement("div");
            col2Div.setAttribute("class", "st-col2");
            colLeftDiv.appendChild(col1Div);
            colLeftDiv.appendChild(col2Div);
            friendsDiv.appendChild(colLeftDiv);
            outColDiv.appendChild(friendsDiv);



            var nameDiv = document.createElement("div");
            nameDiv.setAttribute("class", "statusName");
                            // and others...

            // append nodes to divs
            nameDiv.appendChild(nameTextNode);

            col1Div.appendChild(nameDiv);
            col1Div.appendChild(dateDiv);
            col1Div.appendChild(contentDiv);

            // append the page
            moreDiv.appendChild(outColDiv);
        }
    }
}

}

Gah! Thanks for reading this far.

Well, that wasn't brief at all really. In fact, it's probably unnecessary.

What's the correct approach here? How can I get nameTextNode and all his friends to sit in the same place as ${st.name}?

Upvotes: 2

Views: 7035

Answers (2)

jmbertucci
jmbertucci

Reputation: 8224

General concept is that CSS should get applied appropriately for HTML elements, if they match the given CSS selectors. Even if you add them dynamically via AJAX.

I would recommend making sure you CSS is bullet proof. I think that might be the first pain point your having. If you have a list of news items, setup an HTML list like such:

<ul id="news">
    <li><!-- News Block 1 --></li>
    <li><!-- News Block 2 --></li>
    <li><!--     ...      --></li>
    <li><!-- News Block N --></li>
</ul>

In each news "block", you can structure some HTML as as needed. For example:

<li>
    <h2>News title 1</h2>
    <p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.</p>
    <p>Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.</p>
    <a href="#" class="read-more">Read More about News 1</a>
</li>

Then, you can just style up that "News Block" for all blocks.

#news h2{
    font-weight:600;
    font-family:Arial, Sans-Serif;
}
#news .read-more{
    text-decoration:none;
    color:#FF00FF;
}

From there, all you need to do is fetch and format your data with JavaScript/AJAX and append the LI "Block". Using jQuery can help make this easy.

Here's some rough pseduo-code:

// get news items from AJAX
var newsList = $.ajax().getNews(10);
// loop through all new news items
for(i=0;i<newsList.size;i++) {
    // get a formatted LI block
    var block = formatNewsBlock(newsList[i]);
    // append news block to end of news list
    $('#news').append(block);
}

A good structure to this can help make things easier to implement.

I hope that helps some!

Cheers!

Upvotes: 1

Mike Brant
Mike Brant

Reputation: 71384

You are not showing your CSS, so it is hard to say exactly what is breaking. My guess would be that because you are nesting the new elements inside this "showExtra" div, you are breaking the CSS selectors. You should probably just add the new elements at the same level as the existing ones, that is inside this element

<div class="colwrap st-leftmenu">

Also you probably need to look at your use of id properties in your tags. Id should be unique values and based on your looping structure, it look like you would get multiple items with the same id of "statusNameDiv".

Upvotes: 1

Related Questions