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

March 07, 2007

Integrating Google Maps

Google Maps + Your web app = Simple

Working on a feature for my project and wanted to share how easily you can get Long + Lat using the Google Maps API.

First we need to get the presentation down. We'll be creating a popup div where you can type an address and a button that displays the location on the Google Map.

    <div id="selectgeo" runat="server" style="background-color: GreenYellow; border: solid 1px darkgreen;
position: absolute; left: 10px; top: 5px;">
Address:
<input id="txtAddr" type="text" />
<input id="btnfindgeo" type="button" value="Go" onclick="showAddress(document.getElementById('txtAddr').value); return false;" />
<input id="btndonegeo" type="button" value="Done" onclick="document.getElementById('selectgeo').style.display='none';" />
<div id="mappp" style="width: 270px; height: 175px">
</div>
</div>

<script src="http://maps.google.com/maps?file=api&v=2&key=yourkey"
type="text/javascript"></script>


REMEMBER to replace "yourkey" with your Google Maps API key. Get one here.

So we've got our Div: selectgeo, our Address box: txtAddr, our Button to find the location: btnfindgeo, our Done button: btndonegeo and finally our div which contains the map: mappp.

You can see btnfindgeo is wired up with a javascript function: showAddress. This is where the goods come from :) Onto the JavaScript!

var map;
var geocoder = new GClientGeocoder();

function loadGMap() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("mappp"));
map.addControl(new GSmallZoomControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(37.4019, -122.1419), 13);
}
}

function showAddress(address) {
geocoder.getLatLng(address,
function(point) {
if (!point) {
alert(address + " not found");
} else {
map.setCenter(point, 13);
var marker = new GMarker(point);
map.addOverlay(marker);
alert('['+ point.x + ', ' + point.y +']');
}
}
);
}

// Programatically load the map after onload.
var abo = document.getElementsByTagName("body");
if (abo != null) {
abo[0].onunload = GUnload;
abo[0].onload = loadGMap;
}


And you're done! Type in your address and see what happens.

Also the Google Maps API Documentation provides a TON of useful examples.

kick it on DotNetKicks.com