Search code examples
javascriptjqueryhtmltablesorter

Tablesorter changes row position when editing row item, even if disabled


I've got a weird bug going on in my App and hope someone might know a solution.

My Problem: I've a movie table with different rows, I use the jquery tablesorter plugin from Mottie to sort my items and filter them. Each row also has it's own Edit button, where when you click on it the the td's get editable, now the problem is that when I edit lets say the movie title, then click on the movie director to change his name, the whole row jumps down and it does that all the time until the row is at the bottom. When I remove the tablesorter function everything works correctly, but when it's active, it does this weird bug. Now I tried to just disable the tablesorter on click (following this solution), but that also didn't help me. The sorting and the filter got disabled, but it still pushed my whole row down. Here's a gif to visualize the problem:

enter image description here

Note: The movie title, date, director and runtime are all < p > and < input > tags, on click on the edit button the < p > tags get hidden and the < input >'s get visible. I used this method because I need to give my new data to my django model somehow, maybe thats part of the problem.

Also I have a hidden row, that shows up when I click on the Description, don't know if thats important as well.

I'd like to provide a jsfiddle, but I didn't manage to reproduce this bug in jsfiddle, it only appears in my app :/

Here's the important code of the app:

HTML

<table id="movieTable" class="table-hover tablesorter">
<thead class="table-head">
          <tr>
               <th data-sorter="false"></th>
               <th>TITLE</th>
               <th class="gen">GENRE</th>
               <th>RELEASE DATE</th>
               <th>DIRECTOR</th>
               <th>DESCRIPTION</th>
               <th>RUNTIME</th>
               <th>STATUS</th>
               <th>IMDB</th>
               <th data-sorter="false" id="buttons-head-bottom"></th>
          </tr>
</thead>
<tbody>
<td>
    <a href=“/myapp/evil-dead/">
        <input class="input-title hide" value="Evil Dead" form="movie1" name="title"/> <!— hidden on default —>
        <p class="movie-title">Evil Dead</p>
    </a>
</td>
<td>
    <select class="hide input-genre-select" form="movie1" name="genre"> <!— hidden on default —>
    <!— options code —>
    </select>
    <p class="movie-genre">Horror</p>
</td>
<td>
    <input class="hide input-release" value="25.04.2013" form="movie1" name="date" size="10"/> <!— hidden on default —>
    <p class="movie-release">25.04.2013</p>
</td>
<td>
    <input class="hide input-director" value="Fede Alvarez" form="movie1" name="director"/> <!— hidden on default —>
    <p class="movie-director">Fede Alvarez</p>
</td>
<td class="desc-pointer toggle" data-toggle="collapse" data-target=".description1"> <!— collapse and shows a hidden table row when clicked —>
    Description <i class="fa fa-caret-right"></i>
</td>
<td>
    <input class="hide input-runtime" value="91" form="movie1" name="runtime" maxlength="4" size="4"/> <!— hidden on default —>
    <p class="movie-runtime">91 min</p>
</td>
<td>
    <select class="hide input-status-select" form="movie1" name="status"> <!— hidden on default —>
    <!— options code —>
    </select>
    <p class="movie-status">Bought and watched</p>
</td>
<td>6,5</td>
<td>
    <!— edit button, is hidden when clicked on it —>
    <button type="button" class="edit-btn">
        <i class="fa fa-pencil-square"></i>
    </button>
    <!— hidden on default, shows up when clicked on edit-btn —>
    <button type="submit" form="movie1" class="save-btn">
        <i class="save-btn fa fa-save"></i>
    </button>
    <!-- delete button -->
    <button id="del-btn1" type="button" class="delete-btn btn btn-default" data-toggle="modal" data-target="#deleteModal1">
        <i class="fa fa-remove"></i>
    </button>
</td>
</tbody>
</table>

I only provided one table row here, but every other row is build the same.

Javascript

// table sorter

$(function(){
    const $table = $("#movieTable").tablesorter({
        dateFormat: "ddmmyyyy",
        headers: {
            2: { sorter: "select" },
            3: { sorter: "shortDate" },
            7: { sorter: "select" },
        },
        widgets: ["filter"],
        widgetOptions : {
            filter_columnFilters: false,
        }
    });

    $.tablesorter.filter.bindSearch( $table, $('.search') );

});

 // edit button

$(".edit-btn").click(function() {

    $('table')
    .unbind('appendCache applyWidgetId applyWidgets sorton update updateCell')
    .removeClass('tablesorter')
    .find('thead th')
    .unbind('click mousedown')
    .removeClass('header headerSortDown headerSortUp');

    const parent = $(this).parent().parent()
    parent.find(".input-director, .input-runtime, .input-release, .input-title").addClass("highlight");
    parent.find(".movie-title, .movie-genre, .movie-release, .movie-director, .movie-runtime, .movie-status").addClass("hide");
    parent.find(".input-title, .input-genre-select, .input-release, .input-director, .input-runtime, .input-status-select").removeClass("hide");
    parent.find(".edit-btn").hide();
    parent.find(".save-btn").show();

    $(".gen").addClass("genre-padding");
    $(".title-link").bind("click", function(e) {
        e.preventDefault();
    })
})

If needed I can provide more code, but I hope this is enough for someone to find a solution to this bug. Like I said before, the only solution I had found was to remove the tablesorter plugin, disabling it didn't help.

Thanks to anyone who is trying!


Solution

  • It's not a bug, it's a feature! :D

    Internally the plugin is set up to automatically resort when an update is triggered; although, I don't see it being used in the code that was shared. To get around this "feature", set the resort option to false.