Как я могу сохранить все входные значения страницы и позволить пользователю просматривать изменения при перезагрузке страницы?

1

Я создаю онлайн-журнал пули с многочисленными входами на странице. Входы не входят в элемент.

Я хочу сохранить все входы в локальное хранилище. Входы можно просмотреть, когда страница загружена. Я не хочу кнопку "отправить", если только кнопка "отправить" не является единственным.

В приведенном ниже коде содержатся ошибки, которые могут привести к сбою программы. Помогите исправить ошибки.

//here are my inputs
let eventInputList = [];
let calendarInputList = [];
let checkInputList = [];
let taskInputList = [];
let weekFormDateOne = document.getElementById("week-date-one");
let weekFormDateTwo = document.getElementById("week-date-two");
let textInputList = document.getElementsByTagName("textarea");

const getArrayElements = (array) => {
    for(let i = 0; i < array.length; i++){
        return array[i];
    };
 };

//here is my variable containing all the input values
let allInputsValues = monthInput.value + 
getArrayElements(eventInputList) + getArrayElements(calendarInputList) 
+ getArrayElements(checkInputList) + getArrayElements(taskInputList) + 
weekFormDateOne.value + weekFormDateTwo.value + 
getArrayElements(textInputList);


//here is my localStorage function
const saveAllEntries = () => {
    localStorage.setItem("allInputs", JSON.stringify(allInputsValues));
};

window.addEventListener("input", saveAllEntries);

const loadAllEntries = () => {
    localStorage.getItem("allInputs");
};

window.addEventListener("load", loadAllEntries);
  • 0
    Пожалуйста, объясните, что значит doesn't work
  • 0
    Это означает, что в коде нет ошибок, по крайней мере, консоль, похоже, не видит ничего, но когда я набираю что-то на своих входах и обновляю страницу, то, что я набрал, исчезает.
Показать ещё 2 комментария
Теги:
arrays
input
local-storage

4 ответа

0

Функциональное программирование

Мое объяснение может быть неловким, потому что самые простые вещи всегда труднее всего объяснить должным образом, поэтому, если кто-то испытывает головную боль, читая это, пожалуйста, оставьте полезный комментарий либо к этому объяснению, либо к коду.

Следующая демонстрация - моя серьезная попытка функционального программирования:

  • частичное применение путем преобразования функций с несколькими параметрами с функциями с меньшими параметрами.

  • чистые функции, которые всегда принимают аргументы и возвращают один и тот же результат.

  • повторное использование функций путем возврата значения или передачи в качестве аргумента значения другой функции.


демонстрация

Plunker

Подробности комментируются в демоверсии
Примечание. Этот фрагмент кода не полностью функционален из-за мер безопасности SO, которые блокируют использование localStorage. Для функциональной демонстрации, перейдите на этот Plunker.

<!DOCTYPE html>
<html>

<head>
  <meta charset='utf-8'>
  <style>
    html {font: 400 16px/1.5 Consolas;}
    body {font-size: 1rem;}
    form, form * {font: inherit;}
    fieldset {width: fit-content; height: auto; margin: 5px;}
    legend {font-size: 1.25rem;}
    input, output, textarea, button {display: inline-block; margin: 2.5px;}
    [for=send] {display: inline-block; margin-left: 10px;} 
    #send {vertical-align: middle;}
    #submit {margin-left: 190px;}
    [name=response] {display: block; width:430px; margin:5px}
    .col {display: table; font-size: 0; min-width: fit-content;}
    .col label {display: table-row; font-size: 1rem; line-height: 1;}
    label b {display: table-cell; color: blue; width: 50px;}
    label u, label mark {display: table-cell; color: red; min-width: 60px;}
  </style>
</head>

<body>
  <!--Sends data to a live test server on submit event unless #send is unchecked
 (see below)-->
  <!--Server response will be redirected to iframe[name=response] (see below)-->
  <form id='main' action='https://httpbin.org/post' method='post' target='response'>

    <fieldset class='set'>
      <legend>Set 1</legend>
      <input id='i0' name='i0'>
      <input id='i1' name='i1'><br>
      <input id='i2' name='i2'>
      <input id='i3' name='i3'><br>
      <textarea id='t0' name='t0' rows='2' cols='42'></textarea>
    </fieldset>

    <fieldset class='set'>
      <legend>Set 2</legend>
      <input id='i4' name='i4'>
      <input id='i5' name='i5'><br>
      <input id='i6' name='i6'>
      <input id='i7' name='i7'><br>
      <textarea id='t1' name='t1' rows='2' cols='42'></textarea>
    </fieldset>

    <label for='send'>Send Data </label>
    <!--If not sending data to test server, uncheck #send-->
    <input id='send' type='checkbox' value=null>
    <button type='submit' class='submit'>Send</button>
    <button type='reset' class='reset'>Clear</button>
    <!--If sending data to server, this will display response in JSON format-->
    <iframe src='about:blank' name='response'></iframe>
    
    <fieldset class='col'>
      <!--output#view will display all saved data-->
      <output id='view' value=null></output>
    </fieldset>
    
  </form>

  <script>
    /*
    These parameters are the only ones needed
    [KEY]: const alias = value // param | type 
    */
    const form = document.forms[0]; // e.currentTarget for submit/reset | DOM Object
    const list = form.elements; // NodeList | NodeList
    const key = "formData"; // keyName | String
    const msg = list.view; // DOMText | DOM Object
    const rsp = frames['response'].document.body // Expression in submit/reset | DOM Object   
    
    /* 
    Takes a NodeList (list|NodeList) converts it into an array then returns 
    function saveData() while passing a new array of objects (dataArray|array), 
    and carries over a string (key|keyName) and a DOM Object (msg|DOMText).
    */
    function collectData(NodeList, keyName, DOMText) {
      const dataArray = Array.from(NodeList).map((tag, index) => {
        let item = {};
        item.id = tag.id || tag.className;
        item.value = tag.value || false;
        return item;
      });
      return saveData(dataArray, keyName, DOMText);
    };
    
    /* 
    Takes dataArray from function collectData() and saves it in localStorage 
    under a given string (key|keyName)
    Returns function viewData() while passing dataArray 
    and carrying over a keyName and DOMText.
    */
    function saveData(dataArray, keyName, DOMText) {
      localStorage.setItem(keyName, JSON.stringify(dataArray));
      return viewData(dataArray, DOMText);
    };
    
    /*
    Takes keyName and returns dataArray from localStorage if it exists
    If it doesn't exist, it will notify user
    */    
    function getData(keyName) {
      const dataArray = JSON.parse(localStorage.getItem(keyName));
      if (!dataArray) {
        DOMText.innerHTML = 'There is no data stored under the key name ${key}.';
      } else {
        return dataArray;
      }
      return false;
    };
    
    /*
    Takes dataArray and DOMText
    Extracts each object from dataArray then extracts both properties from each object
    Returns each property and value pair displayed in DOMText
    */
    function viewData(dataArray, DOMText) {
      DOMText.innerHTML = " ";
      dataArray.forEach((item, index) => {
        Object.keys(item).forEach((property, count) => {
          let subLine;
          index = index > 9 ? index : "0" + index;
          if (count === 0) {
            subLine = '
              <label>
                <b>${index}&boxV;${property}:</b><u>${item[property]}</u>
              </label>'
          } else if (count === 1 && index === dataArray.length -1) {
            subLine = '
              <label>
                <b>${property}:</b><u>N/A</u>
              </label>';
          } else if (count === 1 && !item[property]) {
            subLine = '
              <label>
                <b>${property}:</b><u>${item[property]}</u>
              </label><hr>';
          } else if (count === 1 && item[property]) {
            subLine = '
              <label>
                <b>${property}:</b><u><mark>${item[property]}</mark></u>
              </label><hr>';
          } else {
            subLine = '<label><u>ERROR</u></label>';
          }
          return DOMText.insertAdjacentHTML('beforeend', subLine);
        });
      });
      return false;
    };
    
    /*
    Takes dataArray and NodeList
    The NodeList is converted to an array of DOM Objects (DOMArray/array)
    Next each object is extracted from dataArray then each objects values are extracted
    and then assigned to the appropriate DOM Object found in DOMArray
    Returns function viewData() while passing dataArray and carries DOMText
    */
    function setData(dataArray, NodeList, DOMText) {
      const DOMArray = Array.from(NodeList);
      dataArray.forEach((item, index) => {
        Object.values(item).forEach((value, count) => {
          const tag = DOMArray[index];
          if (count === 1 && value) {
            tag.value = value;
          } else {
            tag.value = "";
          }
        });
      });
      return viewData(dataArray, DOMText);
    };
    
    /*
    This event listener populates the form controls with saved values after a 
    submit/reset event.
    During a page load when DOMContentLoaded event occurs, function getData() is
    passed to function setData().
    */
    document.addEventListener('DOMContentLoaded', (e) => {
        const data = getData(key);
        setData(data, list, msg);
    });
    
    /* 
    This event listener collects, saves, and displays form values on a submit event
    Checks whether the data should be sent to test server
    Calls function collectData()
    */
    form.addEventListener('submit', (e) => {
      const sending = list.send.checked;
      if (!sending) {
        e.preventDefault();
        rsp.innerHTML = 'As requested, data was not sent.';
      } 
      collectData(list, key, msg);
    });
    /*
    This event listener resets the form removes the saved data from localStorage
    and where it displayed.
    */
    form.addEventListener('reset', (e) => {
      rsp.innerHTML = 'All saved data has been deleted.';
      msg.innerHTML = " ";
      localStorage.removeItem(key);
    });

  </script>
</body>

</html>

Рекомендации

парадигма

FP: Частичное применение
FP: чистые функции
Функции высшего порядка

термины

Элементы управления формой: <button>, <fieldset>, <input>, <output>, <textarea>
NodeList

API, методы и свойства

HTMLFormControlsCollection API
.elements
кадры
Array.from()
.карта()
Объектные литералы
LocalStorage
JSON.stringify() & JSON.parse()
.для каждого()
Object.keys() & Object.values()
Событие DOMContentLoaded
отправить и сбросить события
.insertAdjacentHTML() &.innerHTML

0

Всего несколько наблюдений. Возможно, я не понимаю ваш вопрос и не пытаюсь оскорбить ваш интеллект, написав основную информацию. о локальном ходу.

1) Использование input события в элементе окна записывает все данные страницы в local storage для каждого пользовательского взаимодействия в любом отдельном элементе, например, при вводе или удалении одной буквы. Это неэффективно. Событие change, вероятно, будет лучшим выбором, и оно будет назначено каждому отдельному элементу ввода, а не окну, и вызовет функцию, которая записывает только эти данные элементов в локальное хранилище, а не все данные на странице.

Вы также можете подумать о том, что происходит, когда пользователь набирает что-то, а затем выходит или обновляет страницу до того, как отредактированный элемент потеряет фокус. Событие change может не срабатывать до тех пор, пока элемент ввода не потеряет фокус, и последнее изменение перед выходом или обновлением не будет записано в локальное хранилище. Вы можете добавить дополнительные события для этих случаев или добавить кнопку "Сохранить изменения", которая сохраняет все данные страницы при щелчке. Кнопка отправки не требуется.

2) Вам не нужно конкатенировать все данные на странице в одну строку JSON или даже использовать строку JSON. Прямо сейчас вы используете только одну пару имя-значение. Вы можете использовать несколько пар имя-значение в локальном хранилище, по одному для каждой переменной массива или даже по одному для каждого элемента каждого массива, а другое для длины. Например, одно имя для calendarInputList, где значение представляет собой массив, преобразованный в текст; или calendarInputList_1, calendarInputList_2, calendarInputList_3,... и calendarInputList_len для длины, так что у вас есть много пар имя-значение.

В случае одного имени для каждого элемента массива вам следует быть осторожным в отслеживании пользовательских изменений, таких как удаление calendarInputList_2, потому что тогда все значения calendarInputList_2 через наивысшее имя индекса в локальном хранилище должны быть обновлены, Имя calendarInputList_3 станет calendarInputList_2, calendarInputList_4 станет calendarInputList_3, calendarInputList_5 станет calendarInputList_4 и т.д., Включая уменьшение значения calendarInputList_len на 1. Если вы выбрали этот маршрут, вы можете просто удалить и перезаписать все элементы, пройдя через локальное хранилище и удалив все имена, начинающиеся с "calendarInputList_", а затем запись новых элементов массива.

Если вы хотите использовать одну пару имя-значение, возможно, сделать allInputsValues объектом. Таким образом, структура будет сохранена между строкой и синтаксическим разбором.

3) Какой бы маршрут вы ни выбрали, вам нужен способ вернуть данные из локального хранилища обратно в ваши переменные и на страницу. Если вы используете JSON.stringify, вам нужно использовать JSON.parse. Независимо от того, используете ли вы JSON stringify и parse, во всех случаях вам нужно получить данные из локального хранилища и записать его в переменную и/или записать на экран. Ваш опубликованный код не анализирует строку JSON, не расшифровывает строку в ее составные части и не записывает эти части в переменные или экран. В настоящее время, например, как вы знаете, где внутри allInputsvalues calendarInputList [3] позиционируется?

Когда страница загружается, и если локальное хранилище сохраняется, после того, как allInputsValues извлекается из локального хранилища, вы должны разбить его и записать каждую часть в соответствующую область на экране.

0

Вы пробовали разобрать содержимое своего локального хранилища и снова установить его в var?

 const loadAllEntries = () => {
      allInputsValues = JSON.parse(localStorage.getItem("allInputs"));
 }
  • 0
    Да, я только что попробовал, все еще не работает :( хотя спасибо!
0

Я бы начал с массива id

var ids = ["id1", "id2", "id3"];

ids.map((id) => {
     if(localstorage.get(id) != null){
         document.getElementById(id).value = localstorage.get(id);
     }
});

Это проверяет локальное хранилище на значения и заполняет их. Затем вам нужно добавить слушателя изменений на каждый вход.

inputChanged(event){
   localstorage.put(event.target.id, event.value)
}

Это будет хранить значения в локальном хранилище каждый раз при изменении ввода.

Наконец, я набрал это с головы. Я сомневаюсь, что код можно скопировать. Вам нужно будет исправить это.

  • 0
    Для чего нужны идентификаторы?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню