Prototype: merges from form branch. Closes #5031, #5902, #7595, #8401, #8483, #8767. [Mislav Marohnić, Tomas, Christophe Porteneuve, Jonathan Viney]
This commit is contained in:
parent
f2d304b3ee
commit
9e7efd5361
15
CHANGELOG
15
CHANGELOG
|
@ -1,5 +1,20 @@
|
|||
*SVN*
|
||||
|
||||
* The action for Form#request defaults to the current URL if the "action" attribute is empty. (This is what most of the major browsers do.) Fixes #8483. [Tomas, Mislav Marohnić]
|
||||
|
||||
* In form serialization, change the way submit buttons are handled. Previously all submit buttons were serialized; now Prototype serializes only the first one. Change Form#serialize and Form.serializeElements to accept a params hash. With the "hash: false" option, a serialized string is returned instead of the hash data object. With the "submit: 'foo'" option, only the submit button with the name "foo" is serialized. References #5031. [Mislav Marohnić]
|
||||
Examples:
|
||||
$('form').serialize({ submit: 'delete' })
|
||||
$('form').serialize({ hash: false }) //-> equivalent to $('form').serialize()
|
||||
|
||||
* Form#findFirstElement respects HTML tabindexes. Closes #7595. [Christophe Porteneuve]
|
||||
|
||||
* Added Form.Element#setValue method for setting values on various form controls. Checkboxes and radio buttons respond to a boolean and multiple select boxes expect an array of values. Closes #5902. [Jonathan Viney, Mislav Marohnić]
|
||||
Examples:
|
||||
$('text_input').setValue('hello world!')
|
||||
$('remember_me').setValue(true)
|
||||
$('attend_classes').setValue(['cheese rolling', 'evil chemistry'])
|
||||
|
||||
* Make document.getElementsByClassName match a subset of the WHATWG Web Applications 1.0 specification which was adopted in Firefox 3 (http://www.whatwg.org/specs/web-apps/current-work/#getelementsbyclassname). It now supports multiple class names given as a whitespace-separated list in a string. Array argument is not supported. The method will only return the nodes that match all the class names. In browsers that implement the method natively it will not be overwritten. Closes #8401. [Mislav Marohnić]
|
||||
Example:
|
||||
document.getElementsByClassName('foo bar')
|
||||
|
|
83
src/form.js
83
src/form.js
|
@ -4,12 +4,18 @@ var Form = {
|
|||
return form;
|
||||
},
|
||||
|
||||
serializeElements: function(elements, getHash) {
|
||||
serializeElements: function(elements, options) {
|
||||
if (typeof options != 'object') options = { hash: !!options };
|
||||
else if (options.hash === undefined) options.hash = true;
|
||||
var key, value, submitted = false, submit = options.submit;
|
||||
|
||||
var data = elements.inject({}, function(result, element) {
|
||||
if (!element.disabled && element.name) {
|
||||
var key = element.name, value = $(element).getValue();
|
||||
if (value != null) {
|
||||
if (key in result) {
|
||||
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 (result[key].constructor != Array) result[key] = [result[key]];
|
||||
result[key].push(value);
|
||||
}
|
||||
|
@ -19,13 +25,13 @@ var Form = {
|
|||
return result;
|
||||
});
|
||||
|
||||
return getHash ? data : Hash.toQueryString(data);
|
||||
return options.hash ? data : Hash.toQueryString(data);
|
||||
}
|
||||
};
|
||||
|
||||
Form.Methods = {
|
||||
serialize: function(form, getHash) {
|
||||
return Form.serializeElements(Form.getElements(form), getHash);
|
||||
serialize: function(form, options) {
|
||||
return Form.serializeElements(Form.getElements(form), options);
|
||||
},
|
||||
|
||||
getElements: function(form) {
|
||||
|
@ -67,9 +73,15 @@ Form.Methods = {
|
|||
},
|
||||
|
||||
findFirstElement: function(form) {
|
||||
return $(form).getElements().find(function(element) {
|
||||
return element.type != 'hidden' && !element.disabled &&
|
||||
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
|
||||
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());
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -82,7 +94,8 @@ Form.Methods = {
|
|||
request: function(form, options) {
|
||||
form = $(form), options = Object.clone(options || {});
|
||||
|
||||
var params = options.parameters;
|
||||
var params = options.parameters, action = form.readAttribute('action') || '';
|
||||
if (action.blank()) action = window.location.href;
|
||||
options.parameters = form.serialize(true);
|
||||
|
||||
if (params) {
|
||||
|
@ -93,7 +106,7 @@ Form.Methods = {
|
|||
if (form.hasAttribute('method') && !options.method)
|
||||
options.method = form.method;
|
||||
|
||||
return new Ajax.Request(form.readAttribute('action'), options);
|
||||
return new Ajax.Request(action, options);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +144,13 @@ Form.Element.Methods = {
|
|||
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;
|
||||
},
|
||||
|
||||
clear: function(element) {
|
||||
$(element).value = '';
|
||||
return element;
|
||||
|
@ -145,7 +165,7 @@ Form.Element.Methods = {
|
|||
try {
|
||||
element.focus();
|
||||
if (element.select && (element.tagName.toLowerCase() != 'input' ||
|
||||
!['button', 'reset', 'submit'].include(element.type)))
|
||||
!['button', 'reset', 'submit'].include(element.type)))
|
||||
element.select();
|
||||
} catch (e) {}
|
||||
return element;
|
||||
|
@ -173,27 +193,44 @@ var $F = Form.Element.Methods.getValue;
|
|||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
Form.Element.Serializers = {
|
||||
input: function(element) {
|
||||
input: function(element, value) {
|
||||
switch (element.type.toLowerCase()) {
|
||||
case 'checkbox':
|
||||
case 'radio':
|
||||
return Form.Element.Serializers.inputSelector(element);
|
||||
return Form.Element.Serializers.inputSelector(element, value);
|
||||
default:
|
||||
return Form.Element.Serializers.textarea(element);
|
||||
return Form.Element.Serializers.textarea(element, value);
|
||||
}
|
||||
},
|
||||
|
||||
inputSelector: function(element) {
|
||||
return element.checked ? element.value : null;
|
||||
inputSelector: function(element, value) {
|
||||
if (value === undefined) return element.checked ? element.value : null;
|
||||
else element.checked = !!value;
|
||||
},
|
||||
|
||||
textarea: function(element) {
|
||||
return element.value;
|
||||
textarea: function(element, value) {
|
||||
if (value === undefined) return element.value;
|
||||
else element.value = value;
|
||||
},
|
||||
|
||||
select: function(element) {
|
||||
return this[element.type == 'select-one' ?
|
||||
'selectOne' : 'selectMany'](element);
|
||||
select: function(element, index) {
|
||||
if (index === undefined)
|
||||
return this[element.type == 'select-one' ?
|
||||
'selectOne' : 'selectMany'](element);
|
||||
else {
|
||||
var opt, value, single = index.constructor != Array;
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
selectOne: function(element) {
|
||||
|
|
|
@ -1,125 +1,159 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Prototype Unit test file</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<script src="../../dist/prototype.js" type="text/javascript"></script>
|
||||
<script src="../lib/unittest.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="../test.css" type="text/css" />
|
||||
<style type="text/css" media="screen">
|
||||
/* <![CDATA[ */
|
||||
#testcss1 { font-size:11px; color: #f00; }
|
||||
#testcss2 { font-size:12px; color: #0f0; display: none; }
|
||||
/* ]]> */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Prototype Unit test file</h1>
|
||||
<p>
|
||||
Test of utility functions in form.js
|
||||
</p>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Prototype Unit test file</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<script src="../../dist/prototype.js" type="text/javascript"></script>
|
||||
<script src="../lib/unittest.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="../test.css" type="text/css" />
|
||||
<style type="text/css" media="screen">
|
||||
/* <![CDATA[ */
|
||||
#testlog { margin-bottom:2em }
|
||||
/* ]]> */
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Prototype Unit test file</h1>
|
||||
<p>
|
||||
Test of utility functions in form.js
|
||||
</p>
|
||||
|
||||
<!-- Log output -->
|
||||
<div id="testlog"> </div>
|
||||
<!-- Log output -->
|
||||
<div id="testlog"> </div>
|
||||
|
||||
<form id="form" method="get" action="fixtures/empty.js">
|
||||
<input type="text" name="val1" id="input_enabled" value="4" />
|
||||
<div>This is not a form element</div>
|
||||
<input type="text" name="val2" id="input_disabled" disabled="disabled" value="5" />
|
||||
<input type="submit" />
|
||||
<input type="text" name="action" value="blah" />
|
||||
</form>
|
||||
<div id="form_wrapper">
|
||||
<form id="form_selects" action="fixtures/empty.js">
|
||||
<select name="vu">
|
||||
<option value="1" selected="selected">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<select id="multiSel1" name="vm[]" multiple="multiple">
|
||||
<option id="multiSel1_opt1" value="1" selected="selected">One</option>
|
||||
<option id="multiSel1_opt2" value="2">Two</option>
|
||||
<option id="multiSel1_opt3" value="3" selected="selected">Three</option>
|
||||
</select>
|
||||
<select name="nvu">
|
||||
<option selected="selected">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<fieldset id="form_fieldset">
|
||||
<select name="nvm[]" multiple="multiple">
|
||||
<option selected="selected">One</option>
|
||||
<option>Two</option>
|
||||
<option selected="selected">Three</option>
|
||||
</select>
|
||||
<select name="evu">
|
||||
<option value="" selected="selected">One</option>
|
||||
<form id="form" method="get" action="fixtures/empty.js">
|
||||
<input type="text" name="val1" id="input_enabled" value="4" />
|
||||
<div>This is not a form element</div>
|
||||
<input type="text" name="val2" id="input_disabled" disabled="disabled" value="5" />
|
||||
<input type="submit" name="first_submit" value="Commit it!" />
|
||||
<input type="submit" name="second_submit" value="Delete it!" />
|
||||
<input type="text" name="action" value="blah" />
|
||||
</form>
|
||||
|
||||
<form id="bigform" method="get" action="fixtures/empty.js">
|
||||
<div id="inputs">
|
||||
<input type="text" name="dummy" id="dummy_disabled" disabled="disabled"/>
|
||||
<input type="submit" name="commit" id="submit" />
|
||||
<input type="button" name="clicky" value="click me" />
|
||||
<input type="reset" name="revert" />
|
||||
<input type="text" name="greeting" id="focus_text" value="Hello" />
|
||||
</div>
|
||||
|
||||
<!-- some edge cases in serialization -->
|
||||
<div id="value_checks">
|
||||
<input name="twin" type="text" value="" />
|
||||
<input name="twin" type="text" value="siamese" />
|
||||
<!-- Rails checkbox hack with hidden input: -->
|
||||
<input name="checky" type="checkbox" id="checkbox_hack" value="1" />
|
||||
<input name="checky" type="hidden" value="0" />
|
||||
</div>
|
||||
|
||||
<!-- all variations of SELECT controls -->
|
||||
<div id="selects_wrapper">
|
||||
<select name="vu">
|
||||
<option value="1" selected="selected">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<select name="evm[]" multiple="multiple">
|
||||
<option value="" selected="selected">One</option>
|
||||
<option>Two</option>
|
||||
<option selected="selected">Three</option>
|
||||
<select id="multiSel1" name="vm[]" multiple="multiple">
|
||||
<option id="multiSel1_opt1" value="1" selected="selected">One</option>
|
||||
<option id="multiSel1_opt2" value="2">Two</option>
|
||||
<option id="multiSel1_opt3" value="3" selected="selected">Three</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
<select name="nvu">
|
||||
<option selected="selected">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
|
||||
<fieldset id="selects_fieldset">
|
||||
<select name="nvm[]" multiple="multiple">
|
||||
<option selected="selected">One</option>
|
||||
<option>Two</option>
|
||||
<option selected="selected">Three</option>
|
||||
</select>
|
||||
<select name="evu">
|
||||
<option value="" selected="selected">One</option>
|
||||
<option value="2">Two</option>
|
||||
<option value="3">Three</option>
|
||||
</select>
|
||||
<select name="evm[]" multiple="multiple">
|
||||
<option value="" selected="selected">One</option>
|
||||
<option>Two</option>
|
||||
<option selected="selected">Three</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
<div id="various">
|
||||
<select name="tf_selectOne"><option selected="selected"></option><option>1</option></select>
|
||||
<textarea name="tf_textarea"></textarea>
|
||||
<input type="checkbox" name="tf_checkbox" value="on" />
|
||||
<select name="tf_selectMany" multiple="multiple"></select>
|
||||
<input type="text" name="tf_text" />
|
||||
<div>This is not a form element</div>
|
||||
<input type="radio" name="tf_radio" value="on" />
|
||||
<input type="hidden" name="tf_hidden" />
|
||||
<input type="password" name="tf_password" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form id="form_array">
|
||||
<input type="text" name="twin" value="" />
|
||||
<input type="text" name="twin" value="siamese" />
|
||||
<!-- Rails checkbox hack with hidden input: -->
|
||||
<input type="checkbox" id="checkbox_hack" name="checky" value="1" />
|
||||
<input name="checky" type="hidden" value="0" />
|
||||
</form>
|
||||
<form id="form_focus_hidden" style="display: none">
|
||||
<input type="text" />
|
||||
</form>
|
||||
|
||||
<form id="form_getelements">
|
||||
<select id="tf_selectOne" name="tf_selectOne"><option></option><option>1</option></select>
|
||||
<textarea id="tf_textarea" name="tf_textarea"></textarea>
|
||||
<input type="checkbox" id="tf_checkbox" name="tf_checkbox" value="on" />
|
||||
<select id="tf_selectMany" name="tf_selectMany" multiple="multiple"></select>
|
||||
<input type="text" id="tf_text" name="tf_text" />
|
||||
<div>This is not a form element</div>
|
||||
<input type="radio" id="tf_radio" name="tf_radio" value="on" />
|
||||
<input type="hidden" id="tf_hidden" name="tf_hidden" />
|
||||
<input type="password" id="tf_password" name="tf_password" />
|
||||
</form>
|
||||
<!-- tabindexed forms -->
|
||||
<div id="tabindex">
|
||||
<form id="ffe">
|
||||
<p><input type="text" disabled="disabled" id="ffe_disabled" /></p>
|
||||
<input type="hidden" id="ffe_hidden" />
|
||||
<input type="checkbox" id="ffe_checkbox" />
|
||||
</form>
|
||||
|
||||
<form id="form_focus">
|
||||
<input type="text" name="focus_disabled" id="focus_disabled" disabled="disabled"/>
|
||||
<input type="submit" name="focus_submit" id="focus_submit" />
|
||||
<input type="button" name="focus_button" id="focus_button" value="button" />
|
||||
<input type="reset" name="focus_reset" id="focus_reset" />
|
||||
<input type="text" name="focus_text" id="focus_text" value="Hello" />
|
||||
</form>
|
||||
<form id="ffe_ti">
|
||||
<p><input type="text" disabled="disabled" id="ffe_ti_disabled" /></p>
|
||||
<input type="hidden" id="ffe_ti_hidden" />
|
||||
<input type="checkbox" id="ffe_ti_checkbox" />
|
||||
<input type="submit" id="ffe_ti_submit" tabindex="1" />
|
||||
</form>
|
||||
|
||||
<form id="form_focus_hidden" style="display: none">
|
||||
<input type="text" />
|
||||
</form>
|
||||
<form id="ffe_ti2">
|
||||
<p><input type="text" disabled="disabled" id="ffe_ti2_disabled" /></p>
|
||||
<input type="hidden" id="ffe_ti2_hidden" />
|
||||
<input type="checkbox" id="ffe_ti2_checkbox" tabindex="0" />
|
||||
<input type="submit" id="ffe_ti2_submit" tabindex="1" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Tests follow -->
|
||||
<script type="text/javascript" language="javascript" charset="utf-8">
|
||||
// <![CDATA[
|
||||
var callbackCounter = 0;
|
||||
var timedCounter = 0;
|
||||
<!-- Tests follow -->
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
// <![CDATA[
|
||||
var callbackCounter = 0;
|
||||
var timedCounter = 0;
|
||||
|
||||
// sweet sweet additional assertions
|
||||
Object.extend(Test.Unit.Testcase.prototype, {
|
||||
assertEnabled: function() {
|
||||
for (var i = 0, element; element = arguments[i]; i++) {
|
||||
this.assert(!$(element).disabled, Test.Unit.inspect(element) + ' was disabled');
|
||||
}
|
||||
},
|
||||
assertDisabled: function() {
|
||||
for (var i = 0, element; element = arguments[i]; i++) {
|
||||
this.assert($(element).disabled, Test.Unit.inspect(element) + ' was enabled');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Test.Unit.Runner({
|
||||
|
||||
// Make sure to set defaults in the test forms, as some browsers override this
|
||||
// with previously entered values on page reload
|
||||
setup: function(){ with(this) {
|
||||
$('input_enabled').value = '4';
|
||||
$('input_disabled').value = '5';
|
||||
|
||||
$('tf_selectOne').selectedIndex = 0;
|
||||
$('tf_textarea').value = '';
|
||||
$('tf_text').value = '';
|
||||
$('tf_hidden').value = '';
|
||||
$('tf_password').value = '';
|
||||
$('tf_checkbox').checked = false;
|
||||
$('tf_radio').checked = false;
|
||||
$$('form').each(function(f){ f.reset() });
|
||||
// hidden value does not reset (for some reason)
|
||||
$('bigform')['tf_hidden'].value = '';
|
||||
}},
|
||||
|
||||
testDollarF: function(){ with(this) {
|
||||
|
@ -190,50 +224,47 @@
|
|||
}},
|
||||
|
||||
testFormEnabling: function(){ with(this) {
|
||||
var form = $('form_focus')
|
||||
var input1 = form.focus_disabled
|
||||
var input2 = form.focus_text
|
||||
var form = $('bigform')
|
||||
var input1 = $('dummy_disabled');
|
||||
var input2 = $('focus_text');
|
||||
|
||||
assert(input1.disabled)
|
||||
assert(!input2.disabled)
|
||||
assertDisabled(input1);
|
||||
assertEnabled(input2);
|
||||
|
||||
form.disable()
|
||||
assert(input1.disabled)
|
||||
assert(input2.disabled)
|
||||
|
||||
form.enable()
|
||||
assert(!input1.disabled)
|
||||
assert(!input2.disabled)
|
||||
|
||||
input1.disable()
|
||||
assert(input1.disabled)
|
||||
form.disable();
|
||||
assertDisabled(input1, input2);
|
||||
form.enable();
|
||||
assertEnabled(input1, input2);
|
||||
input1.disable();
|
||||
assertDisabled(input1);
|
||||
|
||||
// non-form elements:
|
||||
var fieldset = $('form_fieldset')
|
||||
var fields = fieldset.immediateDescendants()
|
||||
assert(fields.all(function(select){ return !select.disabled }))
|
||||
var fieldset = $('selects_fieldset');
|
||||
var fields = fieldset.immediateDescendants();
|
||||
fields.each(function(select) { assertEnabled(select) });
|
||||
|
||||
Form.disable(fieldset)
|
||||
assert(fields.all(function(select){ return select.disabled }))
|
||||
fields.each(function(select) { assertDisabled(select) });
|
||||
|
||||
Form.enable(fieldset)
|
||||
assert(fields.all(function(select){ return !select.disabled }))
|
||||
fields.each(function(select) { assertEnabled(select) });
|
||||
}},
|
||||
|
||||
testFormElementEnabling: function(){ with(this) {
|
||||
assert($('input_disabled').disabled);
|
||||
$('input_disabled').enable();
|
||||
assert(!$('input_disabled').disabled);
|
||||
$('input_disabled').disable();
|
||||
assert($('input_disabled').disabled);
|
||||
var field = $('input_disabled');
|
||||
field.enable();
|
||||
assertEnabled(field);
|
||||
field.disable();
|
||||
assertDisabled(field);
|
||||
|
||||
assert(!$('input_enabled').disabled);
|
||||
$('input_enabled').disable();
|
||||
assert($('input_enabled').disabled);
|
||||
$('input_enabled').enable();
|
||||
assert(!$('input_enabled').disabled);
|
||||
var field = $('input_enabled');
|
||||
assertEnabled(field);
|
||||
field.disable();
|
||||
assertDisabled(field);
|
||||
field.enable();
|
||||
assertEnabled(field);
|
||||
}},
|
||||
|
||||
|
||||
// due to the lack of a DOM hasFocus() API method,
|
||||
// we're simulating things here a little bit
|
||||
testFormActivating: function(){ with(this) {
|
||||
|
@ -250,11 +281,11 @@
|
|||
}
|
||||
|
||||
// Form.focusFirstElement shouldn't focus disabled elements
|
||||
var element = Form.findFirstElement('form_focus');
|
||||
assertEqual('focus_submit',element.id);
|
||||
var element = Form.findFirstElement('bigform');
|
||||
assertEqual('submit', element.id);
|
||||
|
||||
// Test IE doesn't select text on buttons
|
||||
Form.focusFirstElement('form_focus');
|
||||
Form.focusFirstElement('bigform');
|
||||
if(document.selection) assertEqual('', getSelection(element));
|
||||
|
||||
// Form.Element.activate shouldn't select text on buttons
|
||||
|
@ -272,126 +303,162 @@
|
|||
}},
|
||||
|
||||
testFormGetElements: function() {with(this) {
|
||||
var formElements = $('form_getelements').getElements();
|
||||
assertEqual(8, formElements.length);
|
||||
assertEqual('tf_selectOne', formElements[0].id);
|
||||
assertEqual('tf_textarea', formElements[1].id);
|
||||
assertEqual('tf_checkbox', formElements[2].id);
|
||||
assertEqual('tf_selectMany', formElements[3].id);
|
||||
assertEqual('tf_text', formElements[4].id);
|
||||
assertEqual('tf_radio', formElements[5].id);
|
||||
assertEqual('tf_hidden', formElements[6].id);
|
||||
assertEqual('tf_password', formElements[7].id);
|
||||
var elements = Form.getElements('various'),
|
||||
names = $w('tf_selectOne tf_textarea tf_checkbox tf_selectMany tf_text tf_radio tf_hidden tf_password');
|
||||
assertEnumEqual(names, elements.pluck('name'))
|
||||
}},
|
||||
|
||||
testFormGetInputs: function() {with(this){
|
||||
var form = $('form_getelements'), formInputs = Form.getInputs(form);
|
||||
assertEqual(formInputs.length, 5);
|
||||
assert(formInputs instanceof Array);
|
||||
assert(formInputs.all(function(input) { return (input.tagName == "INPUT"); }));
|
||||
|
||||
var formInputs2 = form.getInputs();
|
||||
assertEqual(formInputs2.length, 5);
|
||||
assert(formInputs2 instanceof Array);
|
||||
assert(formInputs2.all(function(input) { return (input.tagName == "INPUT"); }));
|
||||
var form = $('form');
|
||||
[form.getInputs(), Form.getInputs(form)].each(function(inputs){
|
||||
assertEqual(inputs.length, 5);
|
||||
assert(inputs instanceof Array);
|
||||
assert(inputs.all(function(input) { return (input.tagName == "INPUT"); }));
|
||||
});
|
||||
}},
|
||||
|
||||
testFormFindFirstElement: function() {with(this) {
|
||||
assertEqual($('ffe_checkbox'), $('ffe').findFirstElement());
|
||||
assertEqual($('ffe_ti_submit'), $('ffe_ti').findFirstElement());
|
||||
assertEqual($('ffe_ti2_checkbox'), $('ffe_ti2').findFirstElement());
|
||||
}},
|
||||
|
||||
testFormSerialize: function() {with(this){
|
||||
assertEqual('tf_selectOne=&tf_textarea=&tf_text=&tf_hidden=&tf_password=',
|
||||
Form.serialize('form_getelements'));
|
||||
// form is initially empty
|
||||
var form = $('bigform');
|
||||
var expected = { tf_selectOne:'', tf_textarea:'', tf_text:'', tf_hidden:'', tf_password:'' };
|
||||
assertHashEqual(expected, Form.serialize('various', true));
|
||||
|
||||
$('tf_selectOne').selectedIndex = 1;
|
||||
$('tf_textarea').value = "boo hoo!";
|
||||
$('tf_text').value = "123öäü";
|
||||
$('tf_hidden').value = "moo%hoo&test";
|
||||
$('tf_password').value = 'sekrit code';
|
||||
$('tf_checkbox').checked = true;
|
||||
$('tf_radio').checked = true;
|
||||
|
||||
assertEqual(
|
||||
'tf_selectOne=1&tf_textarea=boo%20hoo!&tf_checkbox=on&tf_text=123%C3%B6%C3%A4%C3%BC&'+
|
||||
'tf_radio=on&tf_hidden=moo%25hoo%26test&tf_password=sekrit%20code',
|
||||
Form.serialize('form_getelements'));
|
||||
// set up some stuff
|
||||
form['tf_selectOne'].selectedIndex = 1;
|
||||
form['tf_textarea'].value = "boo hoo!";
|
||||
form['tf_text'].value = "123öäü";
|
||||
form['tf_hidden'].value = "moo%hoo&test";
|
||||
form['tf_password'].value = 'sekrit code';
|
||||
form['tf_checkbox'].checked = true;
|
||||
form['tf_radio'].checked = true;
|
||||
var expected = { tf_selectOne:1, tf_textarea:"boo hoo!", tf_text:"123öäü",
|
||||
tf_hidden:"moo%hoo&test", tf_password:'sekrit code', tf_checkbox:'on', tf_radio:'on' }
|
||||
|
||||
// return params
|
||||
assertHashEqual(expected, Form.serialize('various', true));
|
||||
// return string
|
||||
assertEnumEqual(Hash.toQueryString(expected).split('&').sort(),
|
||||
Form.serialize('various').split('&').sort());
|
||||
assertEqual('string', typeof $('form').serialize({ hash:false }));
|
||||
|
||||
// Checks that disabled element is not included in serialized form.
|
||||
$('input_enabled').enable();
|
||||
assertEqual('val1=4&action=blah', Form.serialize('form'));
|
||||
assertHashEqual({ val1:4, action:'blah', first_submit:'Commit it!' },
|
||||
$('form').serialize(true));
|
||||
|
||||
// Checks that select-related serializations work just fine
|
||||
assertEqual('vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One'+
|
||||
'&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three',
|
||||
Form.serialize('form_selects'));
|
||||
|
||||
// should not eat empty values for duplicate names
|
||||
$('checkbox_hack').checked = false;
|
||||
var data = Form.serialize('form_array', true);
|
||||
var data = Form.serialize('value_checks', true);
|
||||
assertEnumEqual(['', 'siamese'], data['twin']);
|
||||
assertEqual('0', data['checky']);
|
||||
|
||||
$('checkbox_hack').checked = true;
|
||||
assertEnumEqual($w('1 0'), Form.serialize('form_array', true)['checky']);
|
||||
}},
|
||||
|
||||
testFormSerializeWorksWithNonFormElements: function() {with(this) {
|
||||
assertEqual('nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_fieldset'));
|
||||
assertEqual('vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three', Form.serialize('form_wrapper'));
|
||||
assertEnumEqual($w('1 0'), Form.serialize('value_checks', true)['checky']);
|
||||
|
||||
// all kinds of SELECT controls
|
||||
var params = Form.serialize('selects_fieldset', true);
|
||||
var expected = { 'nvm[]':['One', 'Three'], evu:'', 'evm[]':['', 'Three'] };
|
||||
assertHashEqual(expected, params);
|
||||
params = Form.serialize('selects_wrapper', true);
|
||||
assertHashEqual(Object.extend(expected, { vu:1, 'vm[]':[1, 3], nvu:'One' }), params);
|
||||
|
||||
// explicit submit button
|
||||
assertHashEqual({ val1:4, action:'blah', second_submit:'Delete it!' },
|
||||
$('form').serialize({ submit: 'second_submit' }));
|
||||
assertHashEqual({ val1:4, action:'blah' },
|
||||
$('form').serialize({ submit: false }));
|
||||
assertHashEqual({ val1:4, action:'blah' },
|
||||
$('form').serialize({ submit: 'inexistent' }));
|
||||
}},
|
||||
|
||||
testFormMethodsOnExtendedElements: function() {with(this) {
|
||||
assertEqual(Form.serialize('form'), $('form').serialize());
|
||||
var form = $('form');
|
||||
assertEqual(Form.serialize('form'), form.serialize());
|
||||
assertEqual(Form.Element.serialize('input_enabled'), $('input_enabled').serialize());
|
||||
assertNotEqual($('form').serialize, $('input_enabled').serialize);
|
||||
assertNotEqual(form.serialize, $('input_enabled').serialize);
|
||||
|
||||
Element.addMethods('INPUT', { anInputMethod: function(input) { return 'input' } });
|
||||
Element.addMethods('SELECT', { aSelectMethod: function(select) { return 'select' } });
|
||||
|
||||
document.getElementById('tf_text')._extendedByPrototype = false;
|
||||
document.getElementById('tf_selectOne')._extendedByPrototype = false;
|
||||
form = $('bigform');
|
||||
var input = form['tf_text'], select = form['tf_selectOne'];
|
||||
input._extendedByPrototype = select._extendedByPrototype = false;
|
||||
|
||||
assert($('tf_text').anInputMethod);
|
||||
assert(!$('tf_text').aSelectMethod);
|
||||
assertEqual('input', $('tf_text').anInputMethod());
|
||||
assert($(input).anInputMethod);
|
||||
assert(!input.aSelectMethod);
|
||||
assertEqual('input', input.anInputMethod());
|
||||
|
||||
assert($('tf_selectOne').aSelectMethod);
|
||||
assert(!$('tf_selectOne').anInputMethod);
|
||||
assertEqual('select', $('tf_selectOne').aSelectMethod());
|
||||
assert($(select).aSelectMethod);
|
||||
assert(!select.anInputMethod);
|
||||
assertEqual('select', select.aSelectMethod());
|
||||
}},
|
||||
|
||||
testFormRequest: function() {with(this) {
|
||||
var request = $("form_selects").request();
|
||||
assert(!$("form_selects").hasAttribute("method"));
|
||||
assert(request.url.endsWith("fixtures/empty.js"));
|
||||
assertEqual("post", request.method);
|
||||
assertEqual("vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three", Hash.toQueryString(request.options.parameters));
|
||||
|
||||
request = $("form_selects").request({method: "put", parameters: {val2: "hello", val3: "world"}});
|
||||
assertEqual("post", request.method);
|
||||
assertEqual("put", request.parameters['_method']);
|
||||
assertEqual("vu=1&vm%5B%5D=1&vm%5B%5D=3&nvu=One&nvm%5B%5D=One&nvm%5B%5D=Three&evu=&evm%5B%5D=&evm%5B%5D=Three&val2=hello&val3=world", Hash.toQueryString(request.options.parameters));
|
||||
|
||||
request = $("form").request();
|
||||
assert($("form").hasAttribute("method"));
|
||||
assert(request.url.endsWith("fixtures/empty.js?val1=4&action=blah"));
|
||||
assert(request.url.include("fixtures/empty.js?val1=4"));
|
||||
assertEqual("get", request.method);
|
||||
|
||||
request = $("form").request({method: "post"});
|
||||
request = $("form").request({ method: "put", parameters: {val2: "hello"} });
|
||||
assert(request.url.endsWith("fixtures/empty.js"));
|
||||
assertEqual("val1=4&action=blah", Hash.toQueryString(request.options.parameters));
|
||||
assertEqual(4, request.options.parameters['val1']);
|
||||
assertEqual('hello', request.options.parameters['val2']);
|
||||
assertEqual("post", request.method);
|
||||
assertEqual("put", request.parameters['_method']);
|
||||
|
||||
// with empty action attribute
|
||||
request = $("ffe").request({ method: 'post' });
|
||||
assert(request.url.include("unit/form.html"),
|
||||
'wrong default action for form element with empty action attribute');
|
||||
}},
|
||||
|
||||
testFormElementMethodsChaining: function(){ with(this) {
|
||||
var methods = $w('clear activate disable enable'),
|
||||
formElements = $('form_getelements').getElements();
|
||||
formElements = $('form').getElements();
|
||||
methods.each(function(method){
|
||||
formElements.each(function(element){
|
||||
var returned = element[method]();
|
||||
assertIdentical(element, returned);
|
||||
});
|
||||
});
|
||||
}},
|
||||
|
||||
testSetValue: function(){ with(this) {
|
||||
// text input
|
||||
var input = $('input_enabled'), oldValue = input.getValue();
|
||||
assertEqual(input, input.setValue('foo'), 'setValue chaining is broken');
|
||||
assertEqual('foo', input.getValue(), 'value improperly set');
|
||||
input.setValue(oldValue);
|
||||
assertEqual(oldValue, input.getValue(), 'value improperly restored to original');
|
||||
|
||||
// checkbox
|
||||
input = $('checkbox_hack');
|
||||
input.setValue(false);
|
||||
assertEqual(null, input.getValue(), 'checkbox should be unchecked');
|
||||
input.setValue(true);
|
||||
assertEqual("1", input.getValue(), 'checkbox should be checked');
|
||||
// selectbox
|
||||
input = $('bigform')['vu'];
|
||||
input.setValue('3');
|
||||
assertEqual('3', input.getValue(), 'single select option improperly set');
|
||||
input.setValue('1');
|
||||
assertEqual('1', input.getValue());
|
||||
// multiple select
|
||||
input = $('bigform')['vm[]'];
|
||||
input.setValue(['2', '3']);
|
||||
assertEnumEqual(['2', '3'], input.getValue(),
|
||||
'multiple select options improperly set');
|
||||
input.setValue(['1', '3']);
|
||||
assertEnumEqual(['1', '3'], input.getValue());
|
||||
}}
|
||||
|
||||
}, 'testlog');
|
||||
});
|
||||
// ]]>
|
||||
</script>
|
||||
</body>
|
||||
|
|
Loading…
Reference in New Issue