Skip to content

Commit acc903b

Browse files
authored
feat(api): serializeObject, formdata, files
This PR implements an optimized version of the original jquery-serializeobject dependency of SUI when serializeForm:true was used. https://github.com/macek/jquery-serialize-object/blob/master/jquery.serialize-object.js I enhanced the original logic to also support file inputs, convert pure number values and support same name keys (without trailing []) I also added support to use The FormData Api when serializeForm is set to 'formdata'. This way the old code stays backward compatible.
1 parent f9f3304 commit acc903b

File tree

1 file changed

+68
-13
lines changed
  • src/definitions/behaviors

1 file changed

+68
-13
lines changed

src/definitions/behaviors/api.js

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -428,28 +428,76 @@ $.api = $.fn.api = function(parameters) {
428428
formData: function(data) {
429429
var
430430
formData = {},
431-
hasOtherData
431+
hasOtherData,
432+
useFormDataApi = settings.serializeForm === 'formdata'
432433
;
433434
data = data || originalData || settings.data;
434435
hasOtherData = $.isPlainObject(data);
435436

436-
$.each($form.serializeArray(), function (i, element) {
437-
var node = formData[element.name];
438-
439-
if ('undefined' !== typeof node && node !== null) {
440-
if (Array.isArray(node)) {
441-
node.push(element.value);
437+
if (useFormDataApi) {
438+
formData = new FormData($form[0]);
439+
settings.processData = typeof settings.processData !== 'undefined' ? settings.processData : false;
440+
settings.contentType = typeof settings.contentType !== 'undefined' ? settings.contentType : false;
441+
} else {
442+
var formArray = $form.serializeArray(),
443+
pushes = {},
444+
pushValues= {},
445+
build = function(base, key, value) {
446+
base[key] = value;
447+
return base;
448+
}
449+
;
450+
// add files
451+
$.each($('input[type="file"]',$form), function(i, tag) {
452+
$.each($(tag)[0].files, function(j, file) {
453+
formArray.push({name:tag.name, value: file});
454+
});
455+
});
456+
$.each(formArray, function(i, el) {
457+
if (!settings.regExp.validate.test(el.name)) return;
458+
var isCheckbox = $('[name="' + el.name + '"]', $form).attr('type') === 'checkbox',
459+
floatValue = parseFloat(el.value),
460+
value = (isCheckbox && el.value === 'on') || el.value === 'true' || (String(floatValue) === el.value ? floatValue : (el.value === 'false' ? false : el.value)),
461+
nameKeys = el.name.match(settings.regExp.key) || [], k, pushKey= el.name.replace(/\[\]$/,'')
462+
;
463+
if(!(pushKey in pushes)) {
464+
pushes[pushKey] = 0;
465+
pushValues[pushKey] = value;
466+
} else if (Array.isArray(pushValues[pushKey])) {
467+
pushValues[pushKey].push(value);
442468
} else {
443-
formData[element.name] = [node, element.value];
469+
pushValues[pushKey] = [pushValues[pushKey] , value];
444470
}
445-
} else {
446-
formData[element.name] = element.value;
447-
}
448-
});
471+
value = pushValues[pushKey];
472+
473+
while ((k = nameKeys.pop()) !== undefined) {
474+
// foo[]
475+
if (k == '' && !Array.isArray(value)){
476+
value = build([], pushes[pushKey]++, value);
477+
}
478+
// foo[n]
479+
else if (settings.regExp.fixed.test(k)) {
480+
value = build([], k, value);
481+
}
482+
// foo; foo[bar]
483+
else if (settings.regExp.named.test(k)) {
484+
value = build({}, k, value);
485+
}
486+
}
487+
formData = $.extend(true, formData, value);
488+
});
489+
}
449490

450491
if(hasOtherData) {
451492
module.debug('Extending existing data with form data', data, formData);
452-
data = $.extend(true, {}, data, formData);
493+
if(useFormDataApi) {
494+
$.each(Object.keys(data),function(i, el){
495+
formData.append(el, data[el]);
496+
});
497+
data = formData;
498+
} else {
499+
data = $.extend(true, {}, data, formData);
500+
}
453501
}
454502
else {
455503
module.debug('Adding form data', formData);
@@ -1088,6 +1136,8 @@ $.api.settings = {
10881136
defaultData : true,
10891137

10901138
// whether to serialize closest form
1139+
// use true to convert complex named keys like a[b][1][c][] into a nested object
1140+
// use 'formdata' for formdata web api
10911141
serializeForm : false,
10921142

10931143
// how long to wait before request should occur
@@ -1158,6 +1208,11 @@ $.api.settings = {
11581208
regExp : {
11591209
required : /\{\$*[A-z0-9]+\}/g,
11601210
optional : /\{\/\$*[A-z0-9]+\}/g,
1211+
validate: /^[a-z_][a-z0-9_-]*(?:\[(?:\d*|[a-z0-9_-]+)\])*$/i,
1212+
key: /[a-z0-9_-]+|(?=\[\])/gi,
1213+
push: /^$/,
1214+
fixed: /^\d+$/,
1215+
named: /^[a-z0-9_-]+$/i
11611216
},
11621217

11631218
className: {

0 commit comments

Comments
 (0)