Search code examples
jqueryfunctionhtml-tablecustom-data-attributevertical-scrolling

How can I scroll my horizontally scrollable table to a certain position by click on data attribute?


By click on a certrain date on the left side (for example 2018-04-03) I wish that my table is scrolling to that positon (in that case Apr 03). My approach is not working out. This means, only when I click on "Project 1" my table is scrolling to a position.

jQuery(document).ready(function() {
  jQuery(".main-table").clone(true).appendTo('#table-scroll').addClass('clone');
});

 var side_width = $( ".fixed-side" ).width()+262;


$("body").on("click", function(e) {
  // the coordinate you clicked
  var x = e.clientX
  var y = e.clientY
  
  // all th.fixed-side in cloned table (include thead and tbody)
  var fixedSide = $('table.clone th.fixed-side')

  // calculate the height of cloned table's tbody
  // var tableHeight = fixedSide.get(0).offsetHeight * fixedSide.length - 1;

  // only first th in tbody
  var tableHeight = fixedSide.get(0).offsetHeight;

  // th's width
  var offsetWidth = fixedSide.get(0).offsetWidth;

  // calculate offsetTop and offsetLeft from body
  var offset = getOffset(fixedSide.get(0))
  
  // skip thead's th
  offset.Top += fixedSide.get(0).offsetHeight;

  // check if click inside the range
  var inRange = (x >= offset.Left && x <= offset.Left + offsetWidth) &&
    (y >= offset.Top && y <= offset.Top + tableHeight)

  if (inRange) {
       var date = $(e.target).closest('tr').find("[data-date]").data("date");
        var result = $('[data-date="'+date+'"]').offset().left;
        $('.table-wrap').scrollLeft(result - side_width); 
       alert("successfull scrolled to "+date);
  }
});

function getOffset(element) {
  var offsetTop = 0;
  var offsetLeft = 0;
  do {
    offsetTop += element.offsetTop;
    offsetLeft += element.offsetLeft;
  } while (element = element.offsetParent);
  var offset = {
    Left: offsetLeft,
    Top: offsetTop,
  }
  return offset;
}
.table-scroll {
  position: relative;
  margin: auto;
  overflow: hidden;
}

.table-wrap {
  width: 100%;
  overflow: auto;
}

.table-scroll table {
  width: 100%;
  margin: auto;
  border-collapse: separate;
  border-spacing: 0;
}

.table-scroll th,
.table-scroll td {
  padding: 5px 10px;
  white-space: nowrap;
  vertical-align: top;
}

.clone {
  position: absolute;
  top: 0;
  left: 0;
  pointer-events: none;
}

.clone th,
.clone td {
  visibility: hidden
}

.clone td,
.clone th {
  border-color: transparent
}

.clone tbody th {
  visibility: visible;
}

.clone .fixed-side {
  visibility: visible;
  background-color: #fff;
  font-weight: normal;
  border: none;
  border-right: 2px solid #f4f4f4;
}

.clone thead,
.clone tfoot {
  background: transparent;
}

.gantt-h {
  font-weight: normal;
  color: #b0b0b0;
  border-right: 2px solid #f4f4f4;
}

.last {
  border-right: 2px solid #f4f4f4;
}

.gantt td {
  border-right: 2px solid #f4f4f4;
}

.today {
  background-color: pink;
  width: 100px;
  cursor: pointer
}

.fixed-side{
cursor:pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>



<div id="table-scroll" class="table-scroll">
  <div class="table-wrap">
    <table class="main-table table gantt">
      <thead>
        <tr>
          <th class="fixed-side" scope="col" class="left-h" style="border-bottom:2px solid #f4f4f4;color:#b0b0b0">Task</th>

          <th scope="col" class="gantt-h" style="font-weight:normal;color:#b0b0b0;">30 Mar</th>
          <th scope="col" class="gantt-h">31 Mar</th>
          <th scope="col" class="gantt-h">01 Apr</th>
          <th scope="col" class="gantt-h">02 Apr</th>
          <th scope="col" class="gantt-h">03 Apr</th>
          <th scope="col" class="gantt-h">04 Apr</th>
          <th scope="col" class="gantt-h">05 Apr</th>
          <th scope="col" class="gantt-h">06 Apr</th>
          <th scope="col" class="gantt-h">07 Apr</th>
          <th scope="col" class="gantt-h">08 Apr</th>
          <th scope="col" class="gantt-h">09 Apr</th>
          <th scope="col" class="gantt-h">10 Apr</th>
          <th scope="col" class="gantt-h">11 Apr</th>
          <th scope="col" class="gantt-h">12 Apr</th>
          <th scope="col" class="gantt-h">13 Apr</th>
          <th scope="col" class="gantt-h">14 Apr</th>
          <th scope="col" class="gantt-h">15 Apr</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th data-name="Projekt 1" class="fixed-side project"><i class="fa fa-folder-open-o" style="color:#9e9e9e"></i> Projekt 1</th>

             <td data-row="1" data-date="2018-03-30"></td>
          <td data-row="1" data-date="2018-03-31"></td>
          <td data-row="1" data-date="2018-04-01"></td>
          <td data-row="1" data-date="2018-04-02"></td>
          <td data-row="1" data-date="2018-04-03"></td>
          <td data-row="1" data-date="2018-04-04"></td>
          <td data-row="1" data-date="2018-04-05"></td>
          <td data-row="1" data-date="2018-04-06"></td>
          <td data-row="1" data-date="2018-04-07"></td>
          <td data-row="1" data-date="2018-04-08"></td>
           <td data-row="1" data-date="2018-04-09"></td>
         <td data-row="1" data-date="2018-04-10"></td>
          <td data-row="1" data-date="2018-04-11"></td>
           <td data-row="1" data-date="2018-04-12"></td>
           <td data-row="1" data-date="2018-04-13"></td>
          <td data-row="1" data-date="2018-04-14"></td>
          <td data-row="1" data-date="2018-04-15"></td>
        </tr>
        <tr>
          <th data-date="2018-04-02" class="fixed-side" style="padding-left:27px"><i class="fa fa-file-o" style="color:#9e9e9e"></i> 2018-04-02</th>
           <td data-row="2" data-date="2018-03-30"></td>
          <td data-row="2" data-date="2018-03-31"></td>
          <td data-row="2" data-date="2018-04-01"></td>
          <td data-row="2" data-date="2018-04-02"></td>
          <td data-row="2" data-date="2018-04-03"></td>
          <td data-row="2" data-date="2018-04-04"></td>
          <td data-row="2" data-date="2018-04-05"></td>
          <td data-row="2" data-date="2018-04-06"></td>
          <td data-row="2" data-date="2018-04-07"></td>
          <td data-row="2" data-date="2018-04-08"></td>
           <td data-row="2" data-date="2018-04-09"></td>
         <td data-row="2" data-date="2018-04-10"></td>
          <td data-row="2" data-date="2018-04-11"></td>
           <td data-row="2" data-date="2018-04-12"></td>
           <td data-row="2" data-date="2018-04-13"></td>
          <td data-row="2" data-date="2018-04-14"></td>
          <td data-row="2" data-date="2018-04-15"></td>
        </tr>
        <tr>
          <th data-date="2018-04-03" class="fixed-side" style="padding-left:27px"><i class="fa fa-file-o" style="color:#9e9e9e"></i> 2018-04-03</th>

          <td data-row="3" data-date="2018-03-30"></td>
          <td data-row="3" data-date="2018-03-31"></td>
          <td data-row="3" data-date="2018-04-01"></td>
          <td data-row="3" data-date="2018-04-02"></td>
          <td data-row="3" data-date="2018-04-03"></td>
          <td data-row="3" data-date="2018-04-04"></td>
          <td data-row="2" data-date="2018-04-05"></td>
          <td data-row="3" data-date="2018-04-06"></td>
          <td data-row="3" data-date="2018-04-07"></td>
          <td data-row="3" data-date="2018-04-08"></td>
           <td data-row="3" data-date="2018-04-09"></td>
         <td data-row="3" data-date="2018-04-10"></td>
          <td data-row="3" data-date="2018-04-11"></td>
           <td data-row="3" data-date="2018-04-12"></td>
           <td data-row="3" data-date="2018-04-13"></td>
          <td data-row="3" data-date="2018-04-14"></td>
          <td data-row="3" data-date="2018-04-15"></td>
        </tr>
        <tr>
          <th data-date="2018-04-01" class="fixed-side" style="padding-left:27px"><i class="fa fa-file-o" style="color:#9e9e9e"></i> 2018-04-01</th>
 <td data-row="2" data-date="2018-03-30"></td>
          <td data-row="4" data-date="2018-03-31"></td>
          <td data-row="4" data-date="2018-04-01"></td>
          <td data-row="4" data-date="2018-04-02"></td>
          <td data-row="4" data-date="2018-04-03"></td>
          <td data-row="4" data-date="2018-04-04"></td>
          <td data-row="4" data-date="2018-04-05"></td>
          <td data-row="4" data-date="2018-04-06"></td>
          <td data-row="4" data-date="2018-04-07"></td>
          <td data-row="4" data-date="2018-04-08"></td>
           <td data-row="4" data-date="2018-04-09"></td>
         <td data-row="4" data-date="2018-04-10"></td>
          <td data-row="4" data-date="2018-04-11"></td>
           <td data-row="4" data-date="2018-04-12"></td>
           <td data-row="4" data-date="2018-04-13"></td>
          <td data-row="4" data-date="2018-04-14"></td>
          <td data-row="4" data-date="2018-04-15"></td>
        </tr>
        <tr>
          <th data-date="2018-04-04" class="fixed-side" style="padding-left:27px"><i class="fa fa-file-o" style="color:#9e9e9e"></i> 2018-04-04</th>
 <td data-row="2" data-date="2018-03-30"></td>
          <td data-row="5" data-date="2018-03-31"></td>
          <td data-row="5" data-date="2018-04-01"></td>
          <td data-row="5" data-date="2018-04-02"></td>
          <td data-row="5" data-date="2018-04-03"></td>
          <td data-row="5" data-date="2018-04-04"></td>
          <td data-row="5" data-date="2018-04-05"></td>
          <td data-row="5" data-date="2018-04-06"></td>
          <td data-row="5" data-date="2018-04-07"></td>
          <td data-row="5" data-date="2018-04-08"></td>
           <td data-row="5" data-date="2018-04-09"></td>
         <td data-row="5" data-date="2018-04-10"></td>
          <td data-row="5" data-date="2018-04-11"></td>
           <td data-row="5" data-date="2018-04-12"></td>
           <td data-row="5" data-date="2018-04-13"></td>
          <td data-row="5" data-date="2018-04-14"></td>
          <td data-row="5" data-date="2018-04-15"></td>
        </tr>
        <tr>
          <th data-date="2018-04-02" class="fixed-side" style="padding-left:27px"><i class="fa fa-file-o" style="color:#9e9e9e"></i> 2018-04-02</th>
         <td data-row="6" data-date="2018-03-30"></td>
          <td data-row="6" data-date="2018-03-31"></td>
          <td data-row="6" data-date="2018-04-01"></td>
          <td data-row="6" data-date="2018-04-02"></td>
          <td data-row="6" data-date="2018-04-03"></td>
          <td data-row="6" data-date="2018-04-04"></td>
          <td data-row="6" data-date="2018-04-05"></td>
          <td data-row="6" data-date="2018-04-06"></td>
          <td data-row="6" data-date="2018-04-07"></td>
          <td data-row="6" data-date="2018-04-08"></td>
           <td data-row="6" data-date="2018-04-09"></td>
         <td data-row="6" data-date="2018-04-10"></td>
          <td data-row="6" data-date="2018-04-11"></td>
           <td data-row="6" data-date="2018-04-12"></td>
           <td data-row="6" data-date="2018-04-13"></td>
          <td data-row="6" data-date="2018-04-14"></td>
          <td data-row="6" data-date="2018-04-15"></td>
        </tr>
      </tbody>

    </table>
  </div>
</div>


Solution

  • var tableHeight is the issue. You have set it to the height of only the first th in tbody and that is exactly where your intended functionality is working i.e. Projekt 1. (Seems like you missed updating it since you have duly put a comment on top of it stating the same).

    Because of that, your clicks are not being evaluated to being inRange. You can confirm that by changing

    var inRange = (x >= offset.Left && x <= offset.Left + offsetWidth) &&
        (y >= offset.Top && y <= offset.Top + tableHeight);`
    

    to

    var inRange = (x >= offset.Left && x <= offset.Left + offsetWidth) &&
        (y >= offset.Top);
    

    Hope this helps and you can adjust tableHeight to your requirements from here. Also, suggestion by @Keith is spot on.

    EDIT:

    Check this fiddle. Clicks on dates in left column are being evaluated to be in inRange with above suggestion. Horizontal scroll also seems to be working (you can click on 04-04-2018 and then click on 02-04-2018 to confirm that).