@@ -428,28 +428,76 @@ $.api = $.fn.api = function(parameters) {
428
428
formData : function ( data ) {
429
429
var
430
430
formData = { } ,
431
- hasOtherData
431
+ hasOtherData ,
432
+ useFormDataApi = settings . serializeForm === 'formdata'
432
433
;
433
434
data = data || originalData || settings . data ;
434
435
hasOtherData = $ . isPlainObject ( data ) ;
435
436
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 ) ;
442
468
} else {
443
- formData [ element . name ] = [ node , element . value ] ;
469
+ pushValues [ pushKey ] = [ pushValues [ pushKey ] , value ] ;
444
470
}
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
+ }
449
490
450
491
if ( hasOtherData ) {
451
492
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
+ }
453
501
}
454
502
else {
455
503
module . debug ( 'Adding form data' , formData ) ;
@@ -1088,6 +1136,8 @@ $.api.settings = {
1088
1136
defaultData : true ,
1089
1137
1090
1138
// 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
1091
1141
serializeForm : false ,
1092
1142
1093
1143
// how long to wait before request should occur
@@ -1158,6 +1208,11 @@ $.api.settings = {
1158
1208
regExp : {
1159
1209
required : / \{ \$ * [ A - z 0 - 9 ] + \} / g,
1160
1210
optional : / \{ \/ \$ * [ A - z 0 - 9 ] + \} / g,
1211
+ validate : / ^ [ a - z _ ] [ a - z 0 - 9 _ - ] * (?: \[ (?: \d * | [ a - z 0 - 9 _ - ] + ) \] ) * $ / i,
1212
+ key : / [ a - z 0 - 9 _ - ] + | (? = \[ \] ) / gi,
1213
+ push : / ^ $ / ,
1214
+ fixed : / ^ \d + $ / ,
1215
+ named : / ^ [ a - z 0 - 9 _ - ] + $ / i
1161
1216
} ,
1162
1217
1163
1218
className : {
0 commit comments