1

I have a table which I've added some multiple selection functionality where shift + click selects rows between the first click and second click but it ends up highlighting all text between the rows.

I don't want to disable text selection via CSS because this stuff really does need to be selectable, just not when shift + clicking when my multi-select function fires.

Can this be done?

    var lastChecked;    
    $("#contact_table tr").click(function(e) {
        if (e.target.getAttribute('type') == 'checkbox') {
            return;
        };  
        if (e.shiftKey && lastChecked) {
            // select between last point and new point
            var tableRows = $("#contact_table tr");
            var newRow = tableRows.index($(this));
            var oldRow = tableRows.index(lastChecked);
            if (oldRow < newRow) {
                newRow = newRow +1;
            }
            var sliceRange = [newRow, oldRow].sort();
            var selectedRows = tableRows.slice(sliceRange[0], sliceRange[1])
                .find('input[type=checkbox]').attr('checked', true);
        } else {
            var checkbox = $(this).find('input[type=checkbox]');
            var checked = toggleCheckbox(checkbox);
            if (checked) {
                lastChecked = $(this);
            }               
        };
        recalculateSelectedButton();
    });
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Can you share your multi-select function? I think you should be able to prevent the default behavior within your event handler. – PJH Aug 15 '12 at 20:16
  • http://stackoverflow.com/questions/826782/css-rule-to-disable-text-selection-highlighting – Joel Purra Aug 15 '12 at 20:31
  • @JoelPurra yes, I reference that method in my post. I'm curious if there's a JS event that can hijack this behavior instead of dynamically setting CSS temporarily (I'm not even sure if that would work, as the click has already begun). – Yuji 'Tomita' Tomita Aug 15 '12 at 20:48
  • @YujiTomita: you're right. My bad for misreading! – Joel Purra Aug 15 '12 at 20:51
  • @YujiTomita: in order to be able to test this, I still recommend you to add a jsfiddle with your example. – Joel Purra Aug 15 '12 at 21:45

2 Answers2

1

You can try disabling user select based on the number of checked checkboxes. If there are any, just add the CSS style user-select: none; (and prefixed versions) to the #contact_table.

If you provide a jsfiddle with your current javascript code and table, I'd test the code too - now it's as-is ;) I'm not sure how the click interactions will play out with any cancelled event bubbling etcetera. Also, this implementation doesn't take into account that users might want to select text even if there's a checked checkbox (so it might not be what you're looking for).

$(function() {
    var $contactTable = $("#contact_table"),
        userSelectNoneClass = "user-select-none";

    $contactTable.on("change", ":checkbox", function(e) {
        var numberOfCheckedRows = $("#contact_table :checkbox:checked").length,
            anyCheckedRows = (numberOfCheckedRows > 0);

        if (anyCheckedRows && $contactTable.hasClass(userSelectNoneClass)) {
            $contactTable.addClass(userSelectNoneClass);
        } else {
            $contactTable.removeClass(userSelectNoneClass);
        }
    });
});
.user-select-none
{
    /* From https://stackoverflow.com/questions/826782/css-rule-to-disable-text-selection-highlighting */
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

Edit: using the change event instead.

Community
  • 1
  • 1
Joel Purra
  • 24,294
  • 8
  • 60
  • 60
  • Joel, I appreciate your time. Thank you! It's a good idea, but it would be nice not to resort to preventing selection at all except for during the multi click. I think users would be confused if only unchecked boxes were selectable as people are rarely aware of text selection in the first place. "Why wont' this darn thing work??" – Yuji 'Tomita' Tomita Aug 15 '12 at 21:29
  • @YujiTomita: yeah, thought of that *after* I implemented the code ;) – Joel Purra Aug 15 '12 at 21:43
1

You can deselect all text with javascript; add a call to RemoveSelection() after you run the multi-select logic.

From http://help.dottoro.com/ljigixkc.php via Clear a selection in Firefox

function RemoveSelection () {
    if (window.getSelection) {  // all browsers, except IE before version 9
        var selection = window.getSelection ();                                        
        selection.removeAllRanges ();
    }
    else {
        if (document.selection.createRange) {        // Internet Explorer
            var range = document.selection.createRange ();
            document.selection.empty ();
        }
    }
}
Community
  • 1
  • 1
Joel Purra
  • 24,294
  • 8
  • 60
  • 60