March 21, 2007

JavaScript: Adding/Removing Elements from thin air

JavaScript

Some of the key items we'll be going over:

1. How to create an element from thin air.
2. How to remove an element that we created from thin air.
3. How to set properties of an element created from thin air.
4. How to create a toggle feature for our element.
5. How to toggle only one element at a time.

Ok first off, why did I need this? I'm using a DataList to display item information. Each line is one item and contains a few action buttons. These action buttons pop up new windows and allow you to configure whatever it is you need. Anywho, it was decided that there should be no pop-ups and that the information should appear below the row. In an effort to reduce code the information below the row would be in an IFRAME so we could just point to the URL of the old pop-up window. I didn't want to throw in an IFRAME with each row so I decided to use JavaScript to create the IFRAME on the fly.

So first we need to know how to create an element from thin air. No problem,

var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');


Tada! All good to go. We have a DIV element with an id of s2info. But where is it? Well it's not displayed yet because we need to let it know who its parent is. Luckily within each row is a DIV element which contains all the information. This is going to be our parent element. Let's add our newly created DIV to our content DIV and give it some style.

s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';

var par = document.getElementById('parentDiv');
par.appendChild(s2div);


Great now our new DIV appears and it contains our IFRAME pointing to our example.com. Since this code needs to be called from our button clicks lets throw it in a function and then each button can just call it directly.

function showWin(el) {
// Create our DIV container
var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');
s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';
el.parentNode.appendChild(s2div);
return false;
}


Note that el is passed from the calling button. Also note that we append the new DIV with el.parentNode.appendChild(...). This is because we pass the button as el and its parentNode is the DIV we want to append to. So we're basically just pointing to the DIV but getting there through the button. Here is our button:

<input type="button" onclick="showWin(this);" id="iRox0rzB0xorz" value="Display" />


So now every time we click the button we append a new DIV with the iframe on the same row. Gravy right? Well what if we keep clicking the button? We're going to keep appending a new DIV! Well we only want one DIV visible per button click. If another button is clicked we want to close the currently open DIV (if one is open) and then open the one we clicked.

We'll need to set a global variable to keep an eye on which one is open. Here's the whole package:

<script language="javascript" type="text/javascript">
var old = '';
function showWin(el) {
var s = document.getElementById('s2info');
if (s) {
if (old != '') old.removeChild(s);
if (old == el.parentNode) {old=''; return false;}
}

// Create our DIV container
var s2div = document.createElement('div');
s2div.setAttribute('id', 's2info');
s2div.height = '300px';
s2div.width = '90%';
s2div.style.backgroundColor = 'red';
s2div.style.display = 'inline';
s2div.innerHTML = '<iframe src="http://www.example.com" width="100%"></iframe>';
el.parentNode.appendChild(s2div);
old = el.parentNode;

return false;
}
</script>


You can see our old variable keeps track of which element is showing the DIV. We also check to make sure a new button was clicked. If the same button was clicked twice we just remove the element but do not continue to add the new element.

And there you go. Cross-browser compatible? Not sure.

kick it on DotNetKicks.com