0

Issue

I want to be able to touch my screen and drag my finger across the surface and select multiple boxes. I want to do the same thing with my mouse, where I hold down the mouse and drag it across whatever I want to select. Because of this, I am thinking that I would like to implement this in something like JQuery/JQuery mobile so that I have this behavior out of the box?

Code

Here is my working sample of what I have working so far.

  • Built a table and able to select specific elements by color (and ignore another)
  • Able to select by row or colum. Also able to unselect.
  • Able to select entire table or unselect (by color).

Attempts

I tried using JQuery UI. Specifically, the JQuery selectable api, but it breaks my existing code and is buggy. I also took a look at something I found here, but it is completely dependent on the desktop approach using shift and control. I also tried add select as an attribute to my <td> elements and use multiple select. I didn't think that hack would work, but I at least wanted to try it. Finally, looked at stackoverflow and it seems everyone wants to do this for checkboxes or with a keyboard.

Again, what I need is a way to be able to select multiple boxes/grids aka the elements in my grid by touching screen and dragging it across whatever I wish to select or do the same with my mouse.

Edit This is a good question, it is similar but not what I need. Same use case, but applied to both mouse event + touch events.

Any suggestions, clues, hints, or more would be deeply appreciated as I have thrown everything and the kitchen sink at this. I feel like this.

1 Answer 1

2

I combined this answer with this one and it seems to work both on desktop and on mobile (code is a bit ugly, sorry for that).

How it works

Every <td> on the table listens both to normal mouse events (up/down/move) and to touch events (start/end/move).

On mousedown/touchstart the motion becomes "active", selection is reset (removing .highlight class) and current event element is selected.

The trick is in the touchmove event: since $(this) always refers to the element where the touch event started, we have to see what the user is actually touching passing the event coordinates to highlightHoveredObject, which will select the right element.

JSFiddle

JavaScript

function highlightHoveredObject(x, y) {
    $('td').each(function() {
      // check if is inside boundaries
      if (!(
          x <= $(this).offset().left || x >= $(this).offset().left + $(this).outerWidth() ||
          y <= $(this).offset().top  || y >= $(this).offset().top + $(this).outerHeight()
      )) {

        $(this).addClass('highlight');
      }
    });
}

// if you are using jQuery Mobile replace the next line with
// $("#yourpage").on("pagecreate", function() {

$(document).ready(function() {  

    var active = false;

    $("td").on("mousedown", function(ev) {
        active = true;
        $(".highlight").removeClass("highlight"); // clear previous selection
        ev.preventDefault(); // this prevents text selection from happening
        $(this).addClass("highlight");
    });

    $("td").on("mousemove", function(ev) {
        if (active) {
            $(this).addClass("highlight");
        }
    });

    $(document).on("mouseup", function(ev) {
        active = false;
    });

    $("td").on("touchstart", function(ev) {
        active = true;
        $(".highlight").removeClass("highlight"); // clear previous selection
        ev.preventDefault(); // this prevents text selection from happening
        $(this).addClass("highlight");
    });

    $("td").on("touchmove", function(ev) {
        if (active) {
            var touch = ev.originalEvent.touches[0];
            highlightHoveredObject(touch.clientX, touch.clientY);
        }
    });

    $(document).on("touchend", function(ev) {
        active = false;
    });

});

HTML

<table border="1" width="100%">
    <tbody><tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
    <tr>
        <td>1</td>
        <td>2</td>
        <td>3</td>
    </tr>
</tbody></table>

CSS

.highlight { background-color:#ccffcc; }
Sign up to request clarification or add additional context in comments.

9 Comments

It works for my mouse, but I am only getting one td element to select at a time with touch. In other words, no drag select with mobile. Are you experiencing that?
JSFiddle works fine for me both on my Android device (Moto G) and on emulation in Chrome browser
I am on a Microsoft Surface and tested on IE explorer 11 (because of enterprise requirements). Let me check on Firefox. :-(
Thanks. Can you also try adding -ms-touch-action: none;" to your CSS?
Yes! thanks a lot, it is just what I was looking for.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.