prototype/src/form.js

341 lines
9.2 KiB
JavaScript
Raw Normal View History

2007-01-18 22:24:27 +00:00
var Form = {
reset: function(form) {
$(form).reset();
return form;
},
serializeElements: function(elements, options) {
if (typeof options != 'object') options = { hash: !!options };
else if (Object.isUndefined(options.hash)) options.hash = true;
var key, value, submitted = false, submit = options.submit;
var data = elements.inject({ }, function(result, element) {
2007-01-18 22:24:27 +00:00
if (!element.disabled && element.name) {
key = element.name; value = $(element).getValue();
if (value != null && (element.type != 'submit' || (!submitted &&
submit !== false && (!submit || key == submit) && (submitted = true)))) {
if (key in result) {
// a key is already present; construct an array of values
if (!Object.isArray(result[key])) result[key] = [result[key]];
2007-01-18 22:24:27 +00:00
result[key].push(value);
}
else result[key] = value;
}
}
return result;
});
2007-10-13 10:55:52 +00:00
return options.hash ? data : Object.toQueryString(data);
2007-01-18 22:24:27 +00:00
}
};
Form.Methods = {
serialize: function(form, options) {
return Form.serializeElements(Form.getElements(form), options);
2007-01-18 22:24:27 +00:00
},
getElements: function(form) {
return $A($(form).getElementsByTagName('*')).inject([],
function(elements, child) {
if (Form.Element.Serializers[child.tagName.toLowerCase()])
elements.push(Element.extend(child));
return elements;
}
);
},
getInputs: function(form, typeName, name) {
form = $(form);
var inputs = form.getElementsByTagName('input');
if (!typeName && !name) return $A(inputs).map(Element.extend);
for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) || (name && input.name != name))
continue;
matchingInputs.push(Element.extend(input));
}
return matchingInputs;
},
disable: function(form) {
form = $(form);
Form.getElements(form).invoke('disable');
2007-01-18 22:24:27 +00:00
return form;
},
enable: function(form) {
form = $(form);
Form.getElements(form).invoke('enable');
2007-01-18 22:24:27 +00:00
return form;
},
findFirstElement: function(form) {
var elements = $(form).getElements().findAll(function(element) {
return 'hidden' != element.type && !element.disabled;
});
var firstByIndex = elements.findAll(function(element) {
return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
}).sortBy(function(element) { return element.tabIndex }).first();
return firstByIndex ? firstByIndex : elements.find(function(element) {
return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
2007-01-18 22:24:27 +00:00
});
},
focusFirstElement: function(form) {
form = $(form);
form.findFirstElement().activate();
return form;
},
request: function(form, options) {
form = $(form), options = Object.clone(options || { });
var params = options.parameters, action = form.readAttribute('action') || '';
if (action.blank()) action = window.location.href;
options.parameters = form.serialize(true);
if (params) {
if (Object.isString(params)) params = params.toQueryParams();
Object.extend(options.parameters, params);
}
if (form.hasAttribute('method') && !options.method)
options.method = form.method;
return new Ajax.Request(action, options);
2007-01-18 22:24:27 +00:00
}
};
2007-01-18 22:24:27 +00:00
/*--------------------------------------------------------------------------*/
Form.Element = {
focus: function(element) {
$(element).focus();
return element;
},
select: function(element) {
$(element).select();
return element;
}
};
2007-01-18 22:24:27 +00:00
Form.Element.Methods = {
serialize: function(element) {
element = $(element);
if (!element.disabled && element.name) {
var value = element.getValue();
if (value != undefined) {
var pair = { };
2007-01-18 22:24:27 +00:00
pair[element.name] = value;
2007-10-13 10:55:52 +00:00
return Object.toQueryString(pair);
2007-01-18 22:24:27 +00:00
}
}
return '';
},
getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
return Form.Element.Serializers[method](element);
},
setValue: function(element, value) {
element = $(element);
var method = element.tagName.toLowerCase();
Form.Element.Serializers[method](element, value);
return element;
},
2007-01-18 22:24:27 +00:00
clear: function(element) {
$(element).value = '';
return element;
},
present: function(element) {
return $(element).value != '';
},
activate: function(element) {
element = $(element);
try {
element.focus();
if (element.select && (element.tagName.toLowerCase() != 'input' ||
!['button', 'reset', 'submit'].include(element.type)))
element.select();
} catch (e) { }
2007-01-18 22:24:27 +00:00
return element;
},
disable: function(element) {
element = $(element);
element.blur();
2007-01-18 22:24:27 +00:00
element.disabled = true;
return element;
},
enable: function(element) {
element = $(element);
element.disabled = false;
return element;
}
};
2007-01-18 22:24:27 +00:00
/*--------------------------------------------------------------------------*/
2007-01-18 22:24:27 +00:00
var Field = Form.Element;
2007-04-28 03:53:50 +00:00
var $F = Form.Element.Methods.getValue;
2007-01-18 22:24:27 +00:00
/*--------------------------------------------------------------------------*/
Form.Element.Serializers = {
input: function(element, value) {
2007-01-18 22:24:27 +00:00
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element, value);
2007-01-18 22:24:27 +00:00
default:
return Form.Element.Serializers.textarea(element, value);
2007-01-18 22:24:27 +00:00
}
},
inputSelector: function(element, value) {
if (Object.isUndefined(value)) return element.checked ? element.value : null;
else element.checked = !!value;
2007-01-18 22:24:27 +00:00
},
textarea: function(element, value) {
if (Object.isUndefined(value)) return element.value;
else element.value = value;
2007-01-18 22:24:27 +00:00
},
select: function(element, index) {
if (Object.isUndefined(index))
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
else {
var opt, value, single = !Object.isArray(index);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
value = this.optionValue(opt);
if (single) {
if (value == index) {
opt.selected = true;
return;
}
}
else opt.selected = index.include(value);
}
}
2007-01-18 22:24:27 +00:00
},
selectOne: function(element) {
var index = element.selectedIndex;
return index >= 0 ? this.optionValue(element.options[index]) : null;
},
selectMany: function(element) {
var values, length = element.length;
if (!length) return null;
for (var i = 0, values = []; i < length; i++) {
var opt = element.options[i];
if (opt.selected) values.push(this.optionValue(opt));
}
return values;
},
optionValue: function(opt) {
// extend element because hasAttribute may not be native
return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
}
};
2007-01-18 22:24:27 +00:00
/*--------------------------------------------------------------------------*/
Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
initialize: function($super, element, frequency, callback) {
$super(callback, frequency);
2007-01-18 22:24:27 +00:00
this.element = $(element);
this.lastValue = this.getValue();
},
execute: function() {
2007-01-18 22:24:27 +00:00
var value = this.getValue();
if (Object.isString(this.lastValue) && Object.isString(value) ?
this.lastValue != value : String(this.lastValue) != String(value)) {
2007-01-18 22:24:27 +00:00
this.callback(this.element, value);
this.lastValue = value;
}
}
});
2007-01-18 22:24:27 +00:00
Form.Element.Observer = Class.create(Abstract.TimedObserver, {
2007-01-18 22:24:27 +00:00
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.Observer = Class.create(Abstract.TimedObserver, {
2007-01-18 22:24:27 +00:00
getValue: function() {
return Form.serialize(this.element);
}
});
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = Class.create({
2007-01-18 22:24:27 +00:00
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form')
this.registerFormCallbacks();
else
this.registerCallback(this.element);
},
onElementEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},
registerFormCallbacks: function() {
Form.getElements(this.element).each(this.registerCallback, this);
2007-01-18 22:24:27 +00:00
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
default:
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
});
2007-01-18 22:24:27 +00:00
Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
2007-01-18 22:24:27 +00:00
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.EventObserver = Class.create(Abstract.EventObserver, {
2007-01-18 22:24:27 +00:00
getValue: function() {
return Form.serialize(this.element);
}
});