// http://dev.jquery.com/ticket/1209

//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 we 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;
};