Jump to content

Use localStorage for Caspio Submission Form to Retrieve Data Locally After Existing Out of Form without Saving


Recommended Posts

I am building a one-page Caspio submission (deployed by embed) form for clients to fill out. Viewable here: Test Form • WIM Tracking

I want the data to save locally (without the user having to submit the form) in case they are kicked off their browser or leave and return to it later. I have read that I can use localStorage.setItem and localStorage.getItem.

I have found a couple other posts, but they don't quite translate to what I am doing. I have included the posts I have found below and have based the following code on those posts. Any suggestions?

<script type="text/javascript">
  document.addEventListener('DataPageReady', function (event) {
    console.log("DataPageReady");
    console.log(document.getElementById("CaspioForm"))


    fields = document.getElementById("First_Name")
    for (field of fields) {
      //Load stored data into that field and add a listener to store the data on change
      handleStorage(field)
    }

    //Instead of having to list
  });

  //Handle loading/storing data for a field
  function handleStorage(field) {
    // Get value out ofstorage and populate the field with it
    console.log("Loading value " + localStorage.getItem(field.id) + " for field " + field.id);
    if (field.type == "checkbox") {
      //The storage is saving the boolean as a string, so we need to
      //convert it back to a boolean for checkboxes
      field.checked = (localStorage.getItem(field.id) == 'true');
    } else {
      field.value = localStorage.getItem(field.id);
    }

    //Add a listener to store the data every time a field changes
    //This will fire every time they type a letter.
    field.addEventListener('input', (event) => {
      console.log(event);
      //Checkboxes store their value in "checked" instead of "value",
      //so you have to handle it separately.
      value = (event.target.type == "checkbox") ? event.target.checked : event.target.value;
      console.log("Storing " + value + " for " + event.target.id);

      //Store the the value for the id (The id should be unique,
      // so you might as well use it as your storage key as well)
      localStorage.setItem(event.target.id, value);
    });
  }
</script>

 

 

 

Link to comment
Share on other sites

  • 2 weeks later...

<script>


document.addEventListener('DataPageReady', _=> {
if (typeof(Storage) !== "undefined") {

document.querySelector('.cbSubmitButton').addEventListener('click', _=>{localStorage.clear()})

/* POPULATING FORM FROM LOCAL STORAGE*/

const populateAllInputsFromLocalStorage = _=> {
populateTextInputFromLocalStorage();
populateTextAreaInputFromLocalStorage();
populateCheckboxInputFromLocalStorage();
populateSelectInputFromLocalStorage();
populateComboBoxFromLocalStorage();
populateMultiSelectTextFromLocalStorage();
}

const populateMultiSelectTextFromLocalStorage = _=> {

window.setTimeout(_=>{
document.querySelectorAll('.cbFormMultiSelectText input').forEach(multiSelect=> {


let arrID = multiSelect.id.split('_')
    let parentID = multiSelect.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.nextElementSibling.getAttribute('name')
        let recordID = `${parentID}_${arrID[arrID.length-1]}`;

if(localStorage.getItem(recordID)!=null) {
    if(JSON.parse(localStorage.getItem(recordID)).value == 'true') {
    multiSelect.checked = true;
    }
 
}

})
}, 1000)
}


const populateComboBoxFromLocalStorage  = _=> {
window.setTimeout(_=>{
document.querySelectorAll('.cbComboBoxContainer [id*="ComboBoxInsertRecord"]').forEach(comboInput=> {

if(localStorage.getItem(comboInput.getAttribute('name'))!=null) {
comboInput.value = JSON.parse(localStorage.getItem(comboInput.getAttribute('name'))).value
}
})}, 1000)
  
}

const populateTextInputFromLocalStorage = _=> {

document.querySelectorAll('.cbFormTextField').forEach(textInput=> {

if(localStorage.getItem(textInput.getAttribute('name'))!=null) {
textInput.value = JSON.parse(localStorage.getItem(textInput.getAttribute('name'))).value

}
})
}

const populateTextAreaInputFromLocalStorage = _=> {

document.querySelectorAll('.cbFormTextArea').forEach(textInput=> {

if(localStorage.getItem(textInput.getAttribute('name'))!=null) {
textInput.value = JSON.parse(localStorage.getItem(textInput.getAttribute('name'))).value
}
})
}

const populateCheckboxInputFromLocalStorage = _=> {

document.querySelectorAll('[data-cb-name="cbFormDataCheckbox"] input').forEach(checkboxInput => {

if (localStorage.getItem(checkboxInput.getAttribute('id'))!=null) {
if (JSON.parse(localStorage.getItem(checkboxInput.getAttribute('id'))).value == "true") {
      checkboxInput.click()
}}
})
}


const populateSelectInputFromLocalStorage = _=> {

let prefix = 'selectInput';
document.querySelectorAll('.cbFormSelect').forEach(selectInput=> {

if(localStorage.getItem(prefix+selectInput.getAttribute('name'))!=null) {
selectInput.value = JSON.parse(localStorage.getItem(prefix+selectInput.getAttribute('name'))).value

}
})
}


populateAllInputsFromLocalStorage()

const setLocalStorageWithValuesFromEachInput = _=> {
console.log('setLocalStorageWithValuesFromEachInput')
setLocalStorageWithValuesFromTextInput();
setLocalStorageWithValuesFromAreaInput();
setLocalStorageWithValuesFromCheckboxInput();
setLocalStorageWithValuesFromSelectInput();
setLocalStorageWithValuesFromRadioInput();
setLocalStorageWithValuesFromComboBoxInput();
setLocalStorageWithValuesFromMultiSelectTextInput()
}

const setLocalStorageWithValuesFromMultiSelectTextInput = _=> {

document.querySelectorAll('.cbFormMultiSelectText input').forEach(multiSelect => {
    let arrID = multiSelect.id.split('_')
    let parentID = multiSelect.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.nextElementSibling.getAttribute('name')
    
    let recordID = `${parentID}_${arrID[arrID.length-1]}`;
    localStorage.setItem(recordID, `{"inputType": "multiSelectText", "value": "${multiSelect.checked}"}`);
})

}


const setLocalStorageWithValuesFromComboBoxInput = _=> {

document.querySelectorAll('.cbComboBoxContainer [id*=ComboBoxInsertRecord]').forEach(comboInput=> {
if(comboInput.value != undefined) { 
setLocalStorageFromInput(comboInput, 'combo input')}
 
})
}

const setLocalStorageWithValuesFromTextInput = _=> {

document.querySelectorAll('.cbFormTextField').forEach(textInput=>{
if(textInput.value != undefined) { 
setLocalStorageFromInput(textInput, 'text input')}
})
}

const setLocalStorageWithValuesFromAreaInput = _=> {
document.querySelectorAll('.cbFormTextArea').forEach(textInput=>{
if( textInput.value != undefined) { 
setLocalStorageFromInput(textInput, 'text area')}
})
}

const setLocalStorageWithValuesFromCheckboxInput = _=> {
document.querySelectorAll('[data-cb-name="cbFormDataCheckbox"] input').forEach(checkboxInput=>{
 
//  if(checkboxInput.checked) {}
  setLocalStorageFromInput(checkboxInput, 'checkbox')

})
}

const setLocalStorageWithValuesFromSelectInput = _=> {

document.querySelectorAll('.cbFormSelect').forEach(selectInput=>{
if(selectInput.value != undefined) { //textInput.value != '' && 
setLocalStorageFromInput(selectInput, 'select input')}
})
}

const setLocalStorageWithValuesFromRadioInput = _=> {
const radioButtonsContainer = document.querySelectorAll('[data-cb-name="cbFormDataRadios"]');
for (let i=0; i<radioButtonsContainer.length; i++) {
radioButtonsContainer[i].querySelectorAll('input').forEach(input=>{})
}


document.querySelectorAll('[data-cb-name="cbFormDataRadios"] input').forEach(radioInput => { 
if(selectInput.value != undefined) { //textInput.value != '' && 
setLocalStorageFromInput(selectInput, 'select input')}
})
}


const setLocalStorageFromInput = (inputElement, inputType) => {
  
  let inputId = inputElement.getAttribute('id');
  let inputName = inputElement.getAttribute('name');
 
 if(inputType == 'text input') {
    if(inputName !== inputId) {
    localStorage.setItem(inputName, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)  
    }
    else {
    localStorage.setItem(inputId, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)
    }
  }
  else if(inputType == 'text area') {
    if(inputName != inputId) {
    localStorage.setItem(inputName, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)  
    }
    else {
    localStorage.setItem(inputId, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)
    }
  }
  else if(inputType == 'checkbox') {
  localStorage.setItem(inputId, `{"inputType": "${inputType}", "value": "${inputElement.checked}"}`)
  }
  
  else if(inputType == 'select input') {
  localStorage.setItem('selectInput'+inputId, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)
  }

  else if(inputType == 'combo input') {
  localStorage.setItem(inputName, `{"inputType": "${inputType}", "value": "${inputElement.value}"}`)
  }
  
  

}

window.addEventListener('beforeunload', function (e) {

setLocalStorageWithValuesFromEachInput();

});


}

})

</script>
 

Link to comment
Share on other sites

@VolomeisterThis is working great, but I hit a snag. Do you know a solution for the following - The List-String fields are displaying the localstorage text when the form is refreshed, but the data in those fields isn't being stored once the form is submitted. Is there a way to get those list-string fields to "reselect" those options?

You can see this by selecting the first field on this form, refresh and then open up the dropdown again (see image too). Lewis and Clark County: Bright App/211/CONNECT Information (lccountymt.gov)

Multi Select.JPG

Link to comment
Share on other sites

Hi @wimtracking2

You can add this script into the footer of your page
 

<script>
new MutationObserver(records=>{
    for (let i=0; i<records.length-1;i++) {
        if(records[i].addedNodes.length > 0) {
          if(typeof(records[i].addedNodes[0].getAttribute) == 'function') {
            if(records[i].addedNodes[0].getAttribute('id') == 'MultiSelectBox') {
            let HTMLMultiSelectBox = records[i].addedNodes[0];
            window.setTimeout(_=>{
            let tempArr = HTMLMultiSelectBox.querySelector('input').getAttribute('id').split('_');
            let HTMLInputParentID = ''
            for(let i=0; i<tempArr.length-3;i++) {
            HTMLInputParentID+=tempArr[i] + '_'
            }
            if(HTMLInputParentID[HTMLInputParentID.length-1]=='_') {
            HTMLInputParentID = HTMLInputParentID.substring(0, HTMLInputParentID.length-1)
            }
        
            let currentValue = document.querySelector(`input[name*="ComboBox${HTMLInputParentID}"]`).value
            
            HTMLMultiSelectBox.querySelectorAll('input[type="checkbox"]').forEach( checkbox =>{
            if(currentValue.indexOf(checkbox.nextSibling.innerText) > -1 && checkbox.checked == false) {
            checkbox.click()
            }
            })
            
            
            }, 30)
            break;
        }}
      }}
}).observe(document.querySelector('body'), {childList: true, subtree: true })
</script>


It should fix this issue. Let me know if it worked

Link to comment
Share on other sites

  • 1 month later...
On 5/6/2022 at 5:29 AM, Volomeister said:

Hi @wimtracking2

You can add this script into the footer of your page
 

<script>
new MutationObserver(records=>{
    for (let i=0; i<records.length-1;i++) {
        if(records[i].addedNodes.length > 0) {
          if(typeof(records[i].addedNodes[0].getAttribute) == 'function') {
            if(records[i].addedNodes[0].getAttribute('id') == 'MultiSelectBox') {
            let HTMLMultiSelectBox = records[i].addedNodes[0];
            window.setTimeout(_=>{
            let tempArr = HTMLMultiSelectBox.querySelector('input').getAttribute('id').split('_');
            let HTMLInputParentID = ''
            for(let i=0; i<tempArr.length-3;i++) {
            HTMLInputParentID+=tempArr[i] + '_'
            }
            if(HTMLInputParentID[HTMLInputParentID.length-1]=='_') {
            HTMLInputParentID = HTMLInputParentID.substring(0, HTMLInputParentID.length-1)
            }
        
            let currentValue = document.querySelector(`input[name*="ComboBox${HTMLInputParentID}"]`).value
            
            HTMLMultiSelectBox.querySelectorAll('input[type="checkbox"]').forEach( checkbox =>{
            if(currentValue.indexOf(checkbox.nextSibling.innerText) > -1 && checkbox.checked == false) {
            checkbox.click()
            }
            })
            
            
            }, 30)
            break;
        }}
      }}
}).observe(document.querySelector('body'), {childList: true, subtree: true })
</script>


It should fix this issue. Let me know if it worked

This worked perfectly, thank you so much!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...