// FluxValidator - Ajax Form Validation for Rails
// Copyright (c) 2007 Peter Gumeson
// Contributors:
//
// FluxValidator is freely distributable under the terms of an MIT license
// Project Home: http://fluxvalidator.googlecode.com
if (typeof Prototype == 'undefined' || parseFloat(Prototype.Version) < 1.5) {
alert('FluxValidator requires the Prototype javascript library version 1.5.0 or greater. ' +
'Check to make sure prototype.js is loaded before flux_validator.js');
}
if (typeof LowPro == 'undefined' || parseFloat(LowPro.Version) < 0.4) {
alert('FluxValidator requires the LowPro javascript library version 0.4 or greater. ' +
'Check to make sure lowpro.js is loaded before flux_validator.js');
}
if (typeof Effect == 'undefined') {
alert('FluxValidator requires the Scriptaculous javascript library. ' +
'Check to make sure effects.js is loaded before flux_validator.js');
}
FluxValidator = {
form: null,
source: null,
Base: {
initialize : function(options) {
this.options = Object.extend({
evaluateScripts: true
}, options || {});
},
makeRequest : function(options) {
if (options.update) new Ajax.Updater(options.update, options.url, options);
else new Ajax.Request(options.url, options);
return false;
}
}
};
// Handle form validation
FluxValidator.Validate = Behavior.create({
onchange : function(e) {
FluxValidator.form = this.element;
FluxValidator.source = Event.element(e).id.replace(/_([0-9]+)i$/, '');
var fieldSpan = $(FluxValidator.source+'_field');
if (fieldSpan != null) {
if (!fieldSpan.hasClassName('fieldWithErrors') &&
!fieldSpan.hasClassName('fieldWithoutErrors')) {
fieldSpan.addClassName('fieldWithoutErrors');
}
}
var errorSpan = $(FluxValidator.source+'_errors');
if (errorSpan != null) {
if (!errorSpan.hasClassName('formErrors')) {
errorSpan.addClassName('formErrors');
errorSpan.setStyle({display: 'none'});
}
}
var errorSpanHtml = '';
var elementType = Event.element(e).type;
if (elementType == 'radio' || elementType == 'checkbox') {
if (errorSpan == null) {
nextSibling = Event.element(e).up().next();
if (elementType == 'checkbox' && nextSibling.type == 'hidden') {
nextSibling = nextSibling.next();
}
if (nextSibling != undefined ) {
if( nextSibling.tagName == 'BR') {
new Insertion.After(nextSibling, errorSpanHtml);
}
else {
new Insertion.Before(nextSibling, errorSpanHtml);
}
}
else {
new Insertion.Bottom(Event.element(e).up(1), errorSpanHtml);
}
}
if (elementType == 'radio') {
radioPrefix = Event.element(e).name.sub(/^([a-zA-Z0-9_]+)\[([a-zA-Z0-9_]+)\]$/, "#{1}_#{2}");
errorSpan = $(radioPrefix+'_errors');
if (errorSpan != null) {
if (!errorSpan.hasClassName('formErrors')) {
errorSpan.addClassName('formErrors');
errorSpan.setStyle({display: 'none'});
}
}
else {
errorSpanHtml = '';
lastRadio = FluxValidator.form.getInputs('radio', Event.element(e).name).last();
nextSibling = lastRadio.up().next('span');
if (nextSibling != undefined) {
new Insertion.Before(nextSibling, errorSpanHtml);
}
else {
new Insertion.Bottom(lastRadio.up(1), errorSpanHtml);
}
}
}
}
else if (errorSpan == null) {
new Insertion.After(fieldSpan, errorSpanHtml);
}
var path = $F(FluxValidator.form['_validation']);
var queryString = Form.serializeElements(Form.getElements(FluxValidator.form), false);
queryString = queryString.replace(/(_?)method=([a-z]+)&/, '');
var options = Object.extend({
url: path,
method: 'post',
parameters: queryString
}, this.options);
return this.makeRequest(options);
}
});
Object.extend(FluxValidator.Validate.prototype, FluxValidator.Base);
// Define some new Element methods
Element.addMethods({
wrap: function(element, tagName) {
element = $(element);
var wrapper = document.createElement(tagName);
element.up().replaceChild(wrapper, element);
wrapper.appendChild(element);
return Element.extend(wrapper);
},
equals: function(element, html) {
element = $(element).innerHTML.stripScripts().stripTags();
html = html.stripScripts().stripTags();
return (element == html);
}
});
// Override Scriptaculous Shake
Effect.Shake = function(element,valx) {
element = $(element);
valx = $(valx);
nvalx = $(valx * (-1));
var oldStyle = {
top: element.getStyle('top'),
left: element.getStyle('left') };
return new Effect.Move(element,
{ x: (valx * 2) , y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: (nvalx * 2), y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: (valx * 2), y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: (nvalx * 2), y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: (valx), y: 0, duration: 0.1, afterFinishInternal: function(effect) {
new Effect.Move(effect.element,
{ x: valx, y: 0, duration: 0.08, afterFinishInternal: function(effect) {
effect.element.undoPositioned();
effect.element.setStyle(oldStyle);
valx = 0;
nvalx = 0;
}}) }}) }}) }}) }}) }});
}