Skip to content

Commit

Permalink
Extend BUTTON elements with everything defined in Form.Element.Method…
Browse files Browse the repository at this point in the history
…s. Ensure BUTTON elements are traversed in Form.getElements and serialized in Form.serialize. [#394 state:resolved] [#688 state:resolved] (Luis Gomez, Samuel Lebeau, kangax, Andrew Dupont)
  • Loading branch information
savetheclocktower committed Oct 17, 2010
1 parent a7e51ae commit 1fcf2e0
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 47 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
@@ -1,3 +1,5 @@
* Extend BUTTON elements with everything defined in Form.Element.Methods. Ensure BUTTON elements are traversed in Form.getElements and serialized in Form.serialize. (Luis Gomez, Samuel Lebeau, kangax, Andrew Dupont)

* Ensure Object.isFunction returns `false` for RegExp objects. [#661 state:resolved] (James, kangax, Andrew Dupont)

* Revert Opera-specific behavior for calling Element#getStyle with (left|right|top|bottom). [#268 state:resolved] (kangax, Andrew Dupont)
Expand Down
3 changes: 2 additions & 1 deletion src/dom/dom.js
Expand Up @@ -3292,7 +3292,8 @@ Element.addMethods = function(methods) {
"FORM": Object.clone(Form.Methods),
"INPUT": Object.clone(Form.Element.Methods),
"SELECT": Object.clone(Form.Element.Methods),
"TEXTAREA": Object.clone(Form.Element.Methods)
"TEXTAREA": Object.clone(Form.Element.Methods),
"BUTTON": Object.clone(Form.Element.Methods)
});
}

Expand Down
93 changes: 51 additions & 42 deletions src/dom/form.js
Expand Up @@ -724,68 +724,77 @@ var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
input: function(element, value) {
Form.Element.Serializers = (function() {
function input(element, value) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element, value);
return inputSelector(element, value);
default:
return Form.Element.Serializers.textarea(element, value);
return valueSelector(element, value);
}
},

inputSelector: function(element, value) {
if (Object.isUndefined(value)) return element.checked ? element.value : null;
else element.checked = !!value;
},

textarea: function(element, value) {
}

function inputSelector(element, value) {
if (Object.isUndefined(value))
return element.checked ? element.value : null;
else element.checked = !!value;
}

function valueSelector(element, value) {
if (Object.isUndefined(value)) return element.value;
else element.value = value;
},

select: function(element, value) {
}
function select(element, value) {
if (Object.isUndefined(value))
return this[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
else {
var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
currentValue = this.optionValue(opt);
if (single) {
if (currentValue == value) {
opt.selected = true;
return;
}
return (element.type === 'select-one' ? selectOne : selectMany)(element);

var opt, currentValue, single = !Object.isArray(value);
for (var i = 0, length = element.length; i < length; i++) {
opt = element.options[i];
currentValue = this.optionValue(opt);
if (single) {
if (currentValue == value) {
opt.selected = true;
return;
}
else opt.selected = value.include(currentValue);
}
else opt.selected = value.include(currentValue);
}
},

selectOne: function(element) {
}
function selectOne(element) {
var index = element.selectedIndex;
return index >= 0 ? this.optionValue(element.options[index]) : null;
},

selectMany: function(element) {
return index >= 0 ? optionValue(element.options[index]) : null;
}
function selectMany(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));
if (opt.selected) values.push(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;
}
};

function optionValue(opt) {
return Element.hasAttribute(opt, 'value') ? opt.value : opt.text;
}

return {
input: input,
inputSelector: inputSelector,
textarea: valueSelector,
select: select,
selectOne: selectOne,
selectMany: selectMany,
optionValue: optionValue,
button: valueSelector
};
})();

/*--------------------------------------------------------------------------*/

Expand Down
1 change: 1 addition & 0 deletions test/unit/fixtures/form.html
Expand Up @@ -72,6 +72,7 @@
<input type="radio" name="tf_radio" value="on" />
<input type="hidden" name="tf_hidden" />
<input type="password" name="tf_password" />
<button name="tf_button"></button>
</div>
</form>

Expand Down
25 changes: 21 additions & 4 deletions test/unit/form_test.js
Expand Up @@ -204,7 +204,7 @@ new Test.Unit.Runner({

testFormGetElements: function() {
var elements = Form.getElements('various'),
names = $w('tf_selectOne tf_textarea tf_checkbox tf_selectMany tf_text tf_radio tf_hidden tf_password');
names = $w('tf_selectOne tf_textarea tf_checkbox tf_selectMany tf_text tf_radio tf_hidden tf_password tf_button');
this.assertEnumEqual(names, elements.pluck('name'))
},

Expand All @@ -226,7 +226,15 @@ new Test.Unit.Runner({
testFormSerialize: function() {
// form is initially empty
var form = $('bigform');
var expected = { tf_selectOne:'', tf_textarea:'', tf_text:'', tf_hidden:'', tf_password:'' };
var expected = {
tf_selectOne: '',
tf_textarea: '',
tf_text: '',
tf_hidden: '',
tf_password: '',
tf_button: ''
};

this.assertHashEqual(expected, Form.serialize('various', true));

// set up some stuff
Expand All @@ -235,10 +243,19 @@ new Test.Unit.Runner({
form['tf_text'].value = "123öäü";
form['tf_hidden'].value = "moo%hoo&test";
form['tf_password'].value = 'sekrit code';
form['tf_button'].value = 'foo bar';
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' }

var expected = {
tf_selectOne: 1, tf_textarea: "boo hoo!",
tf_text: "123öäü",
tf_hidden: "moo%hoo&test",
tf_password: 'sekrit code',
tf_button: 'foo bar',
tf_checkbox: 'on',
tf_radio: 'on'
};

// return params
this.assertHashEqual(expected, Form.serialize('various', true));
Expand Down

0 comments on commit 1fcf2e0

Please sign in to comment.