Posts Tagged ‘JavaScript’

Forms With Elements With Form Attribute Names

Tuesday, September 23rd, 2008

I commonly create a form element that dictates the action I want the server to perform, like <input type="hidden" name="action" value="save">. This allows me to have a switch to determine what to do with the data in any situation instead of posting and getting to multiple places. I found a bug in Internet Explorer 7’s JavaScript today that introduces a problem with my naming scheme.

When doing Ajax, I often use form.getAttribute('action') to get the location to send the request to. This allows me to keep my code more portable. However, in Internet Explorer 7 (or IE7 for short), if there is also a form element with name="action", IE7 returns the input object instead of the value of the attribute as though I typed formname.action or, in long hand, document.forms['formname'].elements['action'].

To my knowledge, there is no work around other than changing the name of the element. So, I’ll be using name="faction" from now on. That’s short for “form action” but “faction” itself is fairly apt given IE’s behavior is different from all other browsers, making it a faction.

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.

iUI Makes iPhone Development Easier

Friday, August 17th, 2007

The iPhone was a little less exciting when Apple revealed that web apps were the only way developers could write applications for the iPhone. While committed folks eventually opened the phone up for third-party applications, some interesting stuff was happening on the web application front. It’s called iUI.

iUI is a JavaScript framework to make coding pages for the iPhone really easy. Joe Hewitt’s (of FireFox, FireBug, and FaceBook fame) small JavaScript library can transform simple lists and links into an experience much like a regular iPhone application.

iUI uses many CSS3 properties with images ripped from the iPhone itself to create the distinctive interface, complete with sliding animations and Ajax page replacement. He points out in a Y!UI Theater video that Safari Mobile lacks many events found on regular browsers due to lack of ways to input those events on a touch screen, as well as having no mechanism to access flicks used to scroll in native applications.

Despite the limitations, knowing such an easy to use solution makes me want to download TestiPhone and write something for iPhone, even though I don’t own an iPhone. I would take Eric Meyer’s concerns into account, however.

How To Do Modern Web Design

Friday, January 12th, 2007

I’ve been trying to figure out the best way to explain how to do modern, semantic, standards compliant web design. I’ve been trying to make the point to my current protege that one should first look at a website like a term paper and move on from there. I’ve formulated a method now that I’d like to outline.

I once described how I see web design as a left brain plus right brain task. However, a new A List Apart article called Grok Web Standards breaks it down even more, suggesting that a web designer must think like a writer, artist, and engineer. The article inspired me to write the steps I think web designers should take to making a site.

I must say now that I seriously doubt anyone will ever work this way. It relies on the idea that content is given to the designer first. Rarely, if ever, will a client give you content without seeing a design. This is unfortunate because the goal of a website is to communicate a point. Looking pretty is the icing. You won’t be able to bake a cake without letting the client taste the icing first until you have a very good reputation. However, I hope my steps are written well enough that, if need be, designs can be done first.

How To Do Modern Web Design

  1. Understand Your Content

    Content is king. Before you touch an editor, read your content and understand it. Once you understand what you want to present, it becomes easier to mark up and will give you ideas on how you want to present the content to the user. Make a mental outline of what is in the content to help make decisions. To be clear, content does not just mean the text on the page. Content includes navigation and footer information as well as regular page content and images.

  2. Format Your Content

    The first goal of a site (web apps excluded) should be to present a message in a clear manner. The best way to do this is to make sure your markup is structured and semantic. I like to think of it as manually marking up a term paper or essay. Term papers must be clearly arranged and defined in logical sections. Lists should be presented as lists, paragraphs as paragraphs, and headings as headings.

    Every designer should have some boilerplate to work with. That is, having a very simple HTML template with basic elements (e.g. DOCTYPE, head, title, body, and any other basic elements you usually work with) will save you a few minutes up front and allow you to get down to business. Smultron, for example, has this built in. If you don’t, write a basic, empty HTML document. Don’t include stylesheets yet.

    To qualify the previous paragraph, boilerplate is only really needed if you want to validate as you go. If you trust your ability to write valid disembodied markup, just bang out the markup in a text editor without the rest of the code. It’s how I’m writing this post since it’s going to be injected into a design that has the rest of the code. In the end, you might save some time by not using boilerplate (e.g. if you have tons of pages that will need extra elements inserted during step four below). For the beginners, though, understanding the document structure will be more useful than the time saved by skipping out on it.

    Your task is to turn your content into something logical, legible, and semantic. Use your understanding of the content to create a document. Based on your mental outline, use headings with the correct level (typically the document title should be the first level heading, for example), lists, paragraphs, blockquotes, tables for tabulated data. Give emphasis, citations, and hyperlinks. Front load your lists if you need to. Don’t use divisions, fonts, or styles. Do rely on the browser’s built in formatting. Default styles are well thought out by the browser maker. You just want to make sure your content makes sense. Yes, it looks boring, but it also looks clean. When you view your document in a browser with no stylesheets, it should make sense when you try to read it.

  3. Design For Your Content

    By now, you should be pretty intimate with the content. You should have a clear idea about what the content is about. This will allow you to create a design that helps present that content in a truthful manner. Take what you know about your content and mockup something that can present it well. I suggest using Photoshop to work on mockups at this point. This will keep you from having to write a big stylesheet when you don’t know if you need it.

    Also, focus on usability. People that come to this site have no knowledge of how you intended them to use it. They have certain knowledge about the way the web usually works. It’s best to take that into consideration. If you break from tradition, you need to make it obvious how you intend the user to interact with the site.

    After you are certain that the content is accurately represented and the design is usable, then worry about aesthetics.

    Typically, clients will want to approve a design. So, make a good composite to show off. You may even want to do a little HTML and drop a full-sized composite into a browser so the client can get a feel of how it would look.

    If it turns out that you have to do this step first, you should have an idea about what sort of content the client wants to be on his site. You may have to use your imagination a little more. Don’t worry, though. This is where most people have to start, and I believe starting here can still produce a great site, even if it isn’t the most ideal place to start.

  4. Start Merging Content and Design

    Open your basic document in FireFox, Opera, or Safari. Since these browsers basically agree with one another, this will help you start with a standards compliant site. Now is when you want to start working on your stylesheets.

    Start coding your stylesheet based on what you already have. Before, people misused tables to create designs. Using web standards, people tend to get div diarrhea. Instead of using elements that exist, people put divs around everything whether they need it or not. So, I suggest making creative use of headings, navigation lists, and paragraphs to trim down your stylesheet as much as possible.

    The best place to start is by throwing out some of the default formatting. I know I just said it was well thought out. It still is. It just isn’t well thought out for your design.

    The first part of my main stylesheet clears margins, paddings, and borders (i.e. *{margin:0px; border:0px; padding:0px;}). From there, it’s the designers job to figure out the best proximity. It also forces the designer to take a better look at default behavior and hopefully start coding it out (or coding it in) to have well thought out alignment and contrast, which makes cross-browser compatibility a little easier to achieve.

    As you go, you will probably find that you need a div here and there to help represent a certain aspect of your design. For example, I like my designs centered on the page. In HTML 4, the best way to do this is a div that has margin: auto wrapped around all the content (though in real XHTML, the html and body elements can be used to achieve the same ends with no extra markup).

    So, add extra divs when you absolutely need them, and make sure to either code in or code out default styles. Be creative, though. It’s your job. Usually the easiest solution is not the best.

  5. Make Sure It Is Accessible

    A pretty design is useless if it isn’t a good design. Good designs are accessible to the most number of people possible. So, audit your site and make sure there aren’t any serious accessibility problems. Make sure images have meaningful alt tags, form elements have labels, etc. Don’t forget niceties like skip to content links. This section really deserves an article of its own. So, I won’t go into much detail.

    Since I’m on a Mac, I’ve familiarized myself with browsing web sites with VoiceOver. While it isn’t as good as the other web screen readers, it helps me get an understanding of what the page might be like. I highly suggest this (or some similar testing) be part of the audit if you have access.

  6. Debug for Internet Explorer

    Internet Explorer 7 was supposed to bring in a new age of standards compatibility. It didn’t. Even if it did, use of Internet Explorer 6 is still rampant. In the old days, stylesheet hacks were the way to account for differences in browser rendering (fighting bugs with bugs). Now, though, Internet Explorer has a proprietary concept called conditional comments.

    This is the first proprietary HTML concept Microsoft has created that is worth a damn. Conditional comments allows the designer to hide or show page content in Internet Explorer based on variables such as browser name or browser version. So, we create a conditional comment to show our Internet Explorer bug fix stylesheet only to Internet Explorer (e.g. <!--[if lte IE 6.0]> <link rel="stylesheet" type="text/css" href="ie_fixes.css"> <![endif]-->). No hacks needed.

    Work in Internet Explorer to clear up any layout issues by overwriting your real stylesheet values. So, if you had a fieldset{border: 1px dotted gray;} in your real styesheet, which causes weird results in Internet Explorer, you can change it by adding fieldset{border: 1px solid gray;} in your Internet Explorer stylesheet. Don’t get bent out of shape if things aren’t one-for-one the same. Sometimes a reasonable likeness is as good as you can get.

  7. Show It To The Client

    By now you have a semantic document custom tailored to your client’s content that is usable, accessible, and hopefully aesthetically pleasing. You can now show it to the client. Since you had the forethought to use web standards, you can make changes to every page at once via the few stylesheets you created. It will save you time and your client money. Since the code is semantic, search engines can better understand the content and index it properly, which may lead to increased revenue for your client. Everyone wins.

Ajax vs Specific Accessibility vs General Accessibility

Monday, October 23rd, 2006

I was reading Rob Cherny’s article Accessible Ajax, A Basic Hijax Example and started thinking a little more about accessibility. Cherney claims that this hijax method, using unobtrusive JavaScript to make a form submit with Ajax instead of traditional POSTing when Ajax is available, is more accessible. While I think it is more accessible than only using Ajax, it is only more accessible for generic alternative browsers; it isn’t any more accessible for disabled people.

Apparently the term hijax that was used in Cherny’s article was coined by a guy named Jeremy Keith. I don’t think the term was really needed as the concept of unobtrusive JavaScript pretty much sums up the idea of hijax. I’ve inadvertently been using hijax since May, however. So, I have some opinions on it.

Web accessibility is a big beast with two opposing heads. The original term accessible meant that the site was designed such that people with disabilities could use the site. Recently, the term has changed to include people with or without disabilities that browse from alternative devices. By alternative I mean mobile phones, ultra-mobile PCs, screen readers, and the like. These alternatives often lack the typical mouse-based interface of desktops, JavaScript support, cascading stylesheet support, or even HTML support. So, one head of the beast is accessible-for-disabled-persons and the other is accessible-for-alternate-devices.

I personally prefer the inclusiveness of the second head when I talk about accessibility. However, the caveat is that saying something is accessible to some facet of alternative browsers may not make it accessible to the disabled. If you aren’t specific about what you are trying to be accessible to, you end up confusing people (see my comment).

Cherny’s article elegantly addresses a facet of the second head. The form degrades gracefully. Unobtrusive JavaScript is designed this way: create a normal web page, then spice it up with JavaScript to improve the existing functionality. So, for Ajax forms, it is a three step process that might go as follows:

  1. Create a form that works by POST.
  2. If JavaScript is available, unobtrusively add support for validation.
  3. If Ajax is available, unobtrusively add support for Ajax.

If there is no JavaScript, the form will post normally. If there is no Ajax, the user gets error correction and the page posts normally. If there is Ajax, the user gets error correction and doesn’t have to wait for a page load. Whatever the case, the form is submitted and no alternative browser is left out.

However, there are still problems with Ajax and the first head of accessibility. I’m going to focus on screenreaders, as people with motor disabilities or deafness still have random access to the page (they aren’t limited to linearly reading the page). I will say this, though, in reference to the deaf and those with motor disabilities: the form itself must be accessible, using labels and accesskeys, or it’s still not fully accessible. Screenreaders, at this point, are still no good with dynamic page updates, which are a mainstay of Ajax. Some aren’t even good with alerts. Of all the available solutions to the problem of updating content dynamically, none of them work across the board. The only way to accessibly do dynamic content updates is to give the user another option.

Since I was aware of this problem when I redesigned my site, I built in a link to turn off Ajax above every form that uses Ajax. The Ajax is unobtrusive, or hijax if you prefer. This was the only method I could think of to allow full access to my forms. Until screenreaders catch up to the technology, the best Ajax accessibility may be no Ajax at all. So, let the user opt out if he wants.

JSON, An Alternative to XML in AJAX

Tuesday, July 18th, 2006

I admit it. I like Ajax. Sure it’s a dumb buzzword. But, as you’ll recall, in How To Make an Ajax Chat Room, I said something like, It just turns out XML is slightly more usable for complex stuff and that synchronous requests defeat the point. Though Ajat have many uses. The point I was trying to make is that sometimes sending text back instead of XML is nice. For example, I can send back a 1 if the action was successful. But sometimes that isn’t enough. Sometimes, text and XML are both the wrong tools for the job. That’s where JSON comes in.

The Problem With XML

The problem with XML is that it is a bitch to work with. XML files can get big if the file uses meaningful metadata. To boot, they are a pain in the ass to create when all you really want to do is send some simple data that is too complex for regular text. Then, when it comes time to use the XML in JavaScript, one has to do lots of DOM stuff just to get to the data.

Since I don’t do much PHP work, I don’t have to deal with the creation of the XML files. I do, however, have to access the data from the DOM. I got so irritated by it, that I wrote a function in my Ajax class that will convert simple XML files in to Javascript associative arrays. It turns out I was taking an unneeded step.

The Problem With Text

As I mentioned, sending text back is often useful. Since XMLHttpRequest is smart enough to recognize the content type of the returned code, I often send back errors as text and do something similar to this to display the error: if(!ajax_obj.responseXML){alert(ajax_obj.responseText);}. Sometimes, however, I return 1 to alert success and a string error message to give an error. While I’ve made this standard practice, it can get confusing when different Ajax requests get different styles of messages returned.

Additionally, making things more complex, sometimes sending a single raw value back doesn’t require an XML wrapper. For the sake of speeding up the request, the value is sent as text. This mucks with the paradigm I mentioned before.

JSON

XML is nice for documents. It’s a pain to work with as a data exchange format. Text is simpler, but can be inconsistent, often not providing enough useful data. That is where JSON picks up.

JSON, short for JavaScript Object Notation, is exactly what it says it is. It is the syntax used to create objects in JavaScript (and apparently Python, too). If you are curious, it would look like this in Javascript:

1
2
my_object = {"item1": "value", "item2": "value"};
document.write(my_object["item1"]); // Outputs "value"

You can nest objects inside objects, too.

Using JSON Instead of XML

Outputting XML from PHP is straight forward. JSON is similarly straight forward. The PHP script simply dumps out text similar to the object literal notation shown above (without the variable assignment). The request will be stored in the .responseText

When an XMLHttpRequest is sent to the server and XML is received, the XML is automagically parsed into a variable as a DOM object. JSON requires an extra step to assign the JSON object to a variable that you can use in your script.

1
my_object =  eval("("+request_object.responseText+")");

It’s pretty easy. If integrated into a class, the eval could be done on-the-fly.

Freddy — I mean, XML vs JSON

I’m still a JSON newb. I’ve done a pretty good deal of Ajax work, though. I’ve seen some very irritating stuff. For example, when fetching a few hundred records in XML format, the file can get large and cause the browser to freeze while the XML is parsed. Since JSON would be no different from executing Javascript code, it should avoid the crawl.

Unless XML tags are really light weight (which defeats the whole metadata concept of XML), the files can get really big. JSON doesn’t need as much tagging, so file sizes can be smaller.

XML is pretty simple to write. JSON is pretty simple to write. XML must be well-formed. JSON must be syntactically correct. JSON just happens to require less typing than XML.

I’m throwing this bonus in, even though it isn’t specific to Javascript: Not all languages have nice support for XML. PHP 4, for example, will do XML; it is just really hard. There are quite a few JSON interpreters for various languages and JavaScript and Python have it built-in. With XML, one has to learn how to use the XML library. With JSON, all one needs to know is how to work with normal objects in that language. Specifically with Javascript, you don’t need to learn DOM scripting to work with JSON. You just need to know how to use associative arrays.

Real World Testing

I did a simple test. I wrote a PHP file that creates an XML file with 300 values and a JSON file with 300 values. I later modified the loop to 1000 values to see if an article I read was true about Ajax breaking down exponentially. It’s basically true, by the way.

To be fair, I had already written the code, then modified it to run on JSON. For that to work, I had to make the JSON output match what would show after my XML file was turned into an object. The XML file was already optimized to be very small. So, while that might give some size overhead to my JSON (since it had to mimmic nodes), it also gives some parsing overhead to my Ajax (since it was converted to an object before use). What I mean is that the code I used could be more efficient (and I might re-write it eventually).

The Javascript reads the XML or JSON file. It uses the information to populate a select. I uploaded it to a server across the country from where I am and I ran the files. The server gets spikes of heavy use, so the results may be skewed.

At 300 records, I couldn’t really tell a difference between the JSON and the AJAX. Early tests at 1000 records, it was debatable. JSON was at least as fast as XML (usually around 7 seconds from refresh until was complete). Some requests were far faster on JSON (2 seconds instead of 7). Later tests revealed a much larger variation, with XML taking 40 seconds and JSON taking only 15.

The Golden Fleece

I like JSON for what it is. It’s very capable and much lighter than XML, both in terms of parsing and in terms of file size. It is a capable alternative to XML and has quite a few undeniable upsides. I’ll probably do further testing before rewriting all my legacy code, but I will be using JSON in the future.

Mozilla JavaScript RegExp Test Bug

Tuesday, July 5th, 2005

There is what some consider to be a bug in Mozilla’s JavaScript engine. Basically, if you run a regular expression with a global switch (e.g. /x/g), JavaScript remembers the last match position. This causes the RegExp to sometimes validate as true, and sometimes as false (alternatingly). The Mozilla guys say it isn’t a bug. However, removing the /g solves the problem.