PDA

View Full Version : Default behavior if JS fails (for example, lightbox)



djr33
05-03-2010, 05:40 PM
I'm building a webapp that opens a 'window' when you click on the image representing a user. It'll use ajax to get information from the database and display a profile.
Lightbox or something similar would be useful.

After browsing a bit I found this:
http://particletree.com/features/lightbox-gone-wild/

I don't have any preference at the moment for what I use, just that it's easy to implement and uses ajax to load rather than having to preload everything.


So on to the important question:

I know that if you use either event="return function();" or event="function(); return false;" then the original 'action' won't fire.

So if I have:
<a href="..." onclick="return function(this.href);">...</a>
Then that will work:
1. If Javascript is enabled and function() runs smoothly, it will use that and not go to the link.
2. If Javascript is not enabled or function() doesn't work (isn't compatible), then the link will activate.

That's simple enough and easy to work with.

But what happens when you have a much more complicated system with something like Ajax and lightbox where there are multiple elements that can fail?

It will be nice to not load a new page for most users, but it won't be a major problem if those without JS or limited JS must load a new page. That's the desired result.

The problem I'm worried about, though, is people who have limited JS and then do not get lightbox/ajax to work and see nothing AND then don't load the link.


So in summary:
For this script and in general, is it possible that something will go wrong and the JS will fail to properly execute but the original action will still be cancelled?

jscheuer1
05-03-2010, 06:19 PM
Yes. The only way to guarantee that it will still fire the link is to create a chain of the return value all the way through to the very end. In something like that, it would be virtually impossible to trace every possible twist and turn and make sure that each function returns the next or the appropriate value at the point depending upon what's happened so far.

If all the code you are using is well written, it should do a lot of that for you automatically, but it is rare to see code like that. Sometimes, like with AJAX, the return value could happen too late to be of use in determining whether or not the original link should fire anyway. If the href could be passed along chain it could be fired via javascript at some point. Another consideration is that even if the code is well written, the author can't know your intention, so what value should be returned at any given point may differ.

Generally, you should have the big things covered. Like if the browser doesn't support AJAX, get that and fire the link.

djr33
05-03-2010, 07:19 PM
This is why I'm confused. Basically my intention is that the script "works" and displays something. If something odd goes wrong like the server I'm grabbing it from is down or the page doesn't exist, I don't really mind. But the idea is that for every browser either the JS+ajax load the link or the link itself loads the link. I don't want any browsers (by default without any other complicating circumstances) to load nothing.
Is there a way to help to make this not happen?

One of the main problems here is that it is very difficult to test. The situations where it wouldn't work are rare and hard to predict. So aside from just guessing and seeing that it seems to default to the link in a few cases, I feel like it would be very difficult to see if the 'backup' method is really working unless of course Javascript is simply disabled (and ignored).


Generally, you should have the big things covered.Do you mean that I must do this myself or that in general these things 'should' already be covered by default?


Basically, is this something to worry about or am I ok for now at least just assuming everyone can see the content one way or another?



I suppose a more concrete definition of what I want is that if a certain function or method does not exist in a browser, then I want the link to fire. For example, if no ajax functions exist in a browser, then that should make the whole thing fail. If all of the functions exist and it "should" work but doesn't, then I consider that bad coding and another issue entirely.

Is there a way to ensure that if any crucial component (like ajax) is not recognized by the JS parser that the script will default to the normal action?

jscheuer1
05-03-2010, 08:56 PM
Any good AJAX routine has an else in it somewhere that dumps out to an alert or something if there is no AJAX support, or at least none of the kind that the script uses. Some have a fail property that can be configured, usually at least to a fail callback function. If the AJAX routine has none of that, it almost always could be fairly easily modified to have. If the URL passed to the routine is the same as the link you want fired, you don't need to have the return value trace all the way back to the link. You can just edit the fail part of the routine to load the URL normally:


} else {
location=url;
}

Unfortunately, looking over lightbox gone wild, I see it uses prototype 1.4.0 - a rather outdated version. As far as I can see, its AJAX routine is not well documented. It does appear to have a failure property, I'm just not sure how to access it. If you can find documentation on that version of prototype and it does have a failure property, you can use it here (in lbgw's lightbox.js):


// Begin Ajax request based off of the href of the clicked linked
loadInfo: function() {
var myAjax = new Ajax.Request(
this.content,
{method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this)}
);

},


Oh, I just found one (Prototype 1.4.0 Developer's PDF):

http://www.sergiopereira.com/articles/DeveloperNotes-Prototype-JS.pdf

jscheuer1
05-03-2010, 11:25 PM
I'm looking at the documentation and it appears it has an onFailure property. With luck (an educated guess looking at the examples), one could hopefully do (addition highlighted to lbgw's lightbox.js):


// Begin Ajax request based off of the href of the clicked linked
loadInfo: function() {
var myAjax = new Ajax.Request(
this.content,
{method: 'post', parameters: "", onComplete: this.processInfo.bindAsEventListener(this), onFailure: function(request){location = request.url;}}
);

},

The onFailure property can be set to a function. It has two parameters, the first is the request (which I'm using) and the second is the responseHeader (which I am not). The request I believe has a property - url - which is the url requested. If I've got all that right, you're in business.

djr33
05-04-2010, 12:10 AM
Thanks, John.
I'm not positive that script will fit exactly into what I'm doing, but it's good to understand a bit about how this is supposed to work at least.
I will try to implement that once I get the whole system going.
One reason the JS I'm using is a bit limited is that I will be generating all of this through PHP and then finally dealing with the Javascript as a byproduct of that.
But it looks like I'm definitely on the right path now.

Do you by chance have a suggestion of a good script that will display a window in the middle of the page (with or without an overlay on the background-- I don't really care) that can then load ajax content into the div? I could mix two scripts, but maybe there's one out there that is good.

Of course that's assuming there's something wrong with the script we're talking about above.

You know more than I do about all of this, so let me know if you have any suggestions/pointers.

jscheuer1
05-04-2010, 03:10 AM
One that looks promising to me is the DD featured Facebox (third party contributed):

http://www.dynamicdrive.com/dynamicindex4/facebox/index.htm

I've worked with it, it's not perfect - none of these box scripts are. But it is jQuery based. Of all the libraries out there, jQuery is the leanest and meanest IMO. It (jQuery) does AJAX and Facebox takes advantage of that in that one of its 'fetching modes' is via a jQuery based AJAX call. If it isn't already suitable for your purposes (the AJAX part) it probably can easily be made so, and there is ample clear documentation on jQuery AJAX routines. No overlay with Facebox though.

I should also mention that - on your question about those rare occurrences when a browser just can't handle the code - they are that, rare. It's not like PHP where either the server is configured for the code or it isn't and all that's usually required is to tweak either the server and/or the code. But subroutines/branches can often be added to javascript to handle many of these rare instances. Authors often ignore these opportunities though. However, there are browsers, particularly what are known as 'version 4' (NS 4, IE 4) that are so outdated that it is virtually impossible to accommodate them without extreme measures and/or an overall dumbing down of the javascript and HTML used. Google is (or at least was) a fairly good example of this. It's very simple looking. But I'm not sure if even it could fly in version 4 browsers these days.

djr33
05-04-2010, 04:37 AM
That makes a lot of sense. I guess the main thing I'd worry about is browsers that don't have ajax since that's not so common even in the reasonably modern browsers. But beyond that I guess everything is pretty reliable.
I don't care about IE5 even... as long as everything 6+ is working, I'm happy.

The other thing to think about now is mobile devices and limited-distribution browsers. But since they're catching up fast (like full safari on the iphone), that's probably going to work itself out.