Last active
August 29, 2015 14:25
-
-
Save allex/fe0b2b4c1ffeacfe16a5 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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