Side navigation
#1209 closed enhancement (wontfix)
Opened May 18, 2007 07:27PM UTC
Closed May 11, 2008 11:38PM UTC
Last modified May 13, 2008 05:31PM UTC
Form Value Function
Reported by: | bgoldman | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | 1.2.4 |
Component: | core | Version: | 1.1.2 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
This function sets or gets the value of a form variable as a form would interpret it. This function is useful for jQuery core because everybody uses forms. This function makes it very easy to get and set form values without having to use fancy selectors. It's basically shorthand for a bunch of alternatives.
1) For selects and options: formVal() would return the currently selected value. formVal('foo') would select the option with that value.
2) For input text fields: formVal() would return the current value. formVal('foo') would set the value to foo.
3) For textareas: formVal() would return text(). formVal('foo') would set the text() to foo.
4) For checkboxes: formVal() would return the first matched checked value. formVal('foo') would check the boxes with value foo.
5) For radios: formVal() would return the checked value. formVal('foo') would check the radio with value foo.
//gets the value of the first matched form field, or sets the value of all the matched form fields $.fn.formVal = function(newVal) { var self = this.get(0); if(newVal == null) { if(this.size() < 1) return ''; else if(self.type == 'text') return self.value; else if(self.tagName == 'TEXTAREA') return this.text(); else if(self.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val(); else if(self.tagName == 'OPTION') return this.parent().formVal(); else if(self.tagName == 'SELECT') { var match = this.find('option:selected').eq(0); return (match.get(0).value != null) ? match.val() : match.text(); } else return ''; } if(self.type == 'text') this.val(newVal); else if(self.tagName == 'TEXTAREA') this.text(newVal); else if(self.type == 'checkbox' || self.type == 'radio') { var matches = this.filter('[@value=' + newVal + ']'); if(matches.size() < 1) return this; if(self.type == 'radio') this.filter(':checked').removeAttr('checked'); matches.attr('checked', 'checked'); } else if(self.tagName == 'OPTION') this.parent().formVal(newVal); else if(self.tagName == 'SELECT') { var match = this.find('option[@value=' + newVal + ']'); if(match.size() < 1) { if(newVal == '') match = this.find('option:empty'); else match = this.find('option').contains(newVal); } if(match.size() < 1) return this; this.find('option:selected').removeAttr('selected'); match.eq(0).attr('selected', 'selected'); } return this; };
Attachments (0)
Change History (6)
Changed May 18, 2007 08:04PM UTC by comment:1
Changed May 19, 2007 12:41AM UTC by comment:2
Fixed another bug... here we go:
//gets the value of the first matched form field, or sets the value of all the matched form fields $.fn.formVal = function(newVal) { var self = this.get(0); if(newVal == null) { if(this.size() < 1) return ''; else if(self.type == 'text') return self.value; else if(self.tagName == 'TEXTAREA') return this.text(); else if(self.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val() || ''; else if(self.tagName == 'OPTION') return this.parent().formVal(); else if(self.tagName == 'SELECT') { var match = this.find('option:selected').eq(0); return (match.is('[@value]')) ? match.val() : match.text(); } else return ''; } if(self.type == 'text') this.val(newVal); else if(self.tagName == 'TEXTAREA') this.text(newVal); else if(self.type == 'checkbox' || self.type == 'radio') { this.filter(':checked').removeAttr('checked'); this.filter('[@value=' + newVal + ']').attr('checked', 'checked'); } else if(self.tagName == 'OPTION') this.parent().formVal(newVal); else if(self.tagName == 'SELECT') { var match = this.filter('option[@value=' + newVal + ']'); if(match.size() < 1) { if(newVal == '') match = this.find('option:empty'); else match = this.find('option').filter(function() { return ($(this).text() == newVal); }); } if(match.size() < 1) return this; this.find('option:selected').removeAttr('selected'); match.attr('selected', 'selected'); } return this; };
Changed June 20, 2007 09:08PM UTC by comment:3
For SELECT elements, formVal() returns the wrong value when the selected OPTION is marked up with value="": Since "" is falsy, match.is('[@value]') is false and match.text() is incorrectly returned.
Pseudocode for a fix:
if (option.value) { // non-empty string return option.value; } if (! option.outerHTML) { // definitely not IE, so trust value return ''; } if (/* option.outerHTML has 'value=""' in attributes */) { // likely painful regex return ''; } else { return option.text; }
Changed June 21, 2007 07:25PM UTC by comment:4
Here's a fix for setting/getting SELECT when options might have empty value attributes, but non-empty text. Is there a unit test somewhere for this plugin?
//gets the value of the first matched form field, or sets //the value of all the matched form fields $.fn.formVal = function(newVal) { var self = this.get(0); var optVal = function(opt) { if(opt.value) return opt.value; // non-empty string, use it if(!opt.outerHTML) return ''; // not IE, we should trust value // @todo: more rigorous regex to assert value="" in attributes, not text return /\\svalue=""(?:\\s|>)/.test(opt.outerHTML) ? '' : opt.text; }; if(newVal == null) { if(this.size() < 1) return ''; if(self.type == 'text') return self.value; if(self.tagName == 'TEXTAREA') return this.text(); if(self.type == 'checkbox' || self.type == 'radio') return this.filter('input:checked').val() || ''; if(self.tagName == 'OPTION') return this.parent().formVal(); // if a SELECT with no selection, fallthrough to return '' // or should re return null? if(self.tagName == 'SELECT' && self.selectedIndex >= 0) return optVal(self.options[self.selectedIndex]); return ''; } if(self.type == 'text') this.val(newVal); else if(self.tagName == 'TEXTAREA') this.text(newVal); else if(self.type == 'checkbox' || self.type == 'radio') { this.filter(':checked').removeAttr('checked'); this.filter('[@value=' + newVal + ']').attr('checked', 'checked'); } else if(self.tagName == 'OPTION') this.parent().formVal(newVal); else if(self.tagName == 'SELECT') { // search for matching value for (var i=0, l=self.options.length; i<l; ++i) { if(newVal == optVal(self.options[i])) { self.selectedIndex = i; break; } } } return this; };
Changed May 11, 2008 11:38PM UTC by comment:5
resolution: | → wontfix |
---|---|
status: | new → closed |
I think jQuery.form can do all or most of this. If anything is missing you can propose it for this plugin.
Changed May 13, 2008 05:31PM UTC by comment:6
milestone: | 1.1.3 → 1.2.4 |
---|
I found a bug with selects and options. Here is the fixed code: