2

EDIT:: I came up with a solution. See bottom of this post

I have a table I'm trying to get setup with selectable. I'm not a javascript/jquery coder by any means (as my code will show). I'm trying to limit the selectable range to 1 table row then send the starting cell id and ending cell id to another page. I know how to send data via $.post but I can't get the right data or limit it to 1 row.

I did find this post but it limits to table columns and I don't know enough about JS to reverse that to limit to table row.

Here's a JSFiddle, which doesn't work (hence why I'm here) and below is my code. Here's the HTML

<div id="reservation-sheet" style="display: block;">
  <table>
    <thead>
      <tr>
        <th>Size</th>
        <th>8:00</th>
        <th>8:30</th>
        <th>9:00</th>
        <th>9:30</th>
        <th>10:00</th>
        <th>10:30</th>
        <th>11:00</th>
        <th>11:30</th>
        <th>12:00</th>
        <th>12:30</th>
        <th>1:00</th>
        <th>1:30</th>
        <th>2:00</th>
        <th>2:30</th>
        <th>3:00</th>
        <th>3:30</th>
        <th>4:00</th>
        <th>4:30</th>
        <th>5:00</th>
        <th>5:30</th>
        <th>6:00</th>
      </tr>
    </thead>
    <tbody>
      <tr id="0">
        <td id="0-size" class="size">20'</td>
        <td id="0-8.00" class="open">&nbsp;</td>
        <td id="0-8.50" class="open">&nbsp;</td>
        <td id="0-9.00" class="open">&nbsp;</td>
        <td id="0-9.50" class="open">&nbsp;</td>
        <td id="0-10.00" class="open">&nbsp;</td>
        <td id="0-10.50" class="open">&nbsp;</td>
        <td id="0-11.00" class="open">&nbsp;</td>
        <td id="0-11.50" class="open">&nbsp;</td>
        <td id="0-12.00" class="open">&nbsp;</td>
        <td id="0-12.50" class="open">&nbsp;</td>
        <td id="0-13.00" class="open">&nbsp;</td>
        <td id="0-13.50" class="open">&nbsp;</td>
        <td id="0-14.00" class="open">&nbsp;</td>
        <td id="0-14.50" class="open">&nbsp;</td>
        <td id="0-15.00" class="open">&nbsp;</td>
        <td id="0-15.50" class="open">&nbsp;</td>
        <td id="0-16.00" class="open">&nbsp;</td>
        <td id="0-16.50" class="open">&nbsp;</td>
        <td id="0-17.00" class="open">&nbsp;</td>
        <td id="0-17.50" class="open">&nbsp;</td>
        <td id="0-18.00" class="open">&nbsp;</td>
      </tr>
      <tr id="1">
        <td id="1-size" class="size">20'</td>
        <td id="1-8.00" class="open">&nbsp;</td>
        <td id="1-8.50" class="open">&nbsp;</td>
        <td id="1-9.00" class="open">&nbsp;</td>
        <td id="1-9.50" class="open">&nbsp;</td>
        <td id="1-10.00" class="open">&nbsp;</td>
        <td id="1-10.50" class="open">&nbsp;</td>
        <td id="1-11.00" class="open">&nbsp;</td>
        <td id="1-11.50" class="open">&nbsp;</td>
        <td id="1-12.00" class="open">&nbsp;</td>
        <td id="1-12.50" class="open">&nbsp;</td>
        <td id="1-13.00" class="open">&nbsp;</td>
        <td id="1-13.50" class="open">&nbsp;</td>
        <td id="1-14.00" class="open">&nbsp;</td>
        <td id="1-14.50" class="open">&nbsp;</td>
        <td id="1-15.00" class="open">&nbsp;</td>
        <td id="1-15.50" class="open">&nbsp;</td>
        <td id="1-16.00" class="open">&nbsp;</td>
        <td id="1-16.50" class="open">&nbsp;</td>
        <td id="1-17.00" class="open">&nbsp;</td>
        <td id="1-17.50" class="open">&nbsp;</td>
        <td id="1-18.00" class="open">&nbsp;</td>
      </tr>
      <tr id="2">
        <td id="2-size" class="size">20'</td>
        <td id="2-8.00" class="open">&nbsp;</td>
        <td id="2-8.50" class="open">&nbsp;</td>
        <td id="2-9.00" class="open">&nbsp;</td>
        <td id="2-9.50" class="open">&nbsp;</td>
        <td id="2-10.00" class="open">&nbsp;</td>
        <td id="2-10.50" class="open">&nbsp;</td>
        <td id="2-11.00" class="open">&nbsp;</td>
        <td id="2-11.50" class="open">&nbsp;</td>
        <td id="2-12.00" class="open">&nbsp;</td>
        <td id="2-12.50" class="open">&nbsp;</td>
        <td id="2-13.00" class="open">&nbsp;</td>
        <td id="2-13.50" class="open">&nbsp;</td>
        <td id="2-14.00" class="open">&nbsp;</td>
        <td id="2-14.50" class="open">&nbsp;</td>
        <td id="2-15.00" class="open">&nbsp;</td>
        <td id="2-15.50" class="open">&nbsp;</td>
        <td id="2-16.00" class="open">&nbsp;</td>
        <td id="2-16.50" class="open">&nbsp;</td>
        <td id="2-17.00" class="open">&nbsp;</td>
        <td id="2-17.50" class="open">&nbsp;</td>
        <td id="2-18.00" class="open">&nbsp;</td>
      </tr>
      <tr id="3">
        <td id="3-size" class="size">20'</td>
        <td id="3-8.00" class="open">&nbsp;</td>
        <td id="3-8.50" class="open">&nbsp;</td>
        <td id="3-9.00" class="open">&nbsp;</td>
        <td id="3-9.50" class="open">&nbsp;</td>
        <td id="3-10.00" class="open">&nbsp;</td>
        <td id="3-10.50" class="open">&nbsp;</td>
        <td id="3-11.00" class="open">&nbsp;</td>
        <td id="3-11.50" class="open">&nbsp;</td>
        <td id="3-12.00" class="open">&nbsp;</td>
        <td id="3-12.50" class="open">&nbsp;</td>
        <td id="3-13.00" class="open">&nbsp;</td>
        <td id="3-13.50" class="open">&nbsp;</td>
        <td id="3-14.00" class="open">&nbsp;</td>
        <td id="3-14.50" class="open">&nbsp;</td>
        <td id="3-15.00" class="open">&nbsp;</td>
        <td id="3-15.50" class="open">&nbsp;</td>
        <td id="3-16.00" class="open">&nbsp;</td>
        <td id="3-16.50" class="open">&nbsp;</td>
        <td id="3-17.00" class="open">&nbsp;</td>
        <td id="3-17.50" class="open">&nbsp;</td>
        <td id="3-18.00" class="open">&nbsp;</td>
      </tr>
    </tbody>
  </table>
</div>

Here's the JS

$(document).ready(function() {
    var startingRow = 0;
    var startingTime = 0;
    $('#reservation-sheet').selectable({
      filter: 'tr, td', //lets filter to tr and td
      start: function(event, ui) {
        var startingItem = $('.ui-selecting', this);
        startingRow = startingItem.prop('id'); //should be the ID of the starting row
        startingTime = startingItem.last().prop('id'); //should be the id of the starting cell
      },
      selecting: function(event, ui) {
        var selectingItems = $('.ui-selecting', this);
        //during the selecting process lets make sure we limit to 1 row
        if (selectingItems.prop('id') != startingRow) {
          selectingItems.not(':first').removeClass('ui-selecting');
        }
      },
      stop: function(event, ui) {
        var selectedItems = $('.ui-selected', this);
        var endTime = selectedItems.last().prop('id'); //in theory this should be the last selcted cell
        //$.post('contact.php', {sTime: startingTime, eTime: endTime, id: startingRow}, function(data, status) {
        //pop-up window to get name, email and phone number
        //then submit everything
        //});
      }
    });
});

Here's the CSS

table {
  width: 100%;
}

th,
td {
  border: 2px solid #000;
  text-align: center;
}

tr {
  background-color: #CCC;
}

#reservation-sheet td.ui-selecting {
  background-color: #FECA40;
}

#reservation-sheet td.ui-selected {
  background-color: #F39814;
}

EDIT:: I was able to work out a solution...maybe not the prettiest but it works

$(document).ready(function() {
    $('#reservation-sheet').selectable({
     filter: 'tr, td', //lets filter to tr and td
     selecting: function(event, ui) {
      var selectingItems = $('.ui-selecting', this);
      var startingRow = selectingItems.first().prop('id'); //starting row id
      var splitCell = selectingItems.last().prop('id').split('-'); //since we have the row id in the cell id, we can use that to find changes
      if(splitCell[0] != startingRow) {
       selectingItems.not(':first').removeClass('ui-selecting'); //remove extra row to keep it at 1
      }
     },
     stop: function(event, ui) {
      var selectedItems = $('.ui-selected', this);
      var startTime = selectedItems[Object.keys(selectedItems)[1]];
      var startTime2 = startTime['id']; //get our starting cell
      var endTime = selectedItems.last().prop('id'); //get our last cell
      console.log('send to php: startingTime: '+ startTime2 +' endingTime: '+ endTime);
      //$.post('contact.php', {sTime: startingTime, eTime: endTime}, function(data, status) {
       //pop-up window to get name, email and phone number
       //then submit everything
      //});
     }
    });
   });
Community
  • 1
  • 1

2 Answers2

0

you can use pure javascript to remove the selected class at 'start' event.

  start: function( event, ui ){
   var el = document.querySelector('.ui-selected');
    if(el) {
         el.classList.remove('ui-selected')
    }
  }

if you need to support older browsers user jquery to remove class

jsfiddle: https://jsfiddle.net/1p30q2hp/

MonteCristo
  • 1,471
  • 2
  • 20
  • 41
  • Why not just do this in jQuery: `$('.ui-selected').removeClass('ui-selected');` 1 line of code versus 3. – Twisty Nov 17 '16 at 21:19
  • Well you could if you really want to. But things moved on? So why depend on library when you can do it natively? + better performance? https://jsperf.com/jquery-vs-native-element-performance unless you have to support old browsers then I would use something like jQuery. – MonteCristo Nov 17 '16 at 21:45
  • That logic doesn't make much sense. If jQuery is not available, NONE of this UI scripting would work at all. Personally, I would stay in jQuery for consistency of code. This also ensures better cross browser compatibility. – Twisty Nov 17 '16 at 21:58
  • Why wouldn't it make sense? When you minify (which one should) it makes no difference 1 line or 3 lines. What consistency are you talking about? it's javascript http://vanilla-js.com/. Either way if need to support older browsers and not quite familiar with native methods use jquery to remove 'ui-selected' at `start` otherwise native is the best solution. http://stackoverflow.com/questions/5099949/what-are-some-empirical-technical-reasons-not-to-use-jquery/5100169 – MonteCristo Nov 18 '16 at 01:15
0

Here's the solution I came up with. As I say in OP it may not be the prettiest way to do this but it works. Posting it so it may help someone else.

$(document).ready(function() {
    $('#reservation-sheet').selectable({
     filter: 'tr, td', //lets filter to tr and td
     selecting: function(event, ui) {
      var selectingItems = $('.ui-selecting', this);
      var startingRow = selectingItems.first().prop('id'); //starting row id
      var splitCell = selectingItems.last().prop('id').split('-'); //since we have the row id in the cell id, we can use that to find changes
      if(splitCell[0] != startingRow) {
       selectingItems.not(':first').removeClass('ui-selecting'); //remove extra row to keep it at 1
      }
     },
     stop: function(event, ui) {
      var selectedItems = $('.ui-selected', this);
      var startTime = selectedItems[Object.keys(selectedItems)[1]];
      var startTime2 = startTime['id']; //get our starting cell
      var endTime = selectedItems.last().prop('id'); //get our last cell
      console.log('send to php: startingTime: '+ startTime2 +' endingTime: '+ endTime);
      //$.post('contact.php', {sTime: startingTime, eTime: endTime}, function(data, status) {
       //pop-up window to get name, email and phone number
       //then submit everything
      //});
     }
    });
   });