YannickHelmut
YannickHelmut

Reputation: 555

Create jquery plugin : run only once per selector

I'm trying to create a plugin suited for my needs which adds some functions to tables. There are of course thousands of plugins like dataTables.js etc. but a lightweight solution is more suitable for what I'm trying to do.

Problem(s): If there are 2 tables or more, the code runs multiple times on each table and of course if you filter one table, paginate one table and change the page of each... it applies to all.

Any help would be appreciated and if you have improvement ideas they're welcome ! Once I'm done I will publish this on github if anyone is interested in a simple version of datatables... !

https://jsfiddle.net/ygery/gm02mvpk/

function tableOptions(selector, paginate, npages, filter, responsive) {

  var $table = $(selector);
  var currentPage = 0;

  function tablePaginate() {
    $table.bind('paginate', {
      pages: npages
    }, function(event) {
      $('.pagination').remove();
      // if(npages != )
      //alert(event.data.pages);
      var $row = $table.find('tbody tr:not(.hidden)').addClass('row-pagination');
      $row.hide()
      $row.slice(currentPage * npages, (currentPage + 1) * npages).show();
      var numRows = $table.find('.row-pagination').length;

      var numPages = Math.ceil(numRows / npages);
      var $pager = $('<ul class="pagination"></ul>');

      $('<li class="table-prev"></li>').html('<a href="#"><</a>').bind('click', {
        prevPage: currentPage - 1
      }, function(event) {
        if (currentPage != 0) {
          currentPage = event.data['prevPage'];
          $table.trigger('paginate');
          $(this).addClass('active').siblings().removeClass('active');
          $(this).hide();
        }

      }).appendTo($pager).addClass('clickable');

      for (var page = 0; page < numPages; page++) {
        $('<li class="table-page" data-page=' + parseInt(page + 1) + '></li>').html('<a href="#">' + parseInt(page + 1) + '</a>').bind('click', {
          newPage: page
        }, function(event) {

          currentPage = event.data['newPage'];
          //$table.trigger('paginate');
          $(this).addClass('active').siblings().removeClass('active');
        }).appendTo($pager).addClass('clickable');
      }

      $('<li class="table-next"></li>').html('<a href="#">></a>').bind('click', {
        nextPage: currentPage + 1
      }, function(event) {
        if (currentPage != numPages - 1) {
          currentPage = event.data['nextPage'];
          //$table.trigger('paginate');
          $(this).addClass('active').siblings().removeClass('active');
        }

      }).appendTo($pager).addClass('clickable');


      $pager.insertAfter($table);
      if (currentPage == 0) {
        $('.table-prev').addClass('disabled').attr('onclick', 'event.preventDefault();');
      }
      if (currentPage == numPages - 1) {
        $('.table-next').addClass('disabled').attr('onclick', 'event.preventDefault();');
      }
      $('li[data-page="' + parseInt(currentPage + 1) + '"]').addClass('active');

      if (numPages > 5) {
        var $this = parseInt(currentPage + 1);
        $('.table-page').hide();
        if (currentPage == 0) {
          currentPage = currentPage + 1;
        }
        for (var page = currentPage; page < currentPage + 2; page++) {
          $('.table-page[data-page="' + parseInt(page + 1) + '"]').show();
          if (page == currentPage + 1) {
            var dots = '<li class="disabled" onclick="event.preventDefault();"><a href="#">...</a></li>';
            $('.table-page[data-page="' + parseInt(page + 1) + '"]').after(dots);
          }
        }
        for (var page = currentPage; page > currentPage - 1; page--) {
          $('.table-page[data-page="' + parseInt(page) + '"]').show();
          //if(page == currentPage+1) {
          //  var dots = '<li class="disabled" onclick="event.preventDefault();"><a href="#">...</a></li>';
          //  $('.table-page[data-page="'+parseInt(page - 1)+'"]').after(dots);
          //}
        }
      }

    });
    $table.trigger('paginate');
  }

  function tableFilter() {
    $(".table-search").keyup(function() {
      $('li[data-page="1"]').click();
      var input = $(this);
      var $row = $table.find('tbody tr');
      var $cell = $row.find('td');

      if (input.val() != '') {
        $row.addClass('hidden').removeClass('row-pagination');
        $($cell).each(function(i, obj) {
          if ($(obj).find('input').length) {
            var $content = $(obj).find('input').val().toLowerCase().indexOf(input.val().toLowerCase());
          } else {
            if ($(obj).find('select').length) {
              var $content = $(obj).find('select option:selected').text().toLowerCase().indexOf(input.val().toLowerCase());
            } else {
              if ($(obj).text().length) {
                var $content = $(obj).text().toLowerCase().indexOf(input.val().toLowerCase());
              } else {
                var $content = $(obj).html().toLowerCase().indexOf(input.val().toLowerCase());
              }
            }

          }
          if ($content > -1 && input.val()) {
            $(obj).parent().removeClass('hidden');
            $(obj).parent().addClass('row-pagination');
          }
        });
        $table.trigger('paginate');

      } else {
        $table.find('tr').removeClass('hidden').addClass('row-pagination');
        $table.trigger('paginate');
      }

    });
  }

  function tableResponsive() {
    $(window).resize(function() {
      if ($(window).width() < 767) {
        if (!$('.responsive-toggle').length) {
          $table.find('thead tr th:first-child').before('<td class="responsive-toggle"><i class="glyphicon glyphicon-phone"></i></td>');
          $table.find('tbody tr td:first-child').before('<td class="responsive-toggle"><i class="glyphicon glyphicon-menu-down"></i></td>');

        }
        var max = $table.width();
        //alert(max);
      } else {
        $('.responsive-toggle').remove();
      }
    }).resize();


  }

  $table.each(function() {
    if (paginate || filter) {
      var $header = '<div class="col-sm-2 table-pagination-select"></div><div class="col-sm-6 table-options"></div><div class="col-sm-4 table-search-input"></div><hr />';
      $table.before($header);
      $table.wrap('<div class="col-md-12"></div>');
    }
    if (paginate) {
      var $target = $('.table-pagination-select');
      var $select = '<select name="" id="" class="form-control table-select"><option value="10">10</option><option value="25">25</option><option value="50">50</option><option value="100">100</option><option value="all">Tous</option></select>';
      $($select).appendTo($target);
      //$('.table-select').select2();
      tablePaginate();
    }
    if (filter) {
      var $target = $('.table-search-input');
      var $searcher = '<input type="text" class="form-control table-search" placeholder="Rechercher..." />';
      $($searcher).appendTo($target);
      tableFilter();
    }
    if (responsive) {
      tableResponsive();
    }



  })

}

tableOptions('.table', true, 10, true, true);

Upvotes: 0

Views: 67

Answers (1)

jcubic
jcubic

Reputation: 66490

You can set data on jQuery object:

function tableOptions(selector, paginate, npages, filter, responsive) {

  var $table = $(selector);
  if ($table.data('table')) {
     return;
  } else {
     $table.data('table', true);
  }

Upvotes: 1

Related Questions