Skip to content

Instantly share code, notes, and snippets.

@lsmith
Created September 4, 2013 18:13
Show Gist options
  • Save lsmith/6440659 to your computer and use it in GitHub Desktop.
Save lsmith/6440659 to your computer and use it in GitHub Desktop.

Revisions

  1. lsmith created this gist Sep 4, 2013.
    120 changes: 120 additions & 0 deletions gistfile1.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,120 @@
    /**
    Adds a `Y.DOM.formToObject(identifier)` method to extract the values from a
    `<form>` element and return an object map of element name to value(s).
    @module dom
    @submodule dom-form-values
    @since @SINCE@
    **/
    var isArray = Y.Lang.isArray;

    /**
    Return an object with form values from `<input>`s, `<select>`s, and
    `<textarea>`s, keyed by field name. Fields with multiple values will have those
    values in an array.
    * Disabled fields will be ignored unless the _includeDisabled_ param is truthy.
    * If no radio or checkbox is checked, the returned object will not contain a
    reference to it.
    * If no option is selected in a single select, the first option value will be
    used.
    * if no option is selected in a multi-select, it will be omitted from the
    returned object.
    @method formToObject
    @param {Element|Node|String} identifier The DOM element, Node, or selector for
    the `<form>`
    @param {Boolean} includeDisabled
    @return {Object}
    **/
    Y.DOM.formToObject = function (identifier, includeDisabled) {
    var skipDisabled = !includeDisabled, // so I don't have to ! it in loop
    form, fields, field, type, values, name, value,
    selectedIndex, i, len, j, jlen;

    if (identifier.nodeType) {
    form = identifier;
    } else if (identifier._node) {
    form = identifier._node;
    } else if (typeof identifier === 'string') {
    if (/^#([\w\-]+)$/.test(identifier)) {
    form = Y.config.doc.getElementById(RegExp.$1);
    } else if (Y.Selector) {
    form = Y.Selector.query(identifier, null, true);
    }
    }

    function optionValue(opt) {
    return (opt.attributes.value && opt.attributes.value.specified) ?
    opt.value : opt.text;
    }

    if (form && form.elements) {
    values = {};
    fields = form.elements;

    for (i = 0, len = fields.length; i < len; ++i) {
    value = undefined; // reset for fields that may be skipped
    field = fields[i];
    name = field.name;

    if (!name || (skipDisabled && field.disabled)) {
    continue;
    }

    type = (field.tagName || '').toLowerCase();

    if (type === 'input' || type === 'textarea') {
    switch ((field.type || '').toLowerCase()) {
    case 'button':
    case 'image':
    case 'submit':
    case 'reset':
    case 'file': continue; // don't capture buttons or files

    case 'radio':
    case 'checkbox':
    if (!field.checked) {
    break;
    } // else fall through

    default: value = field.value;
    }
    } else if (type === 'select') {
    type = field.type;

    if (field.type === 'select-multiple') {
    j = field.selectedIndex;

    if (j > -1) {
    value = [];
    for (jlen = field.options.length; j < jlen; ++j) {
    if (field.options[j].selected) {
    value.push(optionValue(field.options[j]));
    }
    }
    }
    } else {
    // For browsers that allow no selectedIndex or -1
    // TODO: Is this right?
    selectedIndex = Math.max(field.selectedIndex, 0);

    value = optionValue(field.options[selectedIndex]);
    }
    }

    if (value !== undefined) {
    if (name in values) {
    if (!isArray(values[name])) {
    values[name] = [values[name]];
    }
    values[name].push(value);
    } else {
    values[name] = value;
    }
    }
    }
    }

    return values || null;
    };