简体   繁体   中英

How do handle empty arrays when serializing only altered form elements

I have a form that consists of a number of multi-select fields. Each select has a unique ID, and are named accordingly:

values[foobar1][]
values[foobar2][]
values[foobar3][]
... etc.

This form could potentially contain hundreds of these fields, and so is paged by ajax. The result of that is that there is no guarantee that all records are going to available at once at the front end. Therefore, it is impossible for me to submit the entire form. I do, however, have access to the entire list of records server-side.

My solution to this was to watch for changes in the form fields and, for every field that is changed, store the values in an array to keep track of just the altered field values. So if you make a change to just foobar2 , the resulting serialized array that is sent to the server will look like this:

0: Object {
    name: "values[foobar2][]"
    value: "thevalue1"
},
1: Object {
    name: "values[foobar2][]"
    value: "thevalue3"
}

So this works fine except for, as you may have guessed, when the select multiple is emptied. No matter what format I use for storing the altered values, be it arraySerialization of each field or as an associative array, when I pass my array to $.param() for the ajax request the resulting serialized string contains no trace of the empty value. So there is no way for the server to determine that the value has been emptied.

Can anyone suggest a way of either passing the data to the server so that the empt(ied) array remains intact, or another way of dealing with the initial problem.

Thanks in advance!

Create a single object for all select field values you can use localStorage or sessionStorage to store it. Since the form is in a lot of pages and you use ajax to get each select field. Place the selected values of each field in an array. Creating an object like this is the idea.

{ 
formValues: {
          foobar1: {
                   values: ["thevalue1","thevalue2"]
                   },
          foobar2: {
                   values: ["thevalue3"]
                   },
        ...
          foobarN: {
                   values: []
                   }           
             }
}

Every time you update a select vield value or values make sure to update the localStorage saved value. eg

var valuesObject = { 
              formValues: {
                          foobar1: {
                                   values: ["thevalue1","thevalue2"]
                                   },
                          foobar2: {
                                   values: ["thevalue3"]
                                   },
                          foobar3: {
                                   values: []
                                   }           
                          }
                     }

// Put the object into storage
localStorage.setItem('valuesObject', JSON.stringify(valuesObject));

// Retrieve the object from storage
var valuesObjectA = localStorage.getItem('valuesObject');
//console.log('valuesObject: ', JSON.parse(valuesObjectA));
// post your data
$.post( "ajax.php", valuesObjectA ).done(function( data ) {
alert( "Data Loaded: " + data );
}).fail(function() {
console.log( "error" );
});

Sample fiddle

You want to calculate the diff between current and previous state, send the change to the server, and apply it to the data.

You can do so using the JSON patch standard (rfc6902).

JSON Patch is a format for describing changes to a JSON document. It can be used to avoid sending a whole document when only a part has changed. When used in combination with the HTTP PATCH method it allows partial updates for HTTP APIs in a standards compliant way.

To create the diff you can use an NPM module, such as jiff . A diff is set a of patching commands, that can transform a JSON document. For example:

[
  { "op": "replace", "path": "/values/foobar2/", "value": ["thevalue1"] },
  { "op": "remove", "path": "/values/foobar2/"}
]

You send the diff to the server, and then use a server module, such as php-jsonpatch , to apply the patch to the current data on the server.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM