【问题标题】:Regularly send POST request when user changes value in <textarea>当用户更改 <textarea> 中的值时定期发送 POST 请求
【发布时间】:2020-12-25 00:26:59
【问题描述】:

我创建了一个表单,用户在其中将一些食物名称放在 textarea 的菜单中,然后他/她可以按下按钮提交此表单并发送 POST 请求。提交后,来自 textareas 的所有数据(其中有 20 个)正在发送到 mongoDB。它工作得很好。 问题是:用户填写所有 20 个文本区域需要时间,所以我想做某种“自动保存”,以防浏览器停止工作或发生其他错误并防止数据丢失。 每次在 textarea 中发生更改时,都必须将数据发送到数据库。如何在不点击提交按钮且仅通过更改 textarea 值的情况下从表单发送 POST 请求。

<form method="POST" action="/">
  <table>
    <caption style="margin-bottom: 20px; font-size: 2em"><b>MENÜÜ</b></caption>

    <tr>
      <td style="column-span: 2; border: none; font-size: 0.8em">ESMASPÄEV</td>
    </tr>
    <tr>
      <td class="hommikusook">Hoomikusöök</td>
      <td class="userinput"><textarea name="MondayBreakfast" class="textarea" placeholder="Kirjuta siia" autofocus></textarea></td>
    </tr>
    <tr>
      <td class="vitamiiniamps">Vitamiiniamps</td>
      <td class="userinput"><textarea name="MondayVitamin" class="textarea" placeholder="Kirjuta siia"></textarea>
      </td>
    </tr>
    <tr>
      <td class="louna">Lõunasöök</td>
      <td class="userinput"><textarea name="MondayLunch" class="textarea textarealong" placeholder="Kirjuta siia"></textarea></td>
    </tr>
    <tr>
      <td class="oode">Oode</td>
      <td class="userinput"><textarea name="MondayOode" class="textarea" placeholder="Kirjuta siia"></textarea>
      </td>
    </tr>
  </table>
  <button type="submit">Submit</button>
</form>

我尝试在前端 JS 文件中添加 eventListener,我设法在每次更改 textarea 时控制台记录这些值,但不知道如何将它们发送到后端,因此我可以将其添加到数据库。

var numberOfTextAreas = document.querySelectorAll('.textarea').length;

for (var i = 0; i < numberOfTextAreas; i++) {
   document.querySelectorAll(".textarea")[i].addEventListener("change", function () {

      console.log('New value: ', this.value);
      console.log('Name: ', this.name);
      
   });
}

后端使用快递。

谢谢!

【问题讨论】:

    标签: javascript html node.js database mongodb


    【解决方案1】:

    您需要使用 fetch API 或 AJAX。所以每次用户改变你都要调用这个函数:

    async function postData(url = '', data = {}) {
      const response = await fetch(url, {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });
      return response.json();
    }
    
    // Then you call the function like this:
    postData('https://example.com/autosave', { text: 'This is the text I want to save' })
      .then(data => {
        // Autosaved successfully!
      });

    我建议在每次用户模糊文本区域时对这个函数进行去抖动或调用它(性能原因)。

    【讨论】:

    • 嗨@andrés-figueira。使用 React 创建这样的表单不是更好吗?
    • @IvanLastovko 是的,当然。如果您将使用 React,我建议您使用 Formik 来管理表单
    【解决方案2】:

    自动保存表单组件正在使用onchange(和/或onkeyup和/或onkeydown)属性来注册事件并调用保存方法。

    另外,还有触发很多请求的问题。这个可以通过setTimeout and clearTimeout解决;

    代码看起来像这样(伪代码):

    //HTML
    
    <form method="POST" action="/" name="myForm">
       <textarea name="textareaName_1" onchange="handleAutoSave"></textarea>
       <textarea name="textareaName_2" onchange="handleAutoSave"></textarea>
       ...
    </form>
    
    // JS
    var autoSaveProgress = null;
    function handleAutoSave() {
    
       var formData = new FormData(document.querySelector('[name]="myForm"'));
    
       // cancel last request
       if(autoSaveProgress){
         autoSaveProgress();
         autoSaveProgress = null;
       }
    
       autoSaveProgress = setTimeout(function() {
         saveToLocalstorage('KEY', formData);
       } ,1000); // 1s delay till commit 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-07
      • 2016-06-02
      • 1970-01-01
      • 2019-09-03
      相关资源
      最近更新 更多