首页 > 解决方案 > 使用ajax调用重新加载数据后如何保存选中的复选框

问题描述

我定义了一个保管箱选择器,在选择一个国家后,它会给我一个城市列表作为复选框。我正在使用 jquery 和 ajax 来预览它并选择它,如下所示。

<div>
    <div id="preview-items">
    </div>
</div>

<script>
     $("#id_country").change(function () {
          var countryId = $(this).val();  // get the selected country ID from the HTML input

          $.ajax({  // initialize an AJAX request
            url: '/ajax/ajax_load_cities',
            data: {
                 'countries': countryId   // add the country id to the GET parameters
            },
            dataType: 'json',
            success: function (data) { // `data` is the return of the `load_cities` view function
             $('#preview-items').html('');
    
             for (var i in data.tags) {
                   $('#preview-items').append(`
                       <label class="btn btn-primary mr-1"> 
                       <input type="checkbox"  id="checklist_` + data.tags[i][0]+ `" value="` + data.tags[i][0] + `"> 
                       <span> 
                         ` + data.tags[i][1] + ` 
                       </span> 
                       </label><br />` 
                    ).find("#checklist_" + data.tags[i][0]).on("change", function(e){

                    var cities_array = $(":checkbox:checked").map( function() { return $(this).next().html(); }).get();
                    $("#preview-items").html(cities_array.join(', '));

                   if (e.target.checked) { 
                       localStorage.checked = true;
                    } else {
                        localStorage.checked = false; 
                    } 

              }
            }
           });
      });
</script>

在 Django 中view.py

def load_cities(request):
    ....
    
    data = {
        'tags': list(cities)
    }
    return JsonResponse(data)

问题是,更改国家/地区选择器后,它不会保留选定的城市。谷歌搜索后,我发现饼干是一个不错的选择。我想知道当 Dropbox 项目更改时如何保存选中的复选框?

标签: javascripthtmldjango

解决方案


我不认为你真的需要 cookie 或本地存储。我建议你采取另一种方法:

  • 首先,您创建基于状态构建保管箱选择器的 javascript 代码,在您的示例中为城市列表。
  • 然后,当您进行 ajax 调用时,您只需再次调用该函数。

window.onload = function() {
  var $container = $('#preview-items')  

  // when starting or loading the page I suggest either outputting the initial list
  // of unchecked data in your markup somewhere as a json object
  // or perform an initial ajax call. Here I just store it in a local variable.
  var initialData = [
    {id: 1, name: "Amsterdam", checked: false},
    {id: 2, name: "Berlin", checked: true},
    {id: 3, name: "Brussels", checked: false},
  ]
  
  buildDropbox(initialData)
  
  function buildDropbox(cities) {
    $container.empty()
    cities.forEach(function(city) {
      let checked = city.checked? "checked=\"checked\"" : ""
      $container.append(`
                       <label class="btn btn-primary mr-1" for="checklist_${city.id}"> 
                       <input type="checkbox" ${checked} id="checklist_${city.id}" value="${city.id}"> 
                       <span>${city.name}</span> 
                       </label><br />` 
      )
      var chk = document.getElementById("checklist_" + city.id)
      chk.addEventListener("change", function(e) {
        saveChange(e.currentTarget.name, e.currentTarget.value, e.currentTarget.checked)
      })
    }) 
  }
  
  function saveChange(chkName, chkValue, chkChecked) {
    console.log("POST ajax for " + chkValue + " with checked: " + chkChecked);
    // do your ajax call here, and in the success
    // be sure to return the same list as the
    // initialData, but with the updated 'checked'
    // value, obviously.
    // here, for testing purposes, I reuse the initialData
    // and check all checkboxes randomly
    let updatedData = initialData.map(function(c) {
      return {...c, checked: Math.round(Math.random()) == 0}
    })
    buildDropbox(updatedData)
  }
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>

  <script src="https://code.jquery.com/jquery-3.1.0.js"></script>
  
  <div id="preview-items"></div>
  
</body>
</html>


推荐阅读