【问题标题】:Form Values Returning Null in localStorage When Editing Selects Using Javascript?使用Javascript编辑选择时表单值在localStorage中返回Null?
【发布时间】:2021-04-09 19:09:37
【问题描述】:

我有一个向localStorage 发送数据的表单,我可以查看、删除和编辑该表单。我的表单混合了输入类型textselecttextarea,当我提交表单时,这些值会正确存储,但是当我使用编辑功能时,值会在编辑表单上正确显示,但如果我不会更改值(即使是相同的值),它们会更新/存储为null

例如: 我有一个带有名称(类型text)、地址(类型address)和狗品种(类型select)的表单,当我编辑时,所有三个的值都将来自之前的表单,但如果我点击提交而不更改任何内容,狗品种将返回null。如果我更改值,它们会正确更新,但由于这是一个约会调度程序,并非每个值都会更改(例如,它们可能只需要更改时间或品种)。

这是我的 sn-p - 我知道它不能完全运行,因为沙盒,但你可以看到:

const BREEDS_URL = 'https://dog.ceo/api/breeds/list/all';

const select = document.getElementById('breed');

fetch(BREEDS_URL)
  .then(res => {
    return res.json();
  })
  .then(data => {
    const breedsObject = data.message;
    const breedsArray = Object.keys(breedsObject);
    for (let i = 0; i < breedsArray.length; i++) {
      const option = document.createElement('option');
      option.value = breedsArray[i];
      option.innerText = breedsArray[i];
      select.appendChild(option);
    }
    console.log(breedsArray);
  });

// ~~~ add bookings to localStorage

var bookings = JSON.parse(localStorage.getItem("bookings")) || [];

window.onload = showBooking();
window.onload = showTimes();

$("#submit").click(function() {

  var newBookings = {
    id: new Date().getTime(),
    fname: $('#fname').val(),
    lname: $('#lname').val(),
    email: $('#email').val(),
    number: $('#number').val(),
    sdate: $('#sdate').val(),
    stime: $('#stime').val(),
    duration: $('#duration').val(),
    address: $('#address').val(),
    postcode: $('#postcode').val(),
    dogname: $('#dogName').val(),
    breed: $('#breed').val(),
    info: $('#info').val()
  }

  bookings.push(newBookings);

  var json = JSON.stringify(bookings);
  window.localStorage.setItem("bookings", json);

  alert('Form submitted!');
  showBooking();
});


$(document).on('click', '#edit', function(e) {
  e.preventDefault();

  var parent_form = $(this.form);

  var fname = parent_form.find('.fname').val();
  var lname = parent_form.find('.lname').val();
  var email = parent_form.find('.email').val();
  var number = parent_form.find('.number').val();
  var sdate = parent_form.find('.datepicker').val();
  var stime = parent_form.find('.select').val();
  var duration = parent_form.find('.duration').val();
  var address = parent_form.find('.address').val();
  var postcode = parent_form.find('.postcode').val();
  var dogname = parent_form.find('.dogname').val();
  var breed = parent_form.find('.breed').val();
  var info = parent_form.find('.info').val();

  let i = bookings.findIndex(booking => booking.id == $(this).data("id"));

  bookings[i].fname = fname;
  bookings[i].lname = lname;
  bookings[i].email = email;
  bookings[i].number = number;
  bookings[i].sdate = sdate;
  bookings[i].stime = stime;
  bookings[i].duration = duration;
  bookings[i].address = address;
  bookings[i].postcode = postcode;
  bookings[i].dogname = dogname;
  bookings[i].breed = breed;
  bookings[i].info = info;

  var json = JSON.stringify(bookings);
  window.localStorage.setItem("bookings", json);

  window.location.reload();

  alert('Form updated!');
  showBooking();

});


// ~~~ display bookings in browser

function showBooking() {
  var bookingResult = document.getElementById("result");
  var ul = document.createElement("ul");
  bookingResult.innerHTML = `<h3 class="text-center">Your Bookings</h3>`;
  for (let i = 0; i < bookings.length; i++) {
    bookingResult.innerHTML += `
<div class="card card-body bg-light  m-4"> 
<div class="row">
<p>${bookings[i].fname + " " + bookings[i].lname}</p>
</div>
<div class="row">
<div class="d-grid gap-2 d-md-block">
<button onclick="editBooking(${i})" class="col-md-4 btn btn-outline-danger ">Edit</button>
<button onclick="deleteBooking(${i})" class="col-md-4 btn btn-danger text-light ">Delete</button>
</div>
</div>                          
</div>`;
  }
}

// ~~~ edit bookings in browser

function editBooking(i) {
  $('#result').hide();
  var currentItem = document.getElementById("currentItem");
  var editBooking = document.getElementById("editAppt");

  currentItem.innerHTML += `
<h3 class="text-center">Currently Amending</h3>
<div class="card card-body bg-light  m-4"> 
<p data-id="${bookings[i].id}">${bookings[i].fname + " " + bookings[i].lname}</p>                    
</div>`;

  editBooking.innerHTML = `
<h3 class="text-center">Amend Your Booking</h3>
<div class="row">
<div class="col-md-6">
<input type="text" class="fname form-control required" data-id="${bookings[i].id}" placeholder="First Name" name="${bookings[i].fname}" value="${bookings[i].fname}">
</div>
<div class="col-md-6">
<input type="text" class="lname form-control required" data-id="${bookings[i].id}" placeholder="Last Name" name="${bookings[i].lname}" value="${bookings[i].lname}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="email" class="email form-control required" data-id="${bookings[i].id}" placeholder="Email Address" name="${bookings[i].email}" value="${bookings[i].email}">
</div>
<div class="col-md-6">
<input type="number" class="number form-control required" data-id="${bookings[i].id}" onchange="validateContact()" placeholder="Contact Number" name="${bookings[i].number}" value="${bookings[i].number}">
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="${bookings[i].sdate}" onchange="checkStartDate()" value="${bookings[i].sdate}">
</div>

<div class="col-md-6">
<select id="stime" name="${bookings[i].stime}" onfocus="showTimes()" class="time select form-control required" value="${bookings[i].stime}">${bookings[i].stime}
<option value="${bookings[i].stime}" selected disabled hidden>${bookings[i].stime}</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-6">
<select name="${bookings[i].duration}" class="duration form-control required" data-id="${bookings[i].id}"  value="${bookings[i].duration}">${bookings[i].duration}
<option value="${bookings[i].duration}" selected disabled hidden>${bookings[i].duration}</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}"  class="address form-control required" placeholder="Address" name="${bookings[i].address}" value="${bookings[i].address}">
</div>
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}"  class="postcode form-control " placeholder="Post Code"  name="${bookings[i].postcode}" value="${bookings[i].postcode}">
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="${bookings[i].dogname}" value="${bookings[i].dogname}">
</div>

<div class="col-md-6">
<select id="breed" class="breed form-control required" name="${bookings[i].breed}" value="${bookings[i].breed}">
<option value="${bookings[i].breed}" selected disabled hidden>${bookings[i].breed}</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-12">
<textarea id="info" name="info" class="info form-control required" placeholder="Any additional info - favourite toys or places?" name="${bookings[i].info}">${bookings[i].info}</textarea>
</div>
</div>

<div class="d-grid gap-2 d-md-block">
<input data-id="${bookings[i].id}" id="edit" class="btn btn-danger toggle-disabled" type="submit" value="Edit" disabled>
<a href="index.html" type="button" class="btn btn-outline-danger ">Cancel</a>
</div>

`;

}

function showTimes() {
  let startTime = document.getElementById('stime');

  let times = ['9:00', '9:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'];

  let options = times.map(time => `<option value="${time}">${time}</option>`).join('');

  startTime.innerHTML += options;
}

// ~~~ delete bookings from localStorage

function deleteBooking(i) {
  alert('Are you sure you want to delete this booking?');
  bookings.splice(i, 1);
  localStorage.setItem("bookings", JSON.stringify(bookings));

  showBooking();
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">

<section class="form row">
  <form id="regForm" name="regForm" action="" class="col-md-6">

    <div id="editAppt">
      <div class="row text-center">
        <h3>Book your dog walk now</h3>
        <p>Tell us about yourself first..</p>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="text" class="input form-control required" id="fname" placeholder="First Name" name="fname" required>
        </div>
        <div class="col-md-6">
          <input type="text" class="input form-control required" id="lname" placeholder="Last Name" name="lname" required>
        </div>
      </div>

      <div class="row text-center">
        <p>When should we pick your dog up?</p>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="date" id="sdate" class="datepicker form-control required" name="sdate" onchange="checkStartDate()" required>
        </div>

        <div class="col-md-6">
          <select name="duration" class="duration form-control required" id="duration" required>
            <option value="" selected disabled hidden>Duration</option>
            <option value="30 mins">30 mins</option>
            <option value="1 hour">1 hour</option>
            <option value="1.5 hours">1.5 hours</option>
            <option value="2 hours">2 hours</option>
          </select>
        </div>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname">
        </div>

        <div class="col-md-6">
          <select id="breed" class="breed form-control required">
            <option value="" selected disabled hidden>Select Breed</option>
          </select>
        </div>
      </div>


      <div class="col-md-6">
        <input id="submit" class="btn btn-danger toggle-disabled" type="submit" value="Submit">
      </div>
    </div>

  </form>

  <div class="col-md-6">
    <div id="result" class="row"></div>
    <div id="currentItem" class="row"></div>
  </div>

【问题讨论】:

  • 您的两行设置 window.onload 最终使其立即调用 showBooking()showTimes() 并将 window.onload 设置为这些调用的结果,即 undefined。阅读When do I use parenthesis and when do I not? 了解更多关于为什么这不起作用的信息。真的,你应该使用addEventListener 来添加事件监听器;然后您可以轻松添加多个调用。
  • 你只能有一个window.onload分配的功能。正如上面提到的异端,你正在将函数调用的结果分配给它......这不是一个函数。你做了两次。如果你想在load事件触发时同时执行这两个函数,我建议window.onload = function(){showBooking(); showTimes()}
  • 对不起,这只是一个大学项目,我只是在为一个班级学习 Javascript @HereticMonkey
  • 您的selects 有问题,因为您将先前选择的值作为selected disabled hidden 添加到列表中,然后添加其他选项。因此,如果用户之前选择了“1 小时”,则该选项将被选中、禁用和隐藏。因为它是disabled,所以它不会发布在表单帖子中。您需要为每个option 添加代码,检查其值是否为选定的值,如果是,则设置其selected 属性,或者在设置innerHTML 后,设置相应@ 的value 987654349@ 到 localStorage 中的值。
  • 哦,呵呵!是的,我删除了selected disabled hidden,嘿,快点更新了……真傻。我知道这将是一件愚蠢的事情。也感谢window.onload 的提示!

标签: javascript html jquery arrays local-storage


【解决方案1】:

您需要注意代码中的一些问题:

  • 首先,我会将所有内容都包装在来自 jQuery 的“document.ready”事件处理程序中:

    $(function() {
    ...
    });
    

    以上是简写,只是确保您的代码在所有 HTML 代码都被解析后运行。

    现在,需要注意的是,现在您的所有函数都不再位于全局范围内,因此您无法在 HTML 属性中引用它们,例如 onclick。因此,您需要使用 jQuery 或普通的旧 DOM 方法将它们附加到您的元素。

  • 您有两行设置了window.onload 属性。在下面的代码中,我将其更改为使用 jQuery 样式的事件处理程序附件。

  • 您将表单元素的 name 属性设置为已编辑约会的值,但 name 属性确实不需要经常更改。

$(function() {
      const BREEDS_URL = 'https://dog.ceo/api/breeds/list/all';

      function loadBreeds() {
        const select = document.getElementById('breed');

        fetch(BREEDS_URL)
          .then(res => {
            return res.json();
          })
          .then(data => {
            const breedsObject = data.message;
            const breedsArray = Object.keys(breedsObject);
            for (let i = 0; i < breedsArray.length; i++) {
              const option = document.createElement('option');
              option.value = breedsArray[i];
              option.innerText = breedsArray[i];
              select.appendChild(option);
            }
            console.log(breedsArray);
          });
      }
      // ~~~ add bookings to localStorage

      var bookings = JSON.parse(localStorage.getItem("bookings")) || [];

      $(window).on('load', function() {
        showBooking();
        showTimes();
        loadBreeds();
      });

      $("#submit").click(function() {

        var newBookings = {
          id: new Date().getTime(),
          fname: $('#fname').val(),
          lname: $('#lname').val(),
          email: $('#email').val(),
          number: $('#number').val(),
          sdate: $('#sdate').val(),
          stime: $('#stime').val(),
          duration: $('#duration').val(),
          address: $('#address').val(),
          postcode: $('#postcode').val(),
          dogname: $('#dogName').val(),
          breed: $('#breed').val(),
          info: $('#info').val()
        }

        bookings.push(newBookings);

        var json = JSON.stringify(bookings);
        window.localStorage.setItem("bookings", json);

        alert('Form submitted!');
        showBooking();
      });


      $(document).on('click', '#edit', function(e) {
        e.preventDefault();

        var parent_form = $(this.form);

        var fname = parent_form.find('.fname').val();
        var lname = parent_form.find('.lname').val();
        var email = parent_form.find('.email').val();
        var number = parent_form.find('.number').val();
        var sdate = parent_form.find('.datepicker').val();
        var stime = parent_form.find('.select').val();
        var duration = parent_form.find('.duration').val();
        var address = parent_form.find('.address').val();
        var postcode = parent_form.find('.postcode').val();
        var dogname = parent_form.find('.dogname').val();
        var breed = parent_form.find('.breed').val();
        var info = parent_form.find('.info').val();
        let i = bookings.findIndex(booking => booking.id == $(this).data("id"));

        bookings[i].fname = fname;
        bookings[i].lname = lname;
        bookings[i].email = email;
        bookings[i].number = number;
        bookings[i].sdate = sdate;
        bookings[i].stime = stime;
        bookings[i].duration = duration;
        bookings[i].address = address;
        bookings[i].postcode = postcode;
        bookings[i].dogname = dogname;
        bookings[i].breed = breed;
        bookings[i].info = info;

        var json = JSON.stringify(bookings);
        window.localStorage.setItem("bookings", json);

        window.location.reload();

        alert('Form updated!');
        showBooking();

      });

      $(document).on('change', '.datepicker', checkStartDate);
      $(document).on('change', '.number', validateContact);
      $(document).on('focusin', '.time', showTimes);
      $(document).on('click', '.edit-booking', function(e) {
        var index = +$(this).data('index');
        editBooking(index);
      });
      $(document).on('click', '.delete-booking', function(e) {
        var index = +$(this).data('index');
        deleteBooking(index);
      });


      // ~~~ display bookings in browser

      function showBooking() {
        var bookingResult = document.getElementById("result");
        var ul = document.createElement("ul");
        bookingResult.innerHTML = `<h3 class="text-center">Your Bookings</h3>`;
        for (let i = 0; i < bookings.length; i++) {
          bookingResult.innerHTML += `
<div class="card card-body bg-light  m-4"> 
<div class="row">
<p>${bookings[i].fname + " " + bookings[i].lname}</p>
</div>
<div class="row">
<div class="d-grid gap-2 d-md-block">
<button data-index="${i}" class="edit-booking col-md-4 btn btn-outline-danger ">Edit</button>
<button data-index="${i}" class="delete-booking col-md-4 btn btn-danger text-light ">Delete</button>
</div>
</div>                          
</div>`;
        }
      }

      // ~~~ edit bookings in browser

      function editBooking(i) {
        $('#result').hide();
        var currentItem = document.getElementById("currentItem");
        var editBooking = document.getElementById("editAppt");

        currentItem.innerHTML += `
<h3 class="text-center">Currently Amending</h3>
<div class="card card-body bg-light  m-4"> 
<p data-id="${bookings[i].id}">${bookings[i].fname + " " + bookings[i].lname}</p>                    
</div>`;

        editBooking.innerHTML = `
<h3 class="text-center">Amend Your Booking</h3>
<div class="row">
<div class="col-md-6">
<input type="text" class="fname form-control required" data-id="${bookings[i].id}" placeholder="First Name" name="fname" value="${bookings[i].fname}">
</div>
<div class="col-md-6">
<input type="text" class="lname form-control required" data-id="${bookings[i].id}" placeholder="Last Name" name="lname" value="${bookings[i].lname}">
</div>
</div>
<div class="row">
<div class="col-md-6">
<input type="email" class="email form-control required" data-id="${bookings[i].id}" placeholder="Email Address" name="email" value="${bookings[i].email}">
</div>
<div class="col-md-6">
<input type="number" class="number form-control required" data-id="${bookings[i].id}" placeholder="Contact Number" name="number" value="${bookings[i].number}">
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="date" id="sdate" class="datepicker form-control required" name="sdate" value="${bookings[i].sdate}">
</div>

<div class="col-md-6">
<select id="stime" name="stime" class="time select form-control required" value="${bookings[i].stime}">
<option value="${bookings[i].stime}">${bookings[i].stime}</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-6">
<select name="duration" class="duration form-control required" data-id="${bookings[i].id}"  value="${bookings[i].duration}">
<option value="${bookings[i].duration}">${bookings[i].duration}</option>
<option value="30 mins">30 mins</option>
<option value="1 hour">1 hour</option>
<option value="1.5 hours">1.5 hours</option>
<option value="2 hours">2 hours</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}"  class="address form-control required" placeholder="Address" name="address" value="${bookings[i].address}">
</div>
<div class="col-md-6">
<input type="text" data-id="${bookings[i].id}"  class="postcode form-control " placeholder="Post Code"  name="postcode" value="${bookings[i].postcode}">
</div>
</div>

<div class="row">
<div class="col-md-6">
<input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname" value="${bookings[i].dogname}">
</div>

<div class="col-md-6">
<select id="breed" class="breed form-control required" name="breed" value="${bookings[i].breed}">
<option value="${bookings[i].breed}">${bookings[i].breed}</option>
</select>
</div>
</div>

<div class="row">
<div class="col-md-12">
<textarea id="info" name="info" class="info form-control required" placeholder="Any additional info - favourite toys or places?" name="info">${bookings[i].info}</textarea>
</div>
</div>

<div class="d-grid gap-2 d-md-block">
<input data-id="${bookings[i].id}" id="edit" class="btn btn-danger toggle-disabled" type="submit" value="Edit" disabled>
<a href="index.html" type="button" class="btn btn-outline-danger ">Cancel</a>
</div>

`;
        loadBreeds();

      }

      function showTimes() {
        let startTime = document.getElementById('stime');

        let times = ['9:00', '9:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00'];

        let options = times.map(time => `<option value="${time}">${time}</option>`).join('');

        startTime.innerHTML += options;
      }

      // ~~~ delete bookings from localStorage

      function deleteBooking(i) {
        alert('Are you sure you want to delete this booking?');
        bookings.splice(i, 1);
        localStorage.setItem("bookings", JSON.stringify(bookings));

        showBooking();
      }

    });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
<link rel="stylesheet" href="css/style.css">

<section class="form row">
  <form id="regForm" name="regForm" action="" class="col-md-6">

    <div id="editAppt">
      <div class="row text-center">
        <h3>Book your dog walk now</h3>
        <p>Tell us about yourself first..</p>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="text" class="input form-control required" id="fname" placeholder="First Name" name="fname" required>
        </div>
        <div class="col-md-6">
          <input type="text" class="input form-control required" id="lname" placeholder="Last Name" name="lname" required>
        </div>
      </div>

      <div class="row text-center">
        <p>When should we pick your dog up?</p>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="date" id="sdate" class="datepicker form-control required" name="sdate" required>
        </div>

        <div class="col-md-6">
          <select name="duration" class="duration form-control required" id="duration" required>
            <option value="" selected disabled hidden>Duration</option>
            <option value="30 mins">30 mins</option>
            <option value="1 hour">1 hour</option>
            <option value="1.5 hours">1.5 hours</option>
            <option value="2 hours">2 hours</option>
          </select>
        </div>
      </div>

      <div class="row">
        <div class="col-md-6">
          <input type="text" id="dogName" class="dogname form-control required" placeholder="Dogs Name" name="dogname">
        </div>

        <div class="col-md-6">
          <select id="breed" class="breed form-control required">
            <option value="" selected disabled hidden>Select Breed</option>
          </select>
        </div>
      </div>


      <div class="col-md-6">
        <input id="submit" class="btn btn-danger toggle-disabled" type="submit" value="Submit">
      </div>
    </div>

  </form>

  <div class="col-md-6">
    <div id="result" class="row"></div>
    <div id="currentItem" class="row"></div>
  </div>

【讨论】:

  • 我会删除deleteBooking函数吗?
  • 抱歉刚刚意识到..忽略了它。
  • 预订不再显示在页面加载中..?
  • 我已经分叉了你的 CodePen,它似乎可以工作:codepen.io/heretic-monkey/pen/PoGRBXz
  • 似乎@HereticMonkey 创造了一些魔力!哈哈。无论如何,他已经在我面前指出了一些问题。所以我按我说的做,就是删除我的答案。但是关于要附加的长 innerHTML 字符串......无论如何都要寻找我的other today's answer。这将为您节省很多问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 2016-02-18
相关资源
最近更新 更多