GeekyOmega
GeekyOmega

Reputation: 1329

How to add or modify my jquery for multiple selection to this javascript?

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.

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.

Upvotes: 0

Views: 447

Answers (1)

Sga
Sga

Reputation: 3658

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; }

Upvotes: 2

Related Questions