2
\$\begingroup\$

I'm working on a scheduling table that user' can select cells (which will be gathered with jQuery using data attributes) but I'm trying to work out the best way for user' to be able to select rows and columns in a usable fashion. At the moment you can click and drag cells to select them and you can select rows.

So far this is what I've got, any suggestions would be greatly appreciated.

<!DOCTYPE html>
  <html>
    <head>
      <meta charset="utf-8"/>
      <style type="text/css" media="screen">
        table#power_schedule td
        {
          width: 140px;
        }

        table#power_schedule td.selectable, table#power_schedule th {
          font-size: 12px;
          width: 70px;
          height: 25px;
          text-align: center;
        }

        table#power_schedule td.selectable {
          width: 60px;
          background-color:#77DD77;
          border: 1px solid #68C168;
        }

        table#power_schedule td.highlighted {
          background-color:#FF6961;
          border: 1px solid #E8615A;
        }

        table#power_schedule td:first-child {
          cursor: pointer;
        }
      </style>
    </head>
    <body>
      <table cellpadding="0" cellspacing="0" id="power_schedule">
        <thead>
          <th/>
          <th>Mon</th>
          <th>Tue</th>
          <th>Wed</th>
          <th>Thu</th>
          <th>Fri</th>
          <th>Sat</th>
          <th>Sun</th>
        </thead>
        <tr>
          <td>00:00-00:30</td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
        </tr>
        <tr>
          <td>00:30-01:00</td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
        </tr>
        <tr>
          <td>01:00-01:30</td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
          <td class="selectable"> </td>
        </tr>
      </table>

      <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js" type="text/javascript"></script>
      <script type="text/javascript" charset="utf-8">
        $(function () {
          // Create table dragging functionality
          var isMouseDown = false;
          var highlighted
          $("table#power_schedule td.selectable")
            .mousedown(function () {
              isMouseDown = true;
              highlighted = $(this).hasClass('highlighted')

              if ( highlighted ) {
                $(this).removeClass('highlighted')
              } else {
                $(this).addClass('highlighted')
              }
              return false; // prevent text selection
            })
            .mouseover(function () {
              if (isMouseDown) {
                if ( highlighted ) {
                  $(this).removeClass('highlighted')
                } else {
                  $(this).addClass('highlighted')
                }
              }
            })
            .bind("selectstart", function () {
              return false; // prevent text selection in IE
            })

          $('table#power_schedule td:first-child')
              .mousedown(function() {
                  isMouseDown = true;

                  $(this).parent().find('td:not(:first-of-type)').toggleClass('highlighted')
                  $(this).css('cursor', 'pointer')
                  return false
              })
              .mouseover(function() {
                  if (isMouseDown) {
                      $(this).parent().find('td:not(:first-of-type)').toggleClass('highlighted')
                  }
              })
            .bind("selectstart", function () {
              return false; // prevent text selection in IE
            })

          $(document)
              .mouseup(function () {
              isMouseDown = false
          })
        });
      </script>
    </body>
  </html>
\$\endgroup\$
1
\$\begingroup\$

Two quick comments:

  • The selection didn't work quite as I expected. It seems that if I click-and-hold, any cell I drag the mouse over is also selected. The appearance made me expect a rectangular selection, like you get in a spreadsheet app.

    Also, I didn't realise I could select entire rows at once before reading your post. I'd recommend adding some sort of styling to make it clear that the row labels aren't just plain text – they're clickable!

  • I would move the code for changing the highlighted class of a cell into a function. Something like:

    function toggleHighlightingOfCell(cell) {
        isHighlighted = cell.hasClass('highlighted');
        if (isHighlighted) {
            cell.removeClass('highlighted');
        } else {
            cell.addClass('highlighted');
        }
    }
    

    which you invoke as

    toggleHighlightingOfCell($(this));
    

    Note also that I've changed the name of the variable so that it's not the same as the class you're using – this reduces the ambiguity a little.

\$\endgroup\$
  • \$\begingroup\$ Yeah I was going for a painting effect on the cells - haven't worked out how I'd write it so I could draw a rectangle around a selection of cells to select them - that would solve all my issues though... Also, I had changed the cursor on the hours to a pointer but not sure that makes it obvious enough - I was going to have this on the page to explain how to use the selection but perhaps there are better ways of showing this. Have added your function, I would have got their but I'm still actively working on this so haven't tidied up - my bad. Thanks! \$\endgroup\$ – Allan M Feb 23 '16 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.