miti737
miti737

Reputation: 471

How to prevent multiple selection in jQuery UI Selectable plugin

I am using jQuery UI Selectable plugin. I want to select one item at a time. But jQuery UI Selectable plugin allows multiple selection by clicking/ dragging / holding CTRL key. Is there any way to prevent multiple selection?

Upvotes: 22

Views: 17562

Answers (10)

Cellydy
Cellydy

Reputation: 1339

If you want to disable non consecutive multiselection but still wish to keep the dragging selection you can do this.

         stop: function( event, ui ) {
                if( $(".ui-selected, .ui-selecting").length > 1){
                    var elems = $('.ui-selected, .ui-selecting');

                    for(var i = 0; i < elems.length - 1; i++){
                        if($(elems[i]).closest('td').next('td').text() != $(elems[i+1]).text()){
                           //Non consecutive selection detected
                        }
                    }
                }
            }

It essentially checks if all elements are next to each other.

Upvotes: 0

bandy
bandy

Reputation: 1

There are some good solutions here, but most of them assume that you always want to select the first element as it appears in the DOM in a multiple selection case.

To remedy this, I keep a variable (lastSelection) that contains the last element that was requested successfully (rather than the first in the DOM) to fallback to in the case of an unwanted selection.

var lastSelection;// this will record our last successful selection

$('#selectable').selectable({
    filter: '.element',
    selecting: function () {
        if ($('.ui-selecting').length > 1) {
            // if selecting multiple (lasso) we will ignore the selection and fallback
            $('.ui-selecting').removeClass('ui-selecting');
            $(lastSelection).addClass('ui-selecting');// if no value, nothing will be selected
        }     
    },
    stop: function () {
        if ($('.ui-selected').length > 1) {
            // looks like we have an invalid selection, fallback to lastSelection
            // this handles the ctrl (windows), cmd (OSX) multi-select cases
            $('.ui-selected').removeClass('ui-selected');
            $(lastSelection).addClass('ui-selected');// if no value, nothing will be selected
        } else {
            if ($('.ui-selected').first().is('.element')) {
                // if we successfully found a selection, set it as our new lastSelection value
                lastSelection = $('.ui-selected')[0];
            }     
        }     
    }
});

Note: If you want to deselect without ctrl / cmd + click you will have to implement a work-around with this method.

I also wanted to point out that tolerance: 'fit' simply requires that the lasso completely surrounds a target element in order to select it, it will not disable the lasso selection unless your elements cannot be surrounded in the available lasso area. http://api.jqueryui.com/selectable/#option-tolerance

Upvotes: 0

kyle
kyle

Reputation: 568

This worked for me. It prevents "lassoing" multiple rows and ctrl + click.

$(function() {
$("#selectable").selectable({
      selecting: function(event, ui){
            if( $(".ui-selected, .ui-selecting").length > 1){
                  $(ui.selecting).removeClass("ui-selecting");
            }
      }
});
});

Upvotes: 15

Josh Schultz
Josh Schultz

Reputation: 8190

Here's a more general solution than those previously posted:

    $element.selectable({
        selecting: function (e, ui) {
            // force single selection
            $(e.target).find('.ui-selectee.ui-selecting').not(ui.selecting).removeClass('ui-selecting');
            $(e.target).find('.ui-selectee.ui-selected').not(ui.selecting).removeClass('ui-selected');
        }
    });

(The selectees may not always be children of the selectable, and holding onto the "first" selectee causes some weird behavior when you ctrl+click.)

Upvotes: 7

samit basak
samit basak

Reputation: 91

This might be a better solution:

$('#selectable').selectable({
    selecting: function (event, ui) {
        $(event.target).children('.ui-selecting').not(':first').removeClass('ui-selecting');
    }
});

Upvotes: 9

Lunfel
Lunfel

Reputation: 2667

What i did, is that i allow multiple selection but when the selection is done, i only keep the first element selected

<ul id="select">
    <li>Row 1</li>
    <li>Row 2</li>
    <li>Row 3</li>
</ul>

This selects all the selected elements except the first one and deletes the selected status. So at the end, only one element will be selected. event.target corresponds to my ul element.

$('#select').selectable({
    stop:function(event, ui){
        $(event.target).children('.ui-selected').not(':first').removeClass('ui-selected');
    }
});

I know this topic is kinda old, but i still stumbled upon it, so it can be useful to someone else

Upvotes: 29

Guillermo
Guillermo

Reputation: 429

You can create your custom plugin like this:

$.widget("xim.singleSelectable", {
    options: {
        select: null
    },
    _create: function () {
        var self = this;
        this.element.addClass('ui-selectable');
        this.element.delegate('li', 'click', function (e) {
            self.element.find('>li').removeClass('ui-selected');
            $(this).addClass('ui-selected');

            if ($.isFunction(self.options.select)) {
                self.options.select.apply(self.element, [e, this]);
            }

        });
    },
    selected: function () {
        return this.element.find('li.ui-selected');
    },
    destroy: function () {
        $.Widget.prototype.destroy.apply(this, arguments); // default destroy
    }
});

Upvotes: 2

KenMaster
KenMaster

Reputation: 69

yes, you can prevent this behavior, just set the toletance option to 'fit'

Upvotes: 6

cetnar
cetnar

Reputation: 9415

An interesting discussion about this you can find on this jQuery forum thread.

Upvotes: 2

Dmitri Farkov
Dmitri Farkov

Reputation: 9671

There is no defined way. However, you could pass in a callback function for "Start" or "Selected" events, that cancels the selection if more than one element is selected.

Upvotes: 10

Related Questions