Skip to content

Instantly share code, notes, and snippets.

@allex
Last active August 29, 2015 14:25
Show Gist options
  • Save allex/fe0b2b4c1ffeacfe16a5 to your computer and use it in GitHub Desktop.
Save allex/fe0b2b4c1ffeacfe16a5 to your computer and use it in GitHub Desktop.
/**
* Form utilities for serialize/desrialize.
*
* GistID: fe0b2b4c1ffeacfe16a5
* GistURL: https://gist.github.com/fe0b2b4c1ffeacfe16a5
*
* @author Allex Wang ([email protected])
*
* Usage:
*
* ```js
* var formUtility = require('lib/core/1.0.0/utils/form');
* var form = $('input, textarea, select', '#moduleId');
* var formData = formUtility.getParams(form);
* console.log(formData) // => {"floor_class":"2321","floor_num":"5","floor_skus":["72","73"]}
* ```
*/
define(function(require, exports, module) {
'use strict';
var $ = require('jquery')
, keyBreaker = /[^\[\]]+/g
, numberMatcher = /^[\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?$/
, trim = $.trim
, isNumber = function(v) {
if (typeof v === 'number') return true;
if (typeof v !== 'string') return false;
return v.match(numberMatcher);
}
, decodeEntities = function(str) {
var d = decodeEntities.__el__ || (decodeEntities.__el__ = document.createElement('div'));
d.innerHTML = str;
return d.innerText || d.textContent;
}
function setParams(selector, params, clear) { /*jshint eqeqeq: false*/
$(selector).find('[name]').each(function(i, input) { // Find all the inputs
var name = $(input).attr('name'),
value = params[name];
if (name.indexOf('[') > -1) { // if name is object, e.g. user[name], userData[address][street], update value to read this correctly
var names = name.replace(/\]/g, '').split('['),
i = 0,
n = null,
v = params;
for (; n = names[i++];)
if (v[n]) v = v[n];
else {
v = undefined;
break;
}
value = v;
}
if (clear !== true && value === undefined) return; // if clear==true and no value = clear field, otherwise - leave it as it was
if (value === null || value === undefined) value = ''; // if no value - clear field
if (typeof value === 'string' && value.indexOf('&') > -1) value = decodeEntities(value); // decode html special chars (entities)
if (input.type === 'radio') input.checked = (input.value == value);
else if (input.type === 'checkbox') input.checked = value;
else {
if ('placeholder' in document.createElement('input')) input.value = value; // normal browser
else { // manually handle placeholders for specIEl browser
var el = $(input);
if (input.value != value && value !== '') el.data('changed', true);
if (value === '') el.data('changed', false).val(el.attr('placeholder'));
else input.value = value;
}
}
});
}
function getParams(selector, option) {
var data = {}, current, convert = false;
if (typeof option === 'boolean') {
convert = option;
option = {};
} else {
option = option || {}
convert = option.convert;
convert = convert === undefined ? false : convert;
}
$(selector).each(function(i, el) {
var type = el.type && el.type.toLowerCase();
if ((type === 'submit') || !el.name || el.disabled) return; // if we are submit or disabled - ignore
var key = el.name,
value = $.data(el, 'value') || $(el).val(),
parts = key.match(keyBreaker),
lastPart, // make an array of values
isArray = key.indexOf('[]') === key.length - 2
if (el.type === 'radio' && !el.checked) return; // return only "checked" radio value
if (el.type === 'checkbox') value = el.checked; // convert chekbox to [true | false]
var $el = $(el);
if ($el.data('changed') !== true && value === $el.attr('placeholder')) value = ''; // clear placeholder valus for IEs
if (convert) {
if (isNumber(value)) {
var tv = parseFloat(value),
cmp = tv + '';
if (value.indexOf('.') > 0) cmp = tv.toFixed(value.split('.')[1].length); // convert (string)100.00 to (int)100
if (cmp === value) value = tv;
} else if (value === 'true') value = true;
else if (value === 'false') value = false;
if (value === '') value = undefined;
}
// strip value blanks optionally
if (typeof value === 'string' && !option.raw) {
value = trim(value)
}
current = data;
for (var i = 0; i < parts.length - 1; i++) { // go through and create nested objects
if (!current[parts[i]]) current[parts[i]] = {};
current = current[parts[i]];
}
lastPart = parts[parts.length - 1];
if (isArray || current[lastPart]) { // now we are on the last part, set the value
if (!$.isArray(current[lastPart])) {
current[lastPart] = current[lastPart] === undefined ? [] : [current[lastPart]];
}
current[lastPart].push(value);
} else if (!current[lastPart]) current[lastPart] = value;
});
return data;
}
module.exports = {
/**
* Form params setter/getter
*
* @param {String|HTMLElement} selector The target form dom or selector string.
* @param {Object} A map json data for fill form fields.
*/
params: function(selector, params, convert) {
var form = $(selector);
if (typeof params === 'boolean') {
convert = params;
params = null;
}
if (params) return setParams(form, params, convert); // SET
else if (form[0].nodeName === 'FORM' && form[0].elements) { // GET
return getParams(form.elements, convert);
}
},
setParams: setParams,
getParams: getParams
};
});
// vim: set fdm=marker ts=2 sw=2 sts=2 tw=85 et :
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment