Few days ago I decided to look into an issue that was reported on our forum. Basically the form validation in CMC was not working on Safari. The whole thing was very strange because we are using the Joomla! js classes to validate the form before submitting, so there was no reason why all this would not work. As I looked into the code I discovered things that I never knew & thought that it is a good idea to share them with other developers.
Since the Joomla! 1.5 days developers were able to use JHtml::_('behavior.formvalidation'); if they want to validate their forms with javascript before submitting. On Joomla 3.3 the formvalidation function looks like this.
public static function formvalidation()
{
// Only load once
if (isset(static::$loaded[__METHOD__]))
{
return;
}
// Include MooTools framework
static::framework();
// Include jQuery Framework
JHtml::_('jquery.framework');
// Add validate.js language strings
JText::script('JLIB_FORM_FIELD_INVALID');
JHtml::_('script', 'system/punycode.js', false, true);
JHtml::_('script', 'system/validate.js', false, true);
static::$loaded[__METHOD__] = true;
}
The function makes sure that it only gets executed once and the important lines are:
// Include MooTools framework
static::framework();
// Include jQuery Framework
JHtml::_('jquery.framework');
// Add validate.js language strings
JText::script('JLIB_FORM_FIELD_INVALID');
JHtml::_('script', 'system/punycode.js', false, true);
JHtml::_('script', 'system/validate.js', false, true);
It first loads Mootools, then it loads jQuery, then it ads some language strings to the page, then it loads punycode and finaly it loads validate.js .
The validate.js file contains a class JFormValidate, which on joomla 2.5 was a Mootools class and now on Joomla 3.3 is a plain javascript class. JFormValidate class gets auto-initialized on dom ready. It looks for forms that have a class "form-validate". Since I always added this class to my forms, I thought that I had done my part. And in fact the validation of CMC seemed to work just fine. Whenever a user hits the submit button -> a non-validated field was made red and friendly text was letting the user know that he hasn't filled this field. This worked perfect on FF, Chrome, IE10, but it failed miserably on Safari. Why is that?
Upon further examination of the JFormValidate class I discovered, that I never actually used this class properly. The class was attaching validation to the blur event on each input field (which was working fine), and it was also running validation whenever a user clicks the submit button. But for this to work, the submit button had to have type="submit" & I never actually added such type to my submit buttons. So why the heck was this working then? Well, it was not....
I found out that since I was using JForm, nearly each input field was calling this code:
// Including fallback code for HTML5 non supported browsers.
JHtml::_('jquery.framework');
JHtml::_('script', 'system/html5fallback.js', false, true);
The first line loads jquery, the second line loads a htm5fallback script. And this script was the reason why my form was validated! It was looking for forms on the page and it was attaching a validate function to the "submit" event. Unfortunately HTML5 validation doesn't work on Safari and iOS & it seems that the html5fallback script was not helping here either.
So, if you want to really use JFormValidation, then make sure that your buttons have type="submit" otherwise on Joomla 3.3 you'll use the HTML5 form validation (on previous versions of Joomla! your forms are most probably going to be submitted without validation). If we are going to use HTML5 form validation, do we really need the JFormValidation class anyway?
Also, don't you think that JForm should have a flag that would let you decide if you want to load jquery and html5fallback.js? There are 100 of validation scripts out there, why force one on the developer? Let him decide if he wants to use what is provided with Joomla or something else.
If we are going to use HTML5 form validation, we would need to make sure that it works in Safari. I actually found an issue report about this over here. Maybe something that we could fix on the Piza, Bugs and fun event on the 17th of October!