AIAIO: Our Blog

AIAIO: Our Blog

The pulse and reviews of Alexander Interactive

Solving the IE 7, IE 9 Magento & Prototype Validation Bug

UPDATE: Read this first please…

After receiving some comments from fellow web devs [see comments between 10/26 and 11/11], I decided to integrate some of their changes. I’ve also included some enhancements via my colleague, Tom Rosario. They include a couple of updated variables (hopefully eliminating any headaches with the original ‘fieldsFilled’ infinite increment issue) and a regEx that validates the the email field, once (or if) the core validation fails.

For the rest of you…read the original post [below] to gain a little background/perspective and see if this suits your current issue. Feel free to challenge me and post fixes/improvements (We’re all fighting the same [grunt, groan, teeth-gnash] IE-quirks-battle after all ;) I will also be in the process of trying to find inconsistencies and will update accordingly if I find them.

[original post below]

Hey there fellow Magento-ers,

Have you been spending countless hours scouring the internet for a solution to this odd problem, in Magento, where you use the built-in Prototype validation to validate your form and it does not? And by ‘does not [validate]’ I mean that in Internet Explorer 7 AND 9 (of course) it manages to ‘validate’ your empty fields, when attempting to submit an empty form, and then immediately disregards this ‘validation’ and just submits the form anyway….

Annoying, right? Can’t seem to get around it, right?

Well, have no fear! I’ve already ruined my own life, productivity and sanity in order to bring you this very specific and (I think) simple solution. I wrote (with the help of my pal Tom Rosario) a little unobtrusive Class-based function to handle it!

Just to give you some background, and to ensure I’ve been as thorough as possible, I’d like to list the things I’ve already attempted and failed at. This includes both my own solutions and those suggested by experts on the web:

  • Stopping the page from loading via the location and window object: simply doesn’t work
  • Changing the version of prototype: messes up all kinds of things in Magento, namely, checkout…so don’t do it
  • Using jQuery validation: same issue occurs
  • Using the IE 7/IE 8 compatibility meta tag: should work, but I never had success with it

Now that we’ve covered some of my futile attempts, let me tell you what I know worked; putting a good, old-fashioned ‘ onsubmit=”return false” ‘ on the form itself. This, of course, is only half the work. You then need to remove this, once the validation is satisfied and only if all the required fields are filled. In my humble opinion, this is (currently) the best solution because we’re allowing the built-in validation to still do it’s thing, with an extra layer of validation to prevent any unwanted results. The best part of this is that it doesn’t negatively affect functionality in the other browsers (FF, Chrome, Safari), who weren’t experiencing this problem in the first place. [raised eyebrow]

So speaking of that extra layer, the approach is really quite simple; we prevent the form from submitting anything if all the fields with the ‘required’ classes are empty, then remove that constraint once they’re filled/validated. Prototype validation is still able to do it’s thing, and when it’s done, and all other aspects are satisfied, we go ahead and take the ‘return false’ off the form and let it submit. Pretty simple right? I’m surprised myself that it was that easy.

Here’s the Class:

/* FormValidator Fix for IE7 & IE9 */

var ie7 = $j.browser.msie && $j.browser.version=="7.0";
var ie9 = $j.browser.msie && $j.browser.version=="9.0";
var safari =$j.browser.safari;
/*--------------------------------------------------------------------------*/

var FormValidator = function (form, opts) {
	this.form = $j(form);
	this.required = form.find('.required-entry');
	this.defaults = {
		email: form.find('.validate-email')
	};
	this.options = $j.extend({}, this.defaults, opts);
	this.setup();
};
FormValidator.prototype = {
	setup: function () {
		var self = this;

		this.form.submit(function () {
			self.onSubmit();
		});
	},
	validateEmail: function () {
		var emailCheck = this.options.email.val().match(/^([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9,!\#\$%&'\*\+\/=\?\^_`\{\|\}~-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*@([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z0-9-]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*\.(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]){2,})$/i);
		if (emailCheck != null) { return true; }
		else { return false; }
	},
	onSubmit: function () {
		var self = this, numFilled = 0;
		this.required.each(function (idx) {
			if ($j(this).val().length > 0) {
				numFilled++;
			}
		});

		var valid = this.validateEmail() && (numFilled == this.required.length);
		if (valid) {
			this.form.removeAttr('onsubmit');
			this.form.submit();
			return true;
		} else {
		/*uncomment the alert below to test your numFilled variable
		if all is going well it shouldn't increment and match the
		number of required inputs you have*/
		//alert(numFilled);

		}
	}
};

Here’s the Call (put this below your form markup):

<script type="text/javascript">// <![CDATA[
	var contactForm = new VarienForm('myform', true);
if (ie7 || ie9 || safari) {
    $j('#myForm').submit(function(e){
        if ($j('#myForm').find('.required-entry:input[value=""]').length <= 0 ) { this.submit(); }
    });
    new FormValidator( $j('#myForm') );
} else {
    // remove the 'onsubmit' and don't run the function, as all non-IE browsers don't seem to have this bug
    $j('#myForm').removeAttr('onsubmit');
}
// ]]></script>

It’s really that simple kids. Please feel free to add a comment and let me know if this didn’t work for you, or if you’d like to add something.

Technology
  • Pingback: Solving the IE7, IE9 Magento & Prototype Validation Bug - Rubin Shrestha | www.rubin.com.np()

  • Mike LeDoux

    NOTE: For anyone who’s visited this page prior to 10/26/11, I’ve updated the function call, to that it removes the ‘onsubmit’ value for non-IE browsers.

  • Julia

    Sad to say your solution didn’t work for me. I’m not quite sure how this would work anyway with for example onBlur counting self.fieldsFilled endless without setting it back to 0 or something. Also it doesn’t check if there is a validation error in the email-input or stuff. Maybe not important for you but I wasn’t able to put it in your code beside the fact it never really worked in my forms. And last thing, it caused an endless-loop in onSubmit and I couldn’t figure out why actually. Maybe I was just not able to use your code like you did.

    But thank you anyway since your solution waged me in the right direction so I could fix it on my own. Guess I would have been stuck some more hours without getting the idea to use onsubmit=”return false”.

  • Mike LeDoux

    Julia,

    Thanks for letting me know. Was this actually used in combination with the Prototype validation, and what version of Prototype?

    To respond to your comment on the self.fieldsFilled variable. It stops incrementing/iterating once the number of required fields (i.e. inputs with a class of ‘required-entry’) matches the length of those same fields with values. The Email validation is taken care of by the core Prototype validation. There also may be an issue with the ‘self’ variable, as it may clash with an existing varaiable named ‘self’. I’m actually going to update this now.

    As for the submit loop; thank you, I’ll look into it and update accordingly.

    – Mike

  • Julia

    Indeed, prototype validation and protoype version 1.6.0.3.

    self.fieldsFilled never stopped counting for me. Anytime I edited a field or something else it was always +1 and of course using class ‘required-entry’.
    I know that the email validation it self is done by the protoype validation but the form submits as soon as all fields are filled and didn’t check if there was an validation error width. Don’t know if you are able to understand what i mean. Doesn’t want to reload the page for a validation error if the error-msg is also shown width javascript.

  • http://www.customphix.com JamesD

    Had the same issue as Julia.

    Finally came up with a solution that worked for me..

    <script type="text/javascript">
    //<![CDATA[
        var contactForm = new VarienForm('myform', true);
    	if (ie7 || ie9) {
    		$j('#myForm').submit(function(e){
    			if ($j('#myForm').find('.required-entry:input[value=""]').length <= 0 ) { this.submit(); }
    		});
    	    new FormValidator( $j('#myForm') );
    	} else {
    	    // remove the 'onsubmit' and don't run the function, as all non-IE browsers don't seem to have this bug
    		$j('#myForm').removeAttr('onsubmit');
    	}
    //]]>
    </script>
    

    For some reason IE9 chokes when all elements are empty and this circumvents that.

    Hope this helps at least one other person avoid the same headaches.

  • http://www.customphix.com JamesD

    Right after the last post I ran across the same issue on Safari (PC), so I had to add a browser check for safari to fix it as well.

    Just add the safari declaration:

    var ie7 = jQuery.browser.msie && jQuery.browser.version=="7.0";
    var ie9 = jQuery.browser.msie && jQuery.browser.version=="9.0";
    <strong>var safari = jQuery.browser.safari;</strong>
    

    and add the check with the others:

    <script type="text/javascript">
    //<![CDATA[
        var contactForm = new VarienForm('myform', true);
    	if (ie7 || ie9 <strong>|| safari</strong>) {
    		$j('#myForm').submit(function(e){
    			if ($j('#myForm').find('.required-entry:input[value=""]').length <= 0 ) { this.submit(); }
    		});
    	    new FormValidator( $j('#myForm') );
    	} else {
    	    // remove the 'onsubmit' and don't run the function, as all non-IE browsers don't seem to have this bug
    		$j('#myForm').removeAttr('onsubmit');
    	}
    //]]>
    </script>
    

    Note: The Safari I’m suing is an older version (3.1.2), so the newer ones may not need this. Just do a version check like with IE if that’s the case.

  • Mike LeDoux

    JamesD,

    Thanks for playing around with this and finding a solution! I’m going to try this on my end and update the post accordingly.

  • http://www.bigbridge.nl BigBridge

    Great solution….will play around with this.

  • Thomas

    Good writeup – but hasn’t this been fixed in Magento 1.7.x? I just tried to log in to my 1.7.2 site without entering anything in the user and password fields and they were correctly validated as empty – and form not submitted. I tried entering email, hitting submit and password correctly validates as empty. Then removing the email text and entering the password, hitting submit and now the email field correctly validates as empty.
    Or am I way of target here?

  • Maddin

    Hi,
    this seems to work for me pretty well:

    using the onsubmit=’return false’

    plus using Magentos validate() method

    var dataForm = new VarienForm(‘form, false);

    jQuery(‘#form’).submit(function() {
    if(dataForm.validator.validate() === true) {
    this.submit();
    }
    })

  • http://www.apptha.com/category/extension/Magento/out-of-stock-notification Magento Out of Stock Message

    All you need to do is edit your .htaccess file with the following code.

    BrowserMatch MSIE best-standards-support
    Header set X-UA-Compatible IE=8 env=best-standards-support

    This will help you to compatible issues with IE8 with Magento. :)

  • http://tidylink.net/antiinflammatoryfordogsoverthecounter anti inflammatory belly band for dogs petsmart

    Thanks for sharing such a good idea, post is pleasant, thats why i habe read it entirely