Handles the basic functionality of submitting a form and updating a dom element with the result.
if (!window.Form) window.Form = {};
(function(){
Form.Request = new Class({
Binds: ['onSubmit', 'onFormValidate'],
Implements: [Options, Events, Class.Occlude],
options: {
onFailure: function(){}, onSuccess: #function(){}, //aliased to onComplete, onSend: function(){}
requestOptions: {
evalScripts: true,
useSpinner: true,
emulation: false,
link: 'ignore'
},
sendButtonClicked: true,
extraData: {},
resetForm: true
},
property: 'form.request',
initialize: function(form, update, options){
this.element = document.id(form);
if (this.occlude()) return this.occluded;
this.update = document.id(update);
this.setOptions(options);
this.makeRequest();
if (this.options.resetForm){
this.request.addEvent('success', function(){
Function.attempt(function(){ this.element.reset(); }.bind(this));
if (window.OverText) OverText.update();
}.bind(this));
}
this.attach();
},
toElement: function(){
return this.element;
},
makeRequest: function(){
this.request = new Request.HTML(Object.merge({
update: this.update,
emulation: false,
spinnerTarget: this.element,
method: this.element.get('method') || 'post'
}, this.options.requestOptions)).addEvents({
success: function(tree, elements, html, javascript){
['complete', 'success'].each(function(evt){
this.fireEvent(evt, [this.update, tree, elements, html, javascript]);
}, this);
}.bind(this),
failure: function(){
this.fireEvent('complete', arguments).fireEvent('failure', arguments);
}.bind(this),
exception: function(){
this.fireEvent('failure', arguments);
}.bind(this)
});
},
attach: function(attach){
attach = attach != null ? attach : true;
method = attach ? 'addEvent' : 'removeEvent';
this.element[method]('click:relay(button, input[type=submit])', this.saveClickedButton.bind(this));
var fv = this.element.retrieve('validator');
if (fv) fv[method]('onFormValidate', this.onFormValidate);
else this.element[method]('submit', this.onSubmit);
},
detach: function(){
this.attach(false);
return this;
},
public method
enable: function(){
this.attach();
return this;
},
public method
disable: function(){
this.detach();
return this;
},
onFormValidate: function(valid, form, e){
if there’s no event, then this wasn’t a submit event
if (!e) return;
var fv = this.element.retrieve('validator');
if (valid || (fv && !fv.options.stopOnFailure)){
if (e && e.stop) e.stop();
this.send();
}
},
onSubmit: function(e){
var fv = this.element.retrieve('validator');
if (fv){
form validator was created after Form.Request
this.element.removeEvent('submit', this.onSubmit);
fv.addEvent('onFormValidate', this.onFormValidate);
this.element.validate();
return;
}
if (e) e.stop();
this.send();
},
saveClickedButton: function(event, target){
if (!this.options.sendButtonClicked) return;
if (!target.get('name')) return;
this.options.extraData[target.get('name')] = target.get('value') || true;
this.clickedCleaner = function(){
delete this.options.extraData[target.get('name')];
this.clickedCleaner = function(){};
}.bind(this);
},
clickedCleaner: function(){},
send: function(){
var str = this.element.toQueryString().trim();
var data = Object.toQueryString(this.options.extraData);
if (str) str += "&" + data;
else str = data;
this.fireEvent('send', [this.element, str.parseQueryString()]);
this.request.send({data: str, url: this.element.get("action")});
this.clickedCleaner();
return this;
}
});
Element.Properties.formRequest = {
set: function(){
var opt = Array.link(arguments, {options: Type.isObject, update: Type.isElement, updateId: Type.isString});
var update = opt.update || opt.updateId;
var updater = this.retrieve('form.request');
if (update){
if (updater) updater.update = document.id(update);
this.store('form.request:update', update);
}
if (opt.options){
if (updater) updater.setOptions(opt.options);
this.store('form.request:options', opt.options);
}
return this;
},
get: function(){
var opt = Array.link(arguments, {options: Type.isObject, update: Type.isElement, updateId: Type.isString});
var update = opt.update || opt.updateId;
if (opt.options || update || !this.retrieve('form.request')){
if (opt.options || !this.retrieve('form.request:options')) this.set('form.request', opt.options);
if (update) this.set('form.request', update);
this.store('form.request', new Form.Request(this, this.retrieve('form.request:update'), this.retrieve('form.request:options')));
}
return this.retrieve('form.request');
}
};
Element.implement({
formUpdate: function(update, options){
this.get('formRequest', update, options).send();
return this;
}
});
})();