Wenzz
Wenzz

Reputation: 378

jQuery sortable serialize not recognizing dynamically added content

I am trying to re-order a list via ajax on sortable update, however after adding a new item to this list via ajax after sortable has already been initialized on page load, it does not recognize the new item with the "serialize" function. It does allow me to drag it around as though it is working, but the code that gets sent with my update function is missing the new element.

//Sort categories
$('#categories-list').find('tbody').sortable({
  connectWith: 'tbody',
  opacity: 0.6,
  cursor: 'move',
  forcePlaceholderSize: true,
  update: function(e) {
    var serialized = $('#categories-list tbody').sortable('serialize');
    console.log(serialized);
    $.post('admin/ereg_forms/set_category_position', serialized, function(data) {
      if (data.status == 'error') {
        alert(data.message);
      }
    });

  }
});


//Add category submit
$("#add-category-submit").click(function(e) {
  e.preventDefault();

  $(".errors-block").html('');

  $('#add-category-submit').hide();

  $.ajax({
    url: $("#add-category-form").attr('action'),
    type: 'POST',
    data: $('#add-category-form').serialize(),
    dataType: 'json',
    success: function(data) {

      $('#add-category-submit').show();

      //Check if server side validation passed
      if (data.status == 'error') {
        //Show error on popup dialog
        $("#add-category-form .errors-block").html(data.message);
        alert('Sorry, the information that was sent is invalid. Please review the errors at the top of the form and try again.');
      } else {

        var category_data = data.data;

        var tableRow = '<tr class="category-row-' + category_data.id + '"><td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">&#8597;</span>' +
          '</td><td>' + category_data.title +
          '</td><td></tr>'

        $(tableRow).appendTo('#categories-list tbody');


        resetForm($('#add-category-form'));

        //Close popup window
        $('#add-category').dialog('close');

        $("<div title='Success!'>Category has been saved.</div>").dialog({
          modal: true,
          width: 'auto'
        });

      }

    },
    error: function(data) {
      alert('An unknown error has occurred, please try again.');
      $('#add-category-submit').show();
    }

  });
});
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>

<table class="data" id="categories-list">
  <thead>
    <tr>
      <th>&nbsp;</th>
      <th>Title</th>
    </tr>
  </thead>
  <tbody>
    <tr id="category-row-19">
      <td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">↕</span></td>
      <td class="category-row-title">test1</td>
    </tr>
    <tr id="category-row-20">
      <td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">↕</span></td>
      <td class="category-row-title">test</td>
    </tr>
  </tbody>
</table>

I have looked everywhere for a solution but have not found one that has worked. I have tried using the "refresh" function with sortable, I have tried initializing sortable inside of the success function of the ajax call to add new categories but it also does not work.

when I console.log(serialized) it only has the originally loaded elements in the array.

Upvotes: 0

Views: 398

Answers (2)

Wenzz
Wenzz

Reputation: 378

I ended up solving this problem, the issue was in the add category function I was applying the "class" attribute instead of using the "id" attribute for the category-row-{id}.

Upvotes: 0

Mark Schultheiss
Mark Schultheiss

Reputation: 34217

IDK what is going on, but this fake add works, perhaps you can emulate this? Note I cleaned up a couple syntax issues and used the ajax promise methods to better organize it.

I suggest you update your jQuery version, some better stuff in more recent versions with bug fixes.

//Sort categories
$('#categories-list').find('tbody').sortable({
  connectWith: 'tbody',
  opacity: 0.6,
  cursor: 'move',
  forcePlaceholderSize: true,
  update: function(e) {
    var serialized = $('#categories-list tbody').sortable('serialize');
    console.log(serialized);
    //  $.post('admin/ereg_forms/set_category_position', serialized, function(data) {
    //    if (data.status == 'error') {
    //     alert(data.message);
    //  }
    // });
  }
});
$('#addmorefool').on('click', AddMore);

function AddMore() {
  let tbody = $('#categories-list').find('tbody');
  let rowscount = tbody.find('tr').length;
  let newRow = '<tr id="category-row-' + rowscount + '"><td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">↕</span></td><td class="category-row-title">test' + rowscount + '</td></tr>';
  tbody.append(newRow);
}

AddMore();


//Add category submit
$("#add-category-sumbit").on('click', function(e) {
  //console.log("howdy");
  e.preventDefault();
  var myform = $("#add-category-form");
  var errorBlock = myform.find(".errors-block");
  errorBlock.html('');
  errorBlock.dialog({
    modal: true,
    width: 'auto',
    autoOpen: false
  });
  var catSub = $('#add-category-submit');
  catSub.hide();

  var myjax = $.ajax({
      url: myform.attr('action'),
      type: 'POST',
      data: myform.serialize(),
      dataType: 'json'
    })
    .done(function(data) {
      catSub.show();
      //Check if server side validation passed
      var category_data = data.data;
      var tableRow = $('<tr class="category-row-' + category_data.id + '"><td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">&#8597;</span>' +
        '</td><td>' + category_data.title +
        '</td><td></tr>');
      let tbody = $('#categories-list').find('tbody');
      tbody.append(tableRow);
      resetForm(myform);
      //Close popup window (out cause have none)
      //('#add-category').dialog('close');
      $("<div title='Success!'>Category has been saved.</div>").dialog({
        modal: true,
        width: 'auto'
      });
    }).fail(function(data) {
      //Show error on popup dialog
      errorBlock.html('<span>Sorry, the information that was sent is invalid. Please review the errors at the top of the form and try again.</span>' + data.message);
      errorBlock.dialog("open");
      //catSub.show(); (out cause not in code)
    });
});
tr td {
  border: 1px solid lime;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<div id="add-category-form" action="metoo">I am an empty form, so what
  <div class="errors-block">me error aggain? no way</div>
</div>
<table class="data" id="categories-list">
  <thead>
    <tr>
      <th>&nbsp;</th>
      <th>Title</th>
    </tr>
  </thead>
  <tbody>
    <tr id="category-row-19">
      <td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">↕</span></td>
      <td class="category-row-title">test1</td>
    </tr>
    <tr id="category-row-20">
      <td><span class="double-arrow-unicode" style="font-size:18px; cursor:pointer;">↕</span></td>
      <td class="category-row-title">test</td>
    </tr>
  </tbody>
</table>

<button id="addmorefool" type="button">Add More</button>
<div class="errors-block">me error</div>
<button type="button" id="add-category-sumbit">add category</button>

Upvotes: 1

Related Questions