Ajax populated select elements conflicting with each other on ajax database insert call that retuns json

Viewed 72

I have a rather complicated form that allows the ability to add additional data (make, model, etc.) dynamically via a modal window that once the value is added via an ajax db insert call, the modal window is closed and jQuery is used to refresh the select element the data was added to. I have 5 of these type of select elements in use by my form.

Here's the problem, when I update a select element like explained above, when the modal window closes, all of the select elements on the page will refresh to the selected value of the select that completed the db insert. This id variable is the primary key of the data just inserted and will update the select list with the new value but also have the unintended side effect of making all the other select elements change to a non existing option (blank).

I've been trying to find a way for days to make it so that only the select that initiated the db insert would be the one to refresh, but I'm not sure how to do that. Could anyone point me in the right direction?

Here's my code:

JSON that populates select elements in the form:

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

JSON that is returned after db insert containing the new id from the db

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

Script that populates the select elements and handles select refreshes

$(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);
  }
}

The js ajax call that processes the modal form db insert

$(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
                });
           }
        });
    });
});

Example of html layout of the modal that contains the form (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 -->

Visuals: enter image description here enter image description here

All other selects updated when it should only update the one that was updated: enter image description here

Is it possible to only update that one select element and not all of them?

1 Answers

In your Modal on click of submit you can passed the id of modal in your refreshData function and depending on which modal is open you can change value of that select only .So, your code will look like below :

Your jquery submit event :

 ..
//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
  },
   ...
});

Your refreshData() will look like below :

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
      }
    }
  });
}
Related