How to Use onbeforeunload with Form Submit Buttons

Wednesday, September 23rd, 2009

While doing some programming I came across an interesting predicament. While I understand it’s evil to make it hard for a user to leave a page, I’m not here to argue the merits (or lack thereof) of onbeforeunload.

On a particular form, we are forcing the browser to not cache the information to avoid potential AJAX/JavaScript problems if they should leave the form and come back as browsers don’t all act the same (eg IE leaves checkboxes checked but doesn’t remember changes that have occurred to the page due to JavaScript). As such, we warn our users when they’re about to leave the order form to let them know they’ll need to fill it in again.

The function was simple enough:

window.onbeforeunload = function () {
    return "You are about to leave this order form. You will lose any information...";
}

Unfortunately, this would also be triggered if the user submitted the form which, is obviously not what we want. After searching around on the Internet I came across a simple solution that I thought I would share:

// Create a variable that can be set upon form submission
var submitFormOkay = false;
window.onbeforeunload = function () {
    if (!submitFormOkay) {
        return "You are about to leave this order form. You will lose any information...";
    }
}

Since onclick appears to register before onsubmit when clicking a submit button, we can add a little variable declaration to our submit button so that submitFormOkay will be set to true before the form submission happens:

<input type="submit" id="submit_button" onclick="submitFormOkay = true;">

Problem solved! I hope this post can help others solve the same issue in the future.

If you liked this post, then please consider subscribing to my feed.

PHP Solution for AJAX/XHTML Entities Problem with Chrome and Safari

Monday, March 30th, 2009

If you’re having issues with getting some AJAX to work in Chrome or the newer Safari versions, then I hope this post will hope you.

This issue arose when one of our designers was testing some of the new AJAX I had written in Chrome. It worked fine in Firefox and IE, but Chrome was choking on the XML that was coming back. Treating it as though it were equal to null and alerting the appropriate response that is written in to our AJAX JavaScript. A bit more testing revealed that Safari was also having the issue. Once we figured that out, it became evident that searching for issues with WebKit would help.

Both browsers use the WebKit application framework. Because of this, they both enforce (choke) on XHTML that is given to them which does not follow the standards of XHTML. One of these standards, is that virtually all HTML entities are not valid. Here are the three that are:

&nbsp;
&lt;
&rt;

All other html entities need to be converted to their XML-safe (ASCII) form. So:

&tilde; = &#241;

This can mess up AJAX that works in Internet Explorer and Firefox because they don’t mind dealing with XHTML coming back from an AJAX response with HTML entities. If you’re passing complicated strings with any entities in it through your AJAX requests, don’t expect them to work with any of the browsers using the current WebKit framework.

It took me a while to figure out what was causing the issue that our testers were experiencing, but once we did some searching, we found that others have talked about having this, or a similar problem, too.

We had experienced an issue with foreign characters creating improper RSS feeds for the same reason: html entities showing up when they shouldn’t be. I researched and wrote a function then that would convert all the HTML entities to their numeric format that would be safe. I applied this function to the AJAX responses coming back and presto, it worked.

So, I thought I would share this function with everyone in case someone else was having a similar problem:

function clean_string_for_valid_xml($string) {
    $entities_array = array();
    foreach (get_html_translation_table(HTML_ENTITIES, ENT_QUOTES) as $character => $entity) {
        $entities_array[$entity] = '&#' . ord($character) . ';';
    }
    return str_replace(array_keys($entities_array), $entities_array, $string);
}

Basically, we’re using the get_html_translation_table function to grab all of the entities. Then, we’re using the ord function to get the ASCII value for those entities. Then, we’re returning our string with the entities properly replaced.

Hopefully this works for you, or at least leads you to an answer that works for you.

If you liked this post, then please consider subscribing to my feed.

Javascript – Removing All Select (Drop-Down) Elements from a Page

Monday, May 5th, 2008

The greybox effect that we use for our images in the project that I was working on had a small flaw. Unfortunately, in IE6 (go figure), drop-down menus were showing through whenever a user had expanded the image on the screen.

This was obviously not desirable.

I couldn’t find exactly what I was looking for on the net so I decided to share my snippet of code with everyone out there in case another person was trying to achieve this (or a similar) effect.

Our code uses a toggle for the grey box stuff so we had to make sure one check would be able to take care of all of the select menus on the page:

var dropDowns = document.getElementsByTagName('select');
for (var ii = 0; ii < dropDowns.length; ii++) {
   if (dropDowns[ii].style.display == 'none') {
      dropDowns[ii].style.display = '';
   } else {
      dropDowns[ii].style.display = 'none';
   }
}

This could be used for any type of tag so hopefully others will be able to use this.

Enjoy!