Dynamic Table with options

Multi select

by Zuhaib Siddiqui

HTML

<table id="table_1">
  <tr><td>1 SELECT ME</td></tr>
  <tr><td>2 SELECT ME</td></tr>
  <tr><td>3 SELECT ME</td></tr>
  <tr><td>4 SELECT ME</td></tr>
  <tr><td>5 SELECT ME</td></tr>
  <tr><td>6 SELECT ME</td></tr>
</table>
Seleceted: <span>0</span>
<table id="table_2">
  <tr><td>1 SELECT ME</td></tr>
  <tr><td>2 SELECT ME</td></tr>
  <tr><td>3 SELECT ME</td></tr>
  <tr><td>4 SELECT ME</td></tr>
</table>

<!-- start: Context Menu for Table -->
                                <ul id="contextMenu" class="context-menu" role="menu" style="display:none;" >
                                    <li><a tabindex="-1" href="#">Action</a></li>
                                    <li><a tabindex="-1" href="#">Another action</a></li>
                                    <li><a tabindex="-1" href="#">Something else here</a></li>
                                    <li class="divider"></li>
                                    <li><a tabindex="-1" href="#">Separated link</a></li>
                                </ul>
                                <!-- end: Context Menu for Table -->

CSS

.selected{
  background-color:#cfcfcf;
}
.context-menu{
  background:#fff;
  padding:10px;
  list-style:none;
}

JavaScript

///// Multi Select Table Plugin
(function($) {
// selekt jQuery plugin // http://stackoverflow.com/a/35813513/383904
$.fn.selekt = function() {
  var settings = $.extend({
      children: "tbody tr",
      className: "selected",
      onSelect: function(){}
  }, arguments[0] || {});
  return this.each(function(_, that){
    var $ch = $(this).find(settings.children), sel = [], last;
    $ch.on("mousedown", function(ev) {
      if(ev.shiftKey || ev.ctrlKey) ev.preventDefault();
      var ti = $ch.index(this),
          li = $ch.index(last),
          ai = $.inArray(this, sel);
      $(sel).removeClass(settings.className);
      if(ev.ctrlKey) {
        if(ai > -1) sel.splice(ai, 1);
        else sel.push(this);
      }
      else if(ev.shiftKey && sel.length > 0) {
        if(ti > li) ti = [li, li=ti][0];
        sel = $ch.slice(ti, li+1);
      }
      else {
        sel = ai<0 || sel.length>1 ? [this] : [];
      }
      last = this;
      $(sel).addClass(settings.className);
      settings.onSelect.call(that, sel);
    });
  });
};
}(jQuery));

// Use like:
// $("table").selekt();
//
// Available options:
$("table").selekt({
  children  : "tr",             // Elements to target (default: "tbody tr")
  className : "selected",       // Desired CSS class  (default: "selected")
  onSelect  : function( sel ) { // Useful callback
     $("span").text( sel.length +' in '+ this.id );
  }
});

///// Context Menu (Show on right click)
(function ($, window) {
    $.fn.contextMenu = function (settings) {
        return this.each(function () {
            // Open context menu
            $(this).on("contextmenu", function (e) {
                // return native menu if pressing control
                if (e.ctrlKey) return;
                
                //open menu
                var $menu = $(settings.menuSelector)
                    .data("invokedOn", $(e.target))
                    .show()
                    .css({
                        position: "absolute",
      ...