javascriptjqueryfiledirectorytablesort

how to sort folders and files in a table with jquery javascript


For a filemanagement, I have 2 columns:

name in which are Folders(directories) and Files

extension which give me the extension of the files (folders empty extension)

When I click on the name, it sorts the files and folders alphabetically. But it does not sort the folders first. when I click on extension, it sorts the folders first, but not alphabetically.

What I want to achieve:

  1. Sort folders first and also alphabetically.
  2. The sort should be default when page is loaded, so not after click event

The html:

<table>
  <thead>
    <tr>
      <th class="name header-item"><a id="name" class="filter-link" href="#">Name</a></th>  
      <th class="extension header-item"><a id="extension" class="filter-link" href="#">Ext</a></th>
    </tr>
  </thead>
  <tbody class="table-content">
    <tr class="table-row">
      <td class="table-data">bbb</td>
      <td class="table-data"></td>
    </tr>
    <tr class="table-row">
      <td class="table-data">ccc.jpg</td>
      <td class="table-data">jpg</td>
    </tr>
    <tr class="table-row">
      <td class="table-data">aaa.jpg</td>
      <td class="table-data">jpg</td>
    </tr>
    <tr class="table-row">
      <td class="table-data">ccc</td>
      <td class="table-data"></td>
    </tr>
    <tr class="table-row">
      <td class="table-data">bbb.jpg</td>
      <td class="table-data">jpg</td>
    </tr>
    <tr class="table-row">
      <td class="table-data">aaa</td>
      <td class="table-data"></td>
    </tr>
  </tbody>
</table>

The jquery:

var properties = [
  'name',
  'extension'
];

    $.each( properties, function( i, val ) {

        var orderClass = '';

        $(document).on('click','#' + val,function(e) {  

            e.preventDefault();
            $('.filter-link.filter-link-active').not(this).removeClass('filter-link-active').children('i').show();
            $(this).toggleClass('filter-link-active');
            $('.filter-link').removeClass('asc desc').children('i').show();

            if(orderClass == 'desc' || orderClass == '') {
                $(this).addClass('asc');
                $(this).children('i').hide();                   
                    orderClass = 'asc';
            } else {
                $(this).addClass('desc');
                $(this).children('i').hide();                   
                orderClass = 'desc';
            }

            var parent = $(this).closest('.header-item');
            var index = $(".header-item").index(parent);
            var $table = $('.table-content');
            var rows = $table.find('.table-row').get();
            var isSelected = $(this).hasClass('filter-link-active');
            var isNumber = $(this).hasClass('filter-link-number');

            rows.sort(function(a, b){

                var x = $(a).find('.table-data').eq(index).text();
                    var y = $(b).find('.table-data').eq(index).text();

                if(isNumber == true) {

                    if(isSelected) {
                        return x - y;
                    } else {
                        return y - x;
                    }

                } else {

                    if(isSelected) {        
                        if(x < y) return -1;
                        if(x > y) return 1;
                        return 0;
                    } else {
                        if(x > y) return -1;
                        if(x < y) return 1;
                        return 0;
                    }
                }
            });

            $.each(rows, function(index,row) {
                $table.append(row);
            });

            return false;
        });

    });

How can I achieve this?

Here is a fiddle of the code: https://jsfiddle.net/82j0k3eu/


Solution

  • var properties = [ 'name', 'extension' ];

    $.each( properties, function( i, val ) {
    
        var orderClass = '';
        var folders = files = ''; /* declare empty variables */
    
        $(document).on('click','#' + val,function(e) {  
    
            e.preventDefault();
            $('.filter-link.filter-link-active').not(this).removeClass('filter-link-active').children('i').show();
            $(this).toggleClass('filter-link-active');
            $('.filter-link').removeClass('asc desc').children('i').show();
    
            if(orderClass == 'desc' || orderClass == '') {
                $(this).addClass('asc');
                $(this).children('i').hide();                   
                    orderClass = 'asc';
            } else {
                $(this).addClass('desc');
                $(this).children('i').hide();                   
                orderClass = 'desc';
            }
    
            var parent = $(this).closest('.header-item');
            var index = $(".header-item").index(parent);
            var $table = $('.table-content');
            var rows = $table.find('.table-row').get();
            var isSelected = $(this).hasClass('filter-link-active');
            var isNumber = $(this).hasClass('filter-link-number');
    
            rows.sort(function(a, b){
    
                var x = $(a).find('.table-data').eq(index).text();
                    var y = $(b).find('.table-data').eq(index).text();
    
                if(isNumber == true) {
    
                    if(isSelected) {
                        return x - y;
                    } else {
                        return y - x;
                    }
    
                } else {
    
                    if(isSelected) {        
                        if(x < y) return -1;
                        if(x > y) return 1;
                        return 0;
                    } else {
                        if(x > y) return -1;
                        if(x < y) return 1;
                        return 0;
                    }
                }
            });
    
            $.each(rows, function(index,row) {
                if $(this).children('td').eq(1).text() == '' /* check if there's an extension, no extension = folder */
                folders += row;
                else files += row
            });
    
            $table.append(folders);
            $table.append(files);
    
            return false;
        });
    
    });