【问题标题】:Ajax populated select elements conflicting with each other on ajax database insert call that retuns json在返回 json 的 ajax 数据库插入调用中,Ajax 填充的选择元素相互冲突
【发布时间】:2020-08-26 04:54:46
【问题描述】:

我有一个相当复杂的表单,它允许通过模态窗口动态添加其他数据(品牌、模型等),一旦通过 ajax db insert 调用添加值,模态窗口就会关闭并且 jQuery用于刷新添加数据的选择元素。我的表单使用了 5 个此类选择元素。

这就是问题所在,当我像上面解释的那样更新选择元素时,当模式窗口关闭时,页面上的所有选择元素都会刷新为完成数据库插入的选择的选定值。此 id 变量是刚刚插入的数据的主键,它将使用新值更新选择列表,但也会产生意想不到的副作用,即使所有其他选择元素更改为不存在的选项(空白)。

几天来,我一直在尝试寻找一种方法,以便只有启动数据库插入的选择才会刷新,但我不知道该怎么做。谁能指出我正确的方向?

这是我的代码:

在表单中填充选择元素的 JSON:

{"suppliers":{"1":"Amazon"},"manufacturers":{"1":"Apple"},"categories":{"2":"Tablet"},"status":{"1":"Ready to Deploy","2":"Deployed","3":"Damaged"}}

在 db insert 后返回的 JSON,包含来自 db 的新 id

{"success":true,"id":$id}

填充选择元素并处理选择刷新的脚本

$(document).ready(function() {
  refreshData();
});

function refreshData(newId) {
  $.ajax({
    url: '/json/collection.json',
    type: 'GET',
    dataType: 'json',
    success: function(data) {
      refreshSelect('inputSupplier', data.suppliers, newId);
      refreshSelect('inputManufacturer', data.manufacturers, newId);
      refreshSelect('inputStatus', data.status, newId);
      refreshSelect('inputCategory', data.categories, newId);
      refreshSelect('inputManufacturerModel', data.manufacturers); //modal window select element
    }
  });
}

function refreshSelect(name, data, newId) {
  // Select by id
  let $elem = $('#' + name);
  // Get current value
  let oldValue = $elem.val();
  // Get option with value 0, which is the first element
  let emptyOption = $elem.children('option').first();
  // Empty the element and add the option. We are back to initial state
  $elem.html(emptyOption);
  // Append elements retrieved from backend
  $.each(data, function(key, value) {
    $elem.append('<option value="' + key + '">' + value + '</option>');
  });
  if(newId){
      $elem.val(newId);
  }else{
      $elem.val(oldValue);
  }
}

处理模态表单db insert的js ajax调用

$(document).ready(function () //function to process modal form via ajax
{
    $('.modal-submit').on('submit', function(e){
        e.preventDefault(); //prevent default form submit action

        $(".backend-error").html(''); //clear out previous error messages
        $('input').removeClass('input-error'); //clear error border class

        var data = $(this).serialize();
        var type = $(this).find('input[name="type"]').val(); //get value of hidden input
        var url = $(this).attr('action'); //get action from form
        var modal = $(this).closest('.modal');
        var modalInput = $(this).find('.form-row input'); //get input from form
        var modalName = '#' + type + 'Modal'; //form modalName variable from var 'type'

        $.ajax({
           url:url,
           method:'POST',
           data:data,
           success:function(response){
                refreshData(newId = response.id); // set newId to the id of the newly inserted item
                modal.modal('hide'); //hide modal
                $(modalInput).val(''); //clear input value
           },
           error:function(e){
                $.each(e.responseJSON.error, function (i, error) {
                    $(modalInput).addClass('input-error');
                    $(modalName + ' .backend-error').html(error[0]); //return error from backend
                });
           }
        });
    });
});

包含表单的模态的 html 布局示例 (1 of 5)

<!-- Add New Supplier Modal -->
<div class="modal fade" id="supplierModal" tabindex="-1" role="dialog" aria-labelledby="supplierModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="supplierModalLabel">Add new asset supplier</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
            <form method="post" class="modal-submit" autocomplete="off" action="{{ action('AddAssetController@addDescriptor', ['type' => 'supplier']) }}">
                <input type="hidden" name="_token" value="{{ csrf_token() }}">
                <input type="hidden" name="type" value="supplier">
                <div class="form-row">
                    <div class="col-md-12 mb-3">
                        <label for="inputModelNew">Supplier name *</label>
                        <div class="input-group">
                            <input type="text" name="inputSupplierNew" id="inputSupplierNew" class="form-control" placeholder="Enter supplier name" required="required">
                        </div>
                        <div class="backend-error"></div>
                    </div>
                </div>
                <div class="float-right">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                    <button type="submit" class="btn btn-primary">Save changes</button>
                </div>
            </form>
            </div>
        </div>
    </div>
</div>
<!-- / Add New Supplier Modal -->

视觉效果:

当它应该只更新已更新的选择时,所有其他选择都已更新:

是否可以只更新一个选择元素而不是全部?

【问题讨论】:

    标签: javascript html jquery ajax laravel


    【解决方案1】:

    在您的Modal 中单击提交,您可以在refreshData 函数中传递模态的ID,并且根据打开的模态,您可以仅更改该选择的值。因此,您的代码将如下所示:

    您的 jquery 提交事件:

     ..
    //getting modal id i.e: supplierModal
    var modal_id = $(this).closest('.modal').attr('id');
    console.log(modal_id);
    $.ajax({
     ..
      success: function(response) {
        //passing id of modal
        refreshData(newId = response.id, modal_id ); // set newId to the id of the newly inserted item
        modal.modal('hide'); //hide modal
        $(modalInput).val(''); //clear input value
      },
       ...
    });
    

    您的refreshData() 将如下所示:

    function refreshData(newId, idofmodal) {
      $.ajax({
        url: '/json/collection.json',
        type: 'GET',
        dataType: 'json',
        success: function(data) {
        //checking value
          if (idofmodal != null) {
            if (idofmodal == "supplierModal") {
              refreshSelect('inputSupplier', data.suppliers, newId);
            } else if (idofmodal == "manufacturerModal") {
              refreshSelect('inputManufacturer', data.manufacturers, newId);
            }
            //same for other selects   
          } else {
            refreshSelect('inputSupplier', data.suppliers, newId);
            refreshSelect('inputManufacturer', data.manufacturers, newId);
            refreshSelect('inputStatus', data.status, newId);
            refreshSelect('inputCategory', data.categories, newId);
            refreshSelect('inputManufacturerModel', data.manufacturers); //modal window select element
          }
        }
      });
    }
    

    【讨论】:

    • 完美!非常感谢你帮我解决这个问题。如果设置了模式 ID,我所做的唯一更改是在 refreshData 函数中为模式 ID 使用 switch 语句,否则将运行常规 refreshSelect。
    猜你喜欢
    • 1970-01-01
    • 2015-06-30
    • 2013-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多