Posts Tagged ‘How To’

Element Swapping with Unobtrusive JavaScript

Monday, February 11th, 2008

There may come a time when you need to show different content on one page based on a user-selected option. Here’s a quick tutorial.

The first step is to set up your content properly. In this example, I’ll use a select to swap between two form elements, though the basic premise can be applied to other design patters such as module tabs. Here is how the form should look.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<form method="post" action="post.php">
 <div>
  <label>
   How Should I Reply To You?
   <select name="type" id="type">
    <option value="email">E-mail</option>
    <option value="phone">Phone</option>
   </select>
  </label>
 </div>
 <div id="byemail">
  <label>
   Enter Your Email:
   <input type="text" name="email">
  </label>
 </div>
 <div id="byphone">
  <label>
   Enter Your Phone Number:
   <input type="text" name="phone">
  </label>
 </div>
</form>

That is the basic setup you need. You have something for the user to select (that has an id to assign, in this case, an onchange event), and something to swap between that have ids. Now you need some JavaScript. Comments are inline to explain things.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/* Assign the onload event to the function init. */
/* Test which way adding events is supported. */
if(window.addEventListener) {
	/* W3C method. */
	window.addEventListener('load', init, false);
} else if(window.attachEvent) {
	/* IE method. */
	window.attachEvent('onload', init);
} else {
	/* Old school method. */
	window.onload = init;
}
 
/* This is the function that runs after the page loads. */
function init() {
	/* Get the select element you want the onchange to be applied to. I use the j_ prefix because sometimes errors happen when variables are named the same thing as IDs in the HTML. */
	var j_type = document.getElementById('type');
	/* If the element exists, we can assign the onchange event to call the swap function using the same type test we used before. */
	if(j_type) {
		if(j_type.addEventListener) {
			j_type.addEventListener('change', swap, false);
		} else if(j_type.attachEvent) {
			j_type.attachEvent('onchange', swap);
		} else {
			j_type.onload = swap;
		}
		/* Now, we need to fire the event to get the default. */
		if(document.createEvent) {
			/* The W3C method. */
			var j_event = document.createEvent('HTMLEvents');
			j_event.initEvent("change", true, true);
			j_type.dispatchEvent(j_event);
		} else if(document.createEventObject) {
			/* The IE method. */
			j_type.fireEvent("onchange");
		}
	}
}
 
/* This is the function that does the work of swapping the elements. */
function swap(e) {
	/* Get both the elements you want to swap between. */
	var j_email = document.getElementById('byemail');
	var j_phone = document.getElementById('byphone');
	/* Grab the event from the W3C method or the IE method. */
	var e = e || window.srcEvent;
	/* Grab the event target from the W3C method or the IE method. */
	var target = e.target || e.srcElement;
	/* Grab the target's value */
	var t_value = target.value;
	/* If both swap elements exist... */
	if(j_email && j_phone) {
		/* Depending on which option, hide or show the form elements. */
		if(t_value == 'email') {
			j_email.style.display = 'block';
			j_phone.style.display = 'none';
		} else if(t_value == 'phone') {
			j_email.style.display = 'none';
			j_phone.style.display = 'block';
		} else {
			j_email.style.display = 'none';
			j_phone.style.display = 'none';
		}
	}
	return true;
}

Save the script above to a file and include it in the head of your document that the form is in. You’ll have the swapping capabilities you desire using unobtrusive JavaScript and modern DOM techniques.

This was tested in Safari 3, FireFox 2, Opera 9.25, and Internet Explorer 7.

Easy Clearing Of Floats

Tuesday, April 24th, 2007

Web standards designers often need to make use of display:float to handle things like columns, navigation lists, and more. Usually these floats are followed by something like <div style="clear:both"></div>. It turns out there is an easier way.

I was reading 35 Designers x 5 Questions and saw a link for a way to clear floats without clear divs. The code that comes with the article is a bit confusing and sloppily written, but it works!

So, to make things easier to understand, I wrote my own example. The code below will do it for you.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
 <head>
  <title>Easy Floats</title>
  <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
  <style>
h1 {
	background-color:#FFCCCC;
	margin:auto;
	width:500px;
	text-align:center;
	margin-bottom:0px;
}
div#outer{
	width:500px;
	overflow:auto;
	padding-bottom:0px;
	background-color:#AAAAAA;
	margin:auto;
}
div#column1 {
	float:left;
	background-color:#CCFFCC;
	width:200px;
}
div#column2 {
	float:left;
	background-color:#CCCCFF;
	width:300px;
}
div#footer{
	width:500px;
	overflow:auto;
	padding-bottom:0px;
	background-color:#FFCCFF;
	margin:auto;
}
div p{
	padding:10px;
}
  </style>
 </head>
 <body>
  <h1>title</h1>
  <div id="outer">
   <div id="column1">
    <p>
     Left
     <br>
     Column
     <br>
     Floated
     <br>
     Left
    </p>
   </div>
   <div id="column2">
    <p>
     Right Column float with no clears below it...
    <br>
    </p>
   </div>
  </div>
  <div id="footer">
   <p>
    FOOTER not cleared...
   </p>
  </div>
 </body>
</html>