Navigate
Home
ArticleWiki
Forum
Newsletter
Links
Tech News
Welcome Guest.
Username:

Password:

Remember me

[HELP] DHTML appendChild+className problem
Welcome, Guest. Please login or register.
February 08, 2012, 10:33:42 AM
11513 Posts in 1262 Topics by 496 Members
Latest Member: Beerdernill
Experts Round Table Network  |  Clientside Technology  |  Javascript  |  [HELP] DHTML appendChild+className problem « previous next »
Pages: [1] 2
Author Topic: [HELP] DHTML appendChild+className problem  (Read 2301 times)
thrca

Offline Offline

Posts: 11


« on: November 06, 2007, 08:40:51 AM »

I am having an issue where, when I use javascript to create a new div and apply the className (the class has a background-color), the background-color is not applying to the div and I have been tearing my hair out for days trying to figure this out, so now I am here for help.

I tried to replicate the error with the following example code, but it seems to work properly:
Code:
<html>
<head>
<title>DHTML Bug example</title>
</head>
<body onload="init();">
<style>
.container_div {
border:1px solid #f00;
width: 250px;
}
.create_div {
clear:left;
border:1px solid #00f;
background-color: #0f0;
width: 100%;
height: 20px;
}
.create_div span {
float:left;
font-family: verdana;
font-size: .6em;
padding: 2px;
border-right:1px solid #00f;
height:100%;
overflow:hidden;
white-space:nowrap;
}
.span_25 {
width: 25%;
}
.span_50 {
width: 49%
}
</style>
<div id="container_div" class="container_div">
</div>
<script language="javascript">
function createdivs(numdivs) {
var newdiv = '';
var span = '';

for(i=0;i<numdivs;i++) {
newdiv = document.createElement('DIV');
newdiv.className = 'create_div';
span = document.createElement('SPAN')
span.className = 'span_50';
span.innerHTML = i;
newdiv.appendChild(span);
span = document.createElement('SPAN')
span.className = 'span_25';
span.innerHTML = 'foo'+i;
newdiv.appendChild(span);
span = document.createElement('SPAN')
span.className = 'span_25';
span.innerHTML = 'bar'+i;
newdiv.appendChild(span);
document.getElementById('container_div').appendChild(newdiv);
}
}
function init() {
createdivs(5);
}
</script>
</body>
</html>

So, knowing that this is working right, go look at the Actual code http://www.onebadpixel.com/beta/dispatch/planner.php.  In the bottom pane is a row with SO# 12345 which is statically created with the proper className, however if you click the "Switch Districts" button at the top, it should load some additional rows in the bottom pane with the same className, however the background-color is not applied for some reason. 

Any thoughts from anyone?
Jim B
Logged
GrandSchtroumpf
Mentor

Offline Offline

Posts: 432



« Reply #1 on: November 06, 2007, 10:08:38 AM »

I don't see any background defined in your current code.

Try adding this to the CSS:

.dayScheduler_so_row {
    background: lime;
}

Also, your generated code is invalid.  Several different nodes have the same ID which is illegal.
Logged
thrca

Offline Offline

Posts: 11


« Reply #2 on: November 06, 2007, 10:10:59 AM »

hrmm, background: eh?  I was using background-color: in the CSS, but I will try that.

Thanks for the heads-up on the ID's, I will check into that and fix it.
Logged
thrca

Offline Offline

Posts: 11


« Reply #3 on: November 06, 2007, 10:15:32 AM »

No-Go on the background: attribute instead of background-color:
If you look at it now, I have the style for the dayScheduler_so_row with the background color included.

When you mouseover the generated rows, i do element.style.backgroundColor='something else';
and onmouseout i do element.style.backgroundColor='';  // at this point it returns to the bg color of the style, which it was supposed to have to begin with.

I also tried it with...
.dayScheduler_so_row:hover {} which had no difference, other than IE didnt quite like that as much. :D
Logged
thrca

Offline Offline

Posts: 11


« Reply #4 on: November 06, 2007, 10:17:02 AM »

Also, your generated code is invalid.  Several different nodes have the same ID which is illegal.

How did you find these?  The generated divs dont show up in the page source so I am having a tough time locating them.  If I knew the ID of some of the duplicates, it would be much easier to find them.
Logged
thrca

Offline Offline

Posts: 11


« Reply #5 on: November 06, 2007, 10:21:47 AM »

Oddly enough, even if I set the element.style.backgroundColor='#FFFFD5'; just before the appendChild, it still does not set the color.
Logged
GrandSchtroumpf
Mentor

Offline Offline

Posts: 432



« Reply #6 on: November 06, 2007, 10:59:25 AM »

> The generated divs dont show up in the page source so I am having a tough time locating them.
In firefox, select all (ctrl + a), then right click and choose "show selection source".
The "web developer toolbar" has "View source -> View generated source" which does the same thing.
The "web developer toolbar" is a MUST HAVE when you work with web pages.

Don't use javascript to set the styles on your elements, this only makes things much more complicated than they ought to be.
If you need a javascript mouseover to make your page work in IE, then have the javascript set/unset some class on your element.
Remember, an element can have multiple classes (e.g. <div class="dayScheduler_so_row dayScheduler_so_row_hover">).
Logged
thrca

Offline Offline

Posts: 11


« Reply #7 on: November 06, 2007, 11:34:16 AM »

Don't use javascript to set the styles on your elements, this only makes things much more complicated than they ought to be.
If you need a javascript mouseover to make your page work in IE, then have the javascript set/unset some class on your element.
Remember, an element can have multiple classes (e.g. <div class="dayScheduler_so_row dayScheduler_so_row_hover">).

I would normally just define the class in the div on the page, but the div doesnt exist until the JavaScript creates it, so I couldnt think of any other way to set the className other than to define it during the createElement functions, as in the example in the first post.  I wonder if it would work better if I create a static hidden div with the proper class then use cloneNode instead of createElement to copy it, the append the inner elements into the cloned Div.
Logged
thrca

Offline Offline

Posts: 11


« Reply #8 on: November 06, 2007, 11:46:23 AM »

It appears that even cloning an existing node, that is 100% correct has the same problem, as you will see if you look at the page now.  I am cloning the div.id="dayScheduler_so_row_template" and appending new children spans to it.  I am really confused why this doesnt work, yet worked perfectly in the example I wrote up.
Logged
GrandSchtroumpf
Mentor

Offline Offline

Posts: 432



« Reply #9 on: November 06, 2007, 01:25:00 PM »

> so I couldnt think of any other way to set the className other than to define it during the createElement functions
That's correct.  It's exactly what i meant: use "node.className" and NEVER use "node.style.backgroundColor".
"node.style.xxx" is equivalent to using inline styles (html "style" attribute) which should be avoided AT ALL COSTS.

If you need a quick fix, you can try using the "!important" precedence modifier.  The effect is that your CSS will override the inline styles (as long as your inline styles don't use "!important") and the values you set using "node.style.xxx".

.dayScheduler_so_row {
    background-color: lime !important;
}

The real fix is to modify your code and remove all javascript "node.style.xxx" and all inline styles.
If the planner is someone else's code (some commercial product or open-source project), then I would just use the quick fix.

And I forgot to answer the "background" question:  In CSS, "background" is a shorthand for all background color, image, position, repeat.  If you only want a color, it's better to use "background-color" as you did before.  I only used "background" because i'm a lazy typist.
Logged
thrca

Offline Offline

Posts: 11


« Reply #10 on: November 07, 2007, 02:17:02 PM »

I have been going through and removing the inline styles in favor of CSS, plus did a major overhaul on the CSS to fix positioning which was a bit sloppy.. It now looks the same in IE and FF.

I think the duplicate DIV IDs you found were caused by clicking the "Switch District" button more than once.  I have a function in to clear the existing data that I had not implemented yet as I was still debugging other things, but this definitely would have caused that.  After I enable the function, the problem should clear up.. Thanks for the heads up.
Logged
GrandSchtroumpf
Mentor

Offline Offline

Posts: 432



« Reply #11 on: November 07, 2007, 03:25:58 PM »

> I have been going through and removing the inline styles in favor of CSS
Good, but don't forget to also drop the javascript "node.style.aaa = bbb" in favor of "node.className = 'ccc'".

The idea is that "presentation = CSS" and "content = HTML"... and that javascript should only be used to modify content, not to modify the presentation.
ID's and class names are part of the content and should be semantically correct (describe the content, not the presentation).  Class name can also be used to describe an element's status, like "Open" or "Closed" for tree branches for instance.
If you strictly stick to this simple principle, your code will be a lot easier to debug and maintain.

> I think the duplicate DIV IDs you found were caused by clicking the "Switch District" button more than once.
Yes, that must be it...  Sorry for this false alarm.  Anyway, it has nothing to do with your CSS issue.
Logged
thrca

Offline Offline

Posts: 11


« Reply #12 on: November 08, 2007, 07:17:49 AM »

> I have been going through and removing the inline styles in favor of CSS
Good, but don't forget to also drop the javascript "node.style.aaa = bbb" in favor of "node.className = 'ccc'".

Yeah, I dont think I have any places that have inline JS changes to the style, except that one background color thing I was working on, and the only reason I did that was because I was having trouble making it work.  I've worked around the problem by... Deciding to use white background.  :D  for now at least.
Logged
thrca

Offline Offline

Posts: 11


« Reply #13 on: November 08, 2007, 09:12:43 AM »

You win the bonus prize!
I was removing any places where I had inline styles and found the following:

To create the DIVs, I have a process that uses AJAX to gather data from the server. One of the items gathered is a bgColorCode, which I did the following:

Code:
var currentPendingDiv = createNewPendingDiv(parms);
if(itemsToBeCreated[no]['bgColorCode'] && itemsToBeCreated[no]['bgColorCode'].match(/^#[0-9A-F]{6}$/)){
          currentPendingDiv.style.backgroundColor = itemsToBeCreated[no]['bgColorCode'];
}

So finally, an explanation of why it worked in the example and not on my actual script.  Thanks for all the help.

I did find the stupid IE peek-a-boo bug in doing this though.  Oh well.
Logged
GrandSchtroumpf
Mentor

Offline Offline

Posts: 432



« Reply #14 on: November 08, 2007, 09:52:12 AM »

Good job.
Debugging javascript generated content can be a real nightmare.
I'm glad my comments helped you in finding the source of the problem.

The stupid IE peek-a-boo bug...  It's linked to the "haslayout" flag.  To fix the bug, "haslayout" needs to be "true" which, in some contexts, has some nasty side effects on the box model.  I hate IE.
Logged
Pages: [1] 2
« previous next »
    Jump to: