Wednesday, May 11, 2005

Lessons Learned #5: Cross-browser Javascript and CSS

Unlike previous "Lessons Learned" articles this one will describe my current project and list some of the little annoyances that I have had to solve. I mentioned in my last post that this project was to build a web based administration system for Open Harmonise that mirrored the Java Swing version as closely as possible. Obviously the Java Swing version was pretty dynamic in nature so this project was going to require a lot of Javascript and funky CSS which would have to work in both of our target browsers (Internet Explorer and Mozilla/Firefox).

I have to admit, that when starting out I really did not think the project would be successful. The Java Swing version of the client includes many custom components to allow the management of complex information. The layout includes Outlook style tabs, a highly customised table view and a tabbed form that is built on the fly from data definitions. These form elements are not simple either, for example a text field is made up of the following components;

  • text of the field name.
  • button to open a help text window.
  • valid/invalid icon (updated in real time, also impacting a similar icon on the tab).
  • the text entry field itself.
  • a counter which counts down how many characters you have left based on the data definition. This counter turns amber when you get close to the maximum length and red when you go over it.
That is just one of the simple types of form field, we also support number (with or without floating point), date (with or without time) and boolean. Then there are the complex types including vocabulary lookups, relationships to other resources in the CMS and finally compound properties (nested fields like address). Each field in the form can have a min and max number of occurrences and therefore needs to have plus and minus buttons for adding and removing extra fields.

I have ranted on a bit, but you can see why I was a little worried about building this and supporting it in html's request response model. But this was my task so I forged on. Overall it has been nice to discover that building these types of web application is a lot easier now than in days gone by. The latest versions of IE and Firefox interoperate quite well, but there have been many points where I have had to stop and scratch my head for a while. The following are my experiences and solutions, if for any of these you know that I am just being stupid and that there are much easier ways of doing these then please leave a comment.

1) Dynamically adding dynamic content.

Problem;

There are several approaches to adding content to a html page, the easiest of these is to append to the "innerHTML" attribute of an element. In Internet Explorer this doesn't work for forms as any information people have already input to form elements will be lost. Instead you must construct your new elements as html DOM objects and use the "appendChild" method. While this works fine for simple things life becomes complex in Internet Explorer with some special (for want of another word) attributes. These attributes include;

  • name on form elements
  • value on form elements
  • class
  • name on iframes
  • all Javascript event handlers such as onchange and onclick
The problem with these is that Internet Explorer treats them as plain DOM attributes and does not do the special processing that each requires. The worst offender for these is the Javascript event handlers, they are not parsed by the Javascript engine so they are not actually set as listeners to the events.

Solution;

For most of these it is a simple mater of using the relevant Javascript attribute for the object, such as doing;

element.name='NAME' ;

instead of;

element.setAttribute('name', 'NAME');

However things get a little more complex where the Javascript event handlers are concerned. For these you must again set the relevant Javascript attribute for the object, but you must set it to the method pointer rather than a string. E.g.

inputElement.onchange = elementChangeMethod;

instead of;

inputElement.setAttribute('onchange', 'elementChangeMethod(PARAM1, PARAM2)');

One thing that should be obvious from this is that when having to use the method pointer you cannot provide any parameters to the method. When mocking the interface up in static HTML I was mostly passing "this" into these methods, which is still accessible, but not as a parameter, from a method called using the method pointer. So the rule is to remember that if you are going have to insert a new version of some html that has Javascript event attributes on it, ensure that those methods only deal with the "this" context object and use no other parameters.

2) & in links and window.location

Problem;

Because this is a very dynamic html web application there are many points where I use Javascript to either load a page into a frame/main window or insert an IFRAME in the page. Something that foxed me for quite a while was the fact that "window.location.replace" was working in IE but not in Firefox (and that Firefox was not showing any errors), I would just get a blank page.

Solution;

The solution was embarrassingly simple, but not obvious at all. IE allows you to put "& amp" into the URL for "window.location.replace" and Firefox does not. Mostly this is hard to spot as Firefox doesn't complain, it just shows a blank page.

3) Submitting a form and using window.location

Problem;

I replicated the Java Swing toolbar as a series of buttons in a frame across the top of the page. These submit various forms in other frames to accomplish their tasks. These forms may be visible to the user, for example the "Save Resource" button submits the main visible data entry form. Some are not, the "New Resource" button submits a hidden form. To keep life simple, these forms submit to a page that performs the action and then I redirect the frame back to the previous page which is now in a new state because of the action. However the changes were not happening.

Solution;

After quite a while of fiddling it appeared that the "window.location.replace" was happening before the "form.submit" commands in the Javascript, even though they were in the other order in the source. The evil hacky solution was to put the "window.location.replace" into a delay of a second to allow the "form.submit" to happen, truly horrible but it does work.

4) Comparing the value of a html DOM attribute to a string

Problem;

In many places I am allowing the user to move values from a list into a "select" field. The field has the "multiple" attribute set to "true" so that it appears as a list instead of a drop down, but I want everything in it to be submitted. So I wrote a small Javascript function to find all the elements with a tag name of "SELECT" and a "multiple" attribute with a value of "true". This is a very simple DOM navigating script, so imagine my surprise when it found the elements with the right name but would never match on the attribute value.

Solution;

The html DOM method "getAttribute('ATT_NAME')" returns a "DOMString" object not a "String" object, therefore you cannot do a simple comparison. In the end I did the following;

var attrubuteValue = element.getAttribute('ATT_NAME');
var sValue = '' + attrubuteValue;
if(sValue == 'STRING_TO_COMPARE') {
...
}

I am guessing that I could have compared against the DOMString's "toString()" method, but I was a bit fecked off by the time I thought of that and so haven't gone back in to fix it. But you get the idea. Again, no warnings or errors to be seen.

5) Dynamically inserted IFrame not findable by name

Problem;

Inserting an "IFRAME" element using Javascript works fine, until you come to try and find it by its' name in the "frames[]" array. The name doesn't appear to be available.

Solution;

Another bit of a hack, I found it by comparing the location instead.

Conclusion

So those were the most annoying issues, and the ones that I can remember while writing this. Although these did cause me major headaches, again I must say that the process of building this site has not been anywhere near as bad as I thought it would be. There is a resurgence in the art of building web "applications" instead of websites. Most of this has been the interest surrounding Google's efforts in this area and the fantastic results that can be gained from using asynchronous calls with XMLHttpRequest objects. Of course I would have loved to build this site in that way, but it was a bit too much of a risk given the time and budget allowed. Still I did create the layout structure to allow us to begin replacing various parts in this way over time.

Finally, please to do let me know if I am wrong in anything I have said here. I really do want to find the best way of fixing these issues, and I must thank the Mozilla/Firefox teams for supporting all the non-standard IE ways of doing things so that I could build truly cross-browser Javascript.

16 comments:

Anonymous said...


[url=http://www.homebasedbusinessprogram.com/profiles/blogs/modules-pour-hommes-et-dames][b]sac longchamp[/b][/url]
[url=http://shenenmaoyis.webnode.cn/][b]sac longchamp[/b][/url]
[url=http://shenenmaoyi.publr.com/][b]sac longchamp[/b][/url]
[url=http://shensacens.hpage.com/][b]sac longchamp[/b][/url]
[url=http://shenenmaoyis.sosblogs.com/The-first-blog-b1/Fossil-Winslet-II-Sac-besace-transformable-recemment-revele-b1-p1.htm][b]sac longchamp[/b][/url]

Anonymous said...


[url=http://proyectok.com/blogs/viewstory/56489][b]Cheap NHL Jerseys[/b][/url]
[url=http://wikimommy.com/index.php?title=Few-Secrets-To-Simplify-michael-kors-outlet][b]michael kors outlet[/b][/url]
[url=http://hrpedia.ru/index.php?title=A-Number-Of-Tips-To-Make-Ease-Of-michael-kors-outlet][b]michael kors outlet[/b][/url]
[url=http://abilipedia.com/w/index.php/index.php?title=Funny-But-Nonetheless-][b]Cheap NHL Jerseys[/b][/url]
[url=http://marysdiary.net/mw/index.php?title=A-Handful-Of-Guidelines-To-Simplify-michael-kors-outlet][b]michael kors outlet[/b][/url]

Anonymous said...

if you are having a hard time finding some free psn codes
then you need to go to [url=http://psngenerator.info]Psn Generator[/url]

Anonymous said...

Somebody essentially help to make seriously posts I would state.
That is the first time I frequented your web page and to this point?
I amazed with the research you made to make this particular submit incredible.
Great job!

my webpage ... dave sandler

Coach Factory said...

michael kors, true religion jeans, nike air max, air max, louboutin, nike air max, polo ralph lauren outlet, oakley sunglasses, prada outlet, ray ban sunglasses, louboutin, prada handbags, longchamp handbags, chanel handbags, oakley sunglasses, michael kors outlet online, true religion, michael kors handbags clearance, coach purses, toms shoes, coach factory, ray ban, louis vuitton outlet online, gucci outlet, michael kors, ray ban sunglasses, jordan shoes, tory burch outlet, burberry outlet online, coach outlet store, true religion outlet, nike shoes, michael kors outlet, nike free, michael kors outlet online, oakley sunglasses, kate spade handbags, louis vuitton handbags, kate spade outlet, longchamp outlet, air max, coach outlet, polo ralph lauren outlet, tiffany and co, cheap michael kors

Coach Factory said...

hollister, marc jacobs, nfl jerseys, abercrombie and fitch, north face jackets, lululemon, vans, giuseppe zanotti, yoga pants, timberland, birkin bag, ray ban pas cher, hermes, nike air max, hollister, beats by dre, ferragamo shoes, new balance shoes, air jordan, babyliss pro, mont blanc, mulberry, nike roshe run, mcm handbags, nike free, louis vuitton, michael kors, longchamp, air max, oakley pas cher, ralph lauren, wedding dresses, louis vuitton, ralph lauren, karen millen, hogan, instyler ionic styler, lancel, supra shoes, juicy couture outlet, louboutin, rolex watches, burberry, reebok outlet, nike free, converse shoes, juicy couture outlet, louis vuitton, montre pas cher, north face outlet

Coach Factory said...

oakley sunglasses outlet, canada goose, oakley vault, asics gel, ghd, oakley sunglasses outlet, canada goose outlet, moncler outlet, cheap oakley sunglasses, moncler, moncler, oakley outlet, valentino shoes, ralph lauren, oakley sunglasses cheap, cheap sunglasses, oakley vault, ugg boots, soccer jerseys, ugg boots, cheap sunglasses, jimmy choo, ugg boots, ray ban, insanity, canada goose, louboutin, oakley vault, soccer shoes, herve leger, canada goose outlet, oakley sunglasses cheap, oakley sunglasses outlet, bottega veneta, p90x3, gucci, cheap oakley sunglasses, canada goose, ugg, moncler, canada goose, cheap oakley sunglasses, chi flat iron, celine handbags, oakley, tn pas cher, oakley outlet, cheap sunglasses, oakley sunglasses cheap

mao qiuyun said...

juicy couture outlet
soccer jerseys
ralph lauren outlet
hermes bags, http://www.hermesbags.co.uk/
christian louboutin outlet
louis vuitton bags, http://www.louisvuittonbag.us.com/
louis vuitton handbags
cheap nfl jerseys, http://www.cheap-nfljersey.us.com/
fitflop shoes
ugg boots, http://www.uggbootsclearance.in.net
oakley sunglasses wholesale, http://www.oakleysunglasseswholesale.in.net
michael kors uk
michael kors outlet
the north face clearance
manchester united jersey
iphone 6 cases
pandora
michael kors uk
rolex watches
coach outlet store, http://www.coachoutletstoreonline.in.net/
giuseppe zanotti outlet
converse all star
lululemon
air max 2015
mcm handbags
michael kors factory outlet, http://www.michaelkorsfactoryoutlets.in.net/
michael kors factory outlet, http://www.michaelkorsfactoryoutletonline.com
cheap soccer jerseys
true religion jeans, http://www.truereligionoutletstore.us.com
abercrombie
tory burch shoes
hermes birkin
coach outlet
tory burch outlet online
oakley sunglasses
0910maoqiuyun

Wenhao Guo said...

air jordan 11 free shipping
nike air max 90
swarovski outlet
michael kors online outlet
nike running shoes
baltimore ravens
winter jackets outlet
san antonio spurs
cheap uggs
iphone cases
chicago bulls
coach outlet store
ugg outlet
true religion jeans,cheap true religion jeans,true religion jeans wholesale,true religion outlet,true religion sale,true religion outlet online
cheap oakley sunglasses
mizuno shoes
uggs outlet
replica handbags
kobe bryants shoes 2015
ghd hair straighteners
michael kors outlet store
new balance sale
rolex watches
true religion jeans
michael kors handbags clearance
tods shoes,tods shoes sale,tods sale,tods outlet online,tods outlet store,tods factory outlet
coach outlet online
hermes outlet online
chanel handbags
ugg boots
michael kors outlet online
mulberry outlet online
ddddd1110

dong dong23 said...

mont blanc
tory burch outlet
michael kors handbags
louis vuitton handbags
nike roshe runs
michael kors outlet
louis vuitton outlet
christian louboutin sale
nike uk
true religion outlet
fitflops sale clearance
michael kors
coach outlet
hollister clothing store
adidas originals
nike basketball shoes
michael kors handbags
michael kors outlet clearance
coach outlet store online
michael kors bags
louis vuitton outlet
jordan 3 infrared
jordans
nike air max
true religion jeans
air jordan 13
louis vuitton outlet
michael kors outlet
louis vuitton outlet
ugg boots
coach outlet
true religion shorts
celine
kate spade
christian louboutin shoes
cheap oakleys
jordan 6
jordan shoes
louis vuitton outlet
oakley vault
20164.22wengdongdong

Meiqing Xu said...

coach outlet online
coach outlet store
asics shoes
oakley sunglasses
ray ban sunglasses
uggs
adidas nmd
babyliss flat iron
canada goose parka
lacoste shoes
true religion jeans
ghd flat iron
discount oakley sunglasses
michael kors handbags
michael kors handbags
cheap jerseys wholesale
under armour outlet
adidas supercolor
cheap oakley sunglasses
fitflops shoes
nike air max 95
coach outlet online
longchamp
canada goose jackets
fitflops outlet
nike cortez shoes
adidas nmd
michael kors bags
white converse
louboutin uk
hermes outlet
cheap nhl jerseys
vans outlet
ray ban sunglasses
michael kors handbags
air max
zhuo20160714

dong dong23 said...

rolex watches
mont blanc pens for sale
moncler paris
nike trainers
coach outlet
true religion outlet
coach outlet
mlb jerseys
uggs outlet
oakley sunglasses
20169.29wengdongdong

raybanoutlet001 said...

boston celtics jersey
michael kors outlet clearance
new england patriots jerseys
air max 90
moncler jackets
valentino shoes
ecco shoes
versace
patriots jerseys
michael kors handbags

chenmeinv0 said...

louboutin outlet
cheap rolex watches
canada goose outlet
burberry scarf
spurs jerseys
ugg boots outlet
michael kors outlet clearance
louis vuitton handbags
uggs sale
gucci outlet online
chenyingying20161130

chenmeinv0 said...

louboutin outlet
cheap rolex watches
canada goose outlet
burberry scarf
spurs jerseys
ugg boots outlet
michael kors outlet clearance
louis vuitton handbags
uggs sale
gucci outlet online
chenyingying20161130

caiyan said...

birkenstocks
nike outlet
christian louboutin uk
rolex watches
fitflops sale
true religion uk
michael kors outlet online
ralph lauren outlet online
nike outlet store
longchamps
0405shizhong