user1721994
user1721994

Reputation: 11

Creating dynamic CSS in Javascript

I am trying to create an info window for Google maps and need to generate a dynamic form to display information.

The following scripts generates an error called "No_found_err: DOM exception 8":

//create objects for HTML elements              
var inputElement1 = document.createElement("input");
var inputElement2 = document.createElement("input");

//assign different attributes to the element
inputElement1.setAttribute("type", "text");
inputElement1.setAttribute("id", "poiName");
inputElement2.setAttribute("type", "textarea");
inputElement2.setAttribute("id", "poiDesc");

//create style tag, atrributes and values
//add css style to head tag and define classname for HTML "desctag" element
var cssNode = document.createElement("style");
cssNode.setAttribute("type", "text/css");
cssNode.style.cssText = ".cssClass {vertical-align: text-top; width: 250px; height: 150px }";

document.getElementsByTagName("head")[0].appendChild("cssNode");
document.getElementById("poiDesc").className = "cssClass";

var formString = "<b>Enter location details:</b>
<p>Name:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;" +
"&nbsp;&nbsp;&nbsp;" + inputElement1 + "<br>Description:&nbsp;&nbsp;" + inputElement2 +
"<p><center>" + "<input type='button' id='saveBtn' value='Save' onclick='savePOI()'>  
</center>";

//insert values into the form elements      
document.getElementById("poiName").value = locList[i].name;
**document.getElementById("poiDesc").value = locList[i].desc;**

This error appears in between the last two lines. Does it mean that the tag id "poiName" and/or "poiDesc" have not been created?

How can I solve the above problem?

Thank you.

Upvotes: 1

Views: 196

Answers (3)

enhzflep
enhzflep

Reputation: 13089

In addition to the other answers, this code needs to be changed from:

cssNode.style.cssText = ".cssClass {vertical-align: text-top; width: 250px; height: 150px }";

to:

cssNode.innerText = ".cssClass {vertical-align: text-top; width: 250px; height: 150px }";

Your code was doing the equivalent of this:

<style type='text/css' style='.cssClass {vertical-align: text-top; width: 250px; height: 150px }'></style>

(incidently, since the style string includes the class and the braces, it's invalid when used in this way. This means you actually create <style type='text/css'></style> )

While I assume it was your intention to do this (formatting added for clarity)

<style>
  .cssClass 
  { 
    vertical-align: text-top;
    width: 250px;
    height: 150px;
  }
</style>

Here's a complete example of (a) creating style elements on the fly (b) modifying css on the fly (c) extracting info from items in a list.

Enjoy. :)

<!DOCTYPE html>
<html>
<head>
<style>
label
{
    width: 75px;
    display: inline-block;
}
</style>
<script>
var locList = [ {name:'Australia', desc:'pop. 22,620,600', col:'green', bg:'yellow'}, {name:'New Zealand', desc:'pop. 4,405,200', col:'white', bg:'black'} ];
function byId(e){return document.getElementById(e);}

var dynamicCSS;

function selChange(element)
{
    var arrayIndex = element.value;
    if (arrayIndex != -1)
    {
        byId('poiName').value = locList[arrayIndex].name;
        byId('poiDesc').value = locList[arrayIndex].desc;

        var styleStr = "#poiName,#poiDesc{color: " + locList[arrayIndex].col + "; background-color: " + locList[arrayIndex].bg + "; }";
        dynamicCSS.innerHTML = styleStr;
    }
    else
    {
        byId('poiName').value = byId('poiDesc').value = 'No option selected';
        dynamicCSS.innerHTML = '';
    }
}

function myInit()
{
    var st = document.createElement('style');
    st.innerHTML = '#poiName, #poiDesc{border:solid 2px green;}';
    document.body.appendChild(st);

    dynamicCSS = document.createElement('style');
    document.body.appendChild(dynamicCSS);
}
</script>
</head>
<body onload='myInit();'>
    <form id='myform'>
        <label for='optSel'>Option:</label>
        <select id='optSel' onchange='selChange(this);'>
            <option value='-1'>None selected</option>
            <option value='0'>Aus</option>
            <option value='1'>NZ</option>
        </select>
        <br>
        <label for='poiName'>Name</label><input id='poiName'/>
        <br>
        <label for='poiDesc'>Desc</label><input id='poiDesc'/>
    </form>
</body>
</html>

Upvotes: 0

Musa
Musa

Reputation: 97672

document.getElementsByTagName("head")[0].appendChild("cssNode"); should be document.getElementsByTagName("head")[0].appendChild(cssNode); notice cssNode isn't quoted, you passed a string to append Child instead of the node.

inputElement1 and inputElement1 are elements not string, so appending them to an html string wont give the desired results. Also you never add them or the html string to the dom, so document.getElementById wont be able to find them.

Upvotes: 1

Ashwin Singh
Ashwin Singh

Reputation: 7345

Yes, instead you should use inputElement1 and inputElement2.

document.getElementById() gets an element with the id in the document. The document does not have it until now. It will only when rendered.

Upvotes: 0

Related Questions