March 18, 2012

Internal css doesn't work for me with JS

Question by idish

I am trying to use the following css code in the table I create in JS but it seems that it doesn’t get any of it’s styles and I don’t know why.

So here’s the code:
CSS code:

    <style type = "text/css">
div.team
{
    margin-right:30%;
    }

        .team table

        {

        border-collapse:collapse;

        }

        .team table td

        {

        background-color:#4F5FAC;

        border:2px groove grey;

        }

        .team table th

        {

        font-style:italic;

        background-color:#0B1260;

        padding:0 15px;

        color:white;

        border:2px groove black;

        }

        .team tr td:first-child

        {

        color:yellow;

        font-weight:bold;

        text-align:center;

        }

</style>

JS code:

myWindow=window.open('table.html');
        myWindow.document.write("<table class = 'team'>");
        myWindow.document.write("<tr><td> שם  פרטי: </td><td>" + document.reg.name.value + "</td></tr> <tr><td> שם משפחה: " + document.reg.lname.value + "</td></tr> <tr><td> אימייל: " + document.reg.email.value + "</td></tr> <tr><td> סיסמא: " +document.reg.password.value +"</td></tr>");
        myWindow.document.write("</table>");

Any idea why I don’t get the styles of the table?(it works without the js)
Thanks in advance!

Answer by jfriend00

I see at least four issues:

  1. The CSS rules have to be in the same document that you’re trying to affect. So these CSS rules would need to be in table.html.
  2. If you use document.write() after the document has been loaded which you are doing here, it then clears out the current document (including all style rules you’ve previously included) and starts a new document. So, there is no way for these style rules to be in effect in the table.html file because you’ve cleared out the prior contents of that document. If you want to ADD content to the existing page without destroying it’s current contents and styles, then you need to use DOM insertion API calls like .append() or .insertBefore() or set .innerHTML on an existing DOM object.
  3. Your CSS rules are not specified properly. When you are targeting multiple identifiers on the same tag, you cannot have a space between the identifiers. So, .team table needs to be table.team and .team table th would need to be: table.team th. When you have a space between identifiers as in .team table, that means you want to match a table object with an ancestor of class="team". If you want an object that is both a table and class="team", then you have to not have a space between the two identifiers like this: table.team.
  4. If you want to add content to this new window while keeping the contents of table.html, you will have to wait for it to load (with the onload() event or one of the other DOMReady events) before its contents are ready to be modified and you cannot use document.write().

To solve all this, I would suggest this:

  1. Put all the style rules in an external stylesheet and include them in table.html.
  2. Put the javascript for modifying the page into table.html also.
  3. When you load table.html, add query parameters onto the end of the URL that pass it the values you want to display in that file.
  4. Add javascript to table.html that parses the query parameters to get the data and then, once the DOM is ready in that page, add that relevant content to the page.

This puts style rules in the right file and passes data to the new page while keeping the code for modifying the page within its own page (massively simplifying maintenance going forward).


OK, assuming you don’t need any of the content in table.html, you can create a new window from scratch with this code:

function openMyWindow() {
    var newWin = window.open("", "table");
    newWin.document.write("<div class='team'>");
    newWin.document.write('<table>');
    newWin.document.write("<tr><td> שם  פרטי: </td><td>" + 
        document.reg.name.value + "</td></tr> <tr><td> שם משפחה: " + 
        document.reg.lname.value + "</td></tr> <tr><td> אימייל: " + 
        document.reg.email.value + "</td></tr> <tr><td> סיסמא: " + 
        document.reg.password.value +"</td></tr>");
    newWin.document.write("</table>");
    newWin.document.write("</div>");
    var cssLink = newWin.document.createElement("link") 
    cssLink.href = "iframestylefile.css"; 
    cssLink.rel = "stylesheet"; 
    cssLink.type = "text/css";     
    newWin.document.getElementsByTagName('head')[0].appendChild(cssLink);
}​

You can see this work here: http://jsfiddle.net/jfriend00/VLt8h/. The style rules won’t apply there because the css file doesn’t have the correct full URL.

Answer by Starx

You CANNOT apply style to another page with the CSS of one page.

Upload the CSS to a file, then use the following snippet to load the css onto the opened page.

myWindow=window.open('table.html');
var cssLink = document.createElement("link") 
cssLink.href = "iframestylefile.css"; 
cssLink .rel = "stylesheet"; 
cssLink .type = "text/css"; 
myWindow.document.body.appendChild(cssLink);
// Now carry on writing the elements

Author: Nabin Nepal (Starx)

Hello, I am Nabin Nepal and you can call me Starx. This is my blog where write about my life and my involvements. I am a Software Developer, A Cyclist and a Realist. I hope you will find my blog interesting. Follow me on Google+

...

Please fill the form - I will response as fast as I can!