2

I have a page where is the a form a user can submit multiple times through it I want to store every value submitted in a single local storage key but the problem is the key can only store one value and gets overwritten by the next value

IS there any alternative?

Yoda
  • 127
  • 7
  • 2
    Why don't you want to use multiple keys? – Dai Aug 26 '20 at 01:04
  • How can i create a key for each submitted value? how can i name each of them? for example user submits a value then it gets assigned to key1 and then submits another value again through the form and it gets assigned to key2 . But won't it get tedious if user submits 50 times and we have 50 different keys? – Yoda Aug 26 '20 at 01:06
  • You could name the keys after your form's `input name=""` attributes. – Dai Aug 26 '20 at 01:06
  • Can store whole objects and arrays in one key using JSON.stringify() and JSON.parse() when you retrieve them – charlietfl Aug 26 '20 at 01:06
  • Check out this answer, it seems to answer your question: https://stackoverflow.com/a/23516713/13378247 – GirkovArpa Aug 26 '20 at 01:07
  • i tried array method problem is i don't know when the user will stop submitting – Yoda Aug 26 '20 at 01:07
  • What is your specific use case regarding multiple submits? – charlietfl Aug 26 '20 at 01:09
  • chat application and i want to store the messages sent – Yoda Aug 26 '20 at 01:10
  • Might want to also look at using indexedDB which allows you to define db fields and is more robust than localStorage https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API – charlietfl Aug 26 '20 at 01:12
  • UPDATE: This solved my problem https://stackoverflow.com/questions/40843773/localstorage-keeps-overwriting-my-data – Yoda Aug 26 '20 at 05:26
  • @Yoda That answer you linked to does the same thing my answer does, except they're using an array instead of a key+value object. The downside to using an array is that the values are indexed by number, not name - which makes it harder to accommodate changes to your form's design. – Dai Aug 26 '20 at 08:06
  • @Dai Oh , But i wonder there is only 4 fields what if i want to store 10 or so values for example? – Yoda Aug 26 '20 at 09:05
  • 1
    @Yoda JavaScript objects are extensible (i.e. you can add and remove properties to them) - in part 2 of my answer you can see that the code *adds* `field5` to the `formState` object. – Dai Aug 26 '20 at 09:20

1 Answers1

4

Is there any alternative?

Yes. Use a JSON object that you deserialize + edit + reserialize.

Like so:

// 1: Initial save:

const formState = {
    field1: document.getElementById( 'input1' ).value,
    field2: document.getElementById( 'input2' ).value,
    field3: document.getElementById( 'input3' ).value,
    field4: document.getElementById( 'input4' ).value
};

window.localStorage.setItem( "formState", JSON.stringify( formState ) );

(The const keyword means the object reference cannot be reassigned, it does not mean that formState is immutable)


To add a new value to the object, just set it (JavaScript object values are conceptually the same thing as a hashtable/dictionary):

const formState = JSON.parse( window.localStorage.getItem( "formState" ) );

formState.field5 = document.getElementById( 'input5' ).value;

window.localStorage.setItem( "formState", JSON.stringify( formState ) );

To remove an entry from the formState object, use the delete keyword:

const formState = JSON.parse( window.localStorage.getItem( "formState" ) );

delete formState.field3; // This removes 'field3' completely.

window.localStorage.setItem( "formState", JSON.stringify( formState ) );

You can also quickly dump an entire <form> to an object, like so:

// WARNING: This code is a quick-and-dirty demonstration, it is not production-quality. You'll need to sort-out handling of multiple-select <select> elements and other types of <input>, like file inputs.

const formState = {};

const form = document.getElementById( 'myForm' );

const inputs = form .querySelectorAll( 'input[name], select[name], textarea[name]' );

for( const input of inputs ) {
    let shouldInclude = true;
    if( input.tagName == 'INPUT' && ( input.type == 'radio' || input.type == 'checkbox') ) {
        if( input.checked === false ) shouldInclude = false;
    }

    if( shouldInclude ) formState[ input.name ] = input.value;
}

Dai
  • 141,631
  • 28
  • 261
  • 374