8

I need to make multiple selection available by default, so the user doesn't have to hold ctrl. Would appreciate some help with this, thanks.

5 Answers 5

6
$("#selectable").selectable();
    $("#selectable").on("selectablestart", function (event, ui) {
        event.originalEvent.ctrlKey = true;
    });
Sign up to request clarification or add additional context in comments.

3 Comments

Provide detail please
api.jqueryui.com/selectable/#event-start this event fires before any selection, so i simply modify original event object to make it look like the CTRL key was pressed from start :)
Thanks, I've confirmed this works beautifully; no need to hack jQueryUI code, or use an alternative. (I'm using 1.10.x of both jQuery and jQueryUI, but IIUC this will be compatible much further back than that.)
3

If you want to use selectable , you might want to use bind meta key with mousedown event. There's already a debate going down here , i just found when i googled.

Comments

2

Well, if you want to modify the selectable code, add an option to the options object at the top (I called mine multi_no_key, and defaulted to false).

Then, look for where var doSelect is declared, it originally looks like this

var doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');

And change it to this

var doSelect;
if(!options.multi_no_key)
    doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
else
    doSelect = !selectee.$element.hasClass('ui-selected');

In that same _mouseStart method, look for the following code

this.selectees.filter('.ui-selected').each(function() {
        var selectee = $.data(this, "selectable-item");
        selectee.startselected = true;
        if (!event.metaKey) {
            selectee.$element.removeClass('ui-selected');
            selectee.selected = false;
            selectee.$element.addClass('ui-unselecting');
            selectee.unselecting = true;
            // selectable UNSELECTING callback
            self._trigger("unselecting", event, {
                unselecting: selectee.element
            });
        }
    });

And change the conditional to check the option for multi_no_key

this.selectees.filter('.ui-selected').each(function() {
        var selectee = $.data(this, "selectable-item");
        selectee.startselected = true;
        if (!event.metaKey && options.multi_no_key == false) {
            selectee.$element.removeClass('ui-selected');
            selectee.selected = false;
            selectee.$element.addClass('ui-unselecting');
            selectee.unselecting = true;
            // selectable UNSELECTING callback
            self._trigger("unselecting", event, {
                unselecting: selectee.element
            });
        }
    });

I tested this and it worked well for me. Below is the entire contents of the selectable js file (version 1.8.12)

/*
* jQuery UI Selectable 1.8.12
*
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
* Dual licensed under the MIT or GPL Version 2 licenses.
* http://jquery.org/license
*
* http://docs.jquery.com/UI/Selectables
*
* Depends:
*   jquery.ui.core.js
*   jquery.ui.mouse.js
*   jquery.ui.widget.js
*/
(function( $, undefined ) {

$.widget("ui.selectable", $.ui.mouse, {
options: {
    appendTo: 'body',
    autoRefresh: true,
    distance: 0,
    filter: '*',
    tolerance: 'touch',
            multi_no_key: false
},
_create: function() {
    var self = this;

    this.element.addClass("ui-selectable");

    this.dragged = false;

    // cache selectee children based on filter
    var selectees;
    this.refresh = function() {
        selectees = $(self.options.filter, self.element[0]);
        selectees.each(function() {
            var $this = $(this);
            var pos = $this.offset();
            $.data(this, "selectable-item", {
                element: this,
                $element: $this,
                left: pos.left,
                top: pos.top,
                right: pos.left + $this.outerWidth(),
                bottom: pos.top + $this.outerHeight(),
                startselected: false,
                selected: $this.hasClass('ui-selected'),
                selecting: $this.hasClass('ui-selecting'),
                unselecting: $this.hasClass('ui-unselecting')
            });
        });
    };
    this.refresh();

    this.selectees = selectees.addClass("ui-selectee");

    this._mouseInit();

    this.helper = $("<div class='ui-selectable-helper'></div>");
},

destroy: function() {
    this.selectees
        .removeClass("ui-selectee")
        .removeData("selectable-item");
    this.element
        .removeClass("ui-selectable ui-selectable-disabled")
        .removeData("selectable")
        .unbind(".selectable");
    this._mouseDestroy();

    return this;
},

_mouseStart: function(event) {
    var self = this;

    this.opos = [event.pageX, event.pageY];

    if (this.options.disabled)
        return;

    var options = this.options;

    this.selectees = $(options.filter, this.element[0]);

    this._trigger("start", event);

    $(options.appendTo).append(this.helper);
    // position helper (lasso)
    this.helper.css({
        "left": event.clientX,
        "top": event.clientY,
        "width": 0,
        "height": 0
    });

    if (options.autoRefresh) {
        this.refresh();
    }

    this.selectees.filter('.ui-selected').each(function() {
        var selectee = $.data(this, "selectable-item");
        selectee.startselected = true;
        if (!event.metaKey && options.multi_no_key == false) {
            selectee.$element.removeClass('ui-selected');
            selectee.selected = false;
            selectee.$element.addClass('ui-unselecting');
            selectee.unselecting = true;
            // selectable UNSELECTING callback
            self._trigger("unselecting", event, {
                unselecting: selectee.element
            });
        }
    });

    $(event.target).parents().andSelf().each(function() {
        var selectee = $.data(this, "selectable-item");
        if (selectee) {                            
                            var doSelect;
                            if(!options.multi_no_key)
                                doSelect = !event.metaKey || !selectee.$element.hasClass('ui-selected');
                            else
                                doSelect = !selectee.$element.hasClass('ui-selected');

            selectee.$element
                .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
                .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
            selectee.unselecting = !doSelect;
            selectee.selecting = doSelect;
            selectee.selected = doSelect;
            // selectable (UN)SELECTING callback
            if (doSelect) {
                self._trigger("selecting", event, {
                    selecting: selectee.element
                });
            } else {
                self._trigger("unselecting", event, {
                    unselecting: selectee.element
                });
            }
            return false;
        }
    });

},

_mouseDrag: function(event) {
    var self = this;
    this.dragged = true;

    if (this.options.disabled)
        return;

    var options = this.options;

    var x1 = this.opos[0], y1 = this.opos[1], x2 = event.pageX, y2 = event.pageY;
    if (x1 > x2) { var tmp = x2; x2 = x1; x1 = tmp; }
    if (y1 > y2) { var tmp = y2; y2 = y1; y1 = tmp; }
    this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});

    this.selectees.each(function() {
        var selectee = $.data(this, "selectable-item");
        //prevent helper from being selected if appendTo: selectable
        if (!selectee || selectee.element == self.element[0])
            return;
        var hit = false;
        if (options.tolerance == 'touch') {
            hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
        } else if (options.tolerance == 'fit') {
            hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
        }

        if (hit) {
            // SELECT
            if (selectee.selected) {
                selectee.$element.removeClass('ui-selected');
                selectee.selected = false;
            }
            if (selectee.unselecting) {
                selectee.$element.removeClass('ui-unselecting');
                selectee.unselecting = false;
            }
            if (!selectee.selecting) {
                selectee.$element.addClass('ui-selecting');
                selectee.selecting = true;
                // selectable SELECTING callback
                self._trigger("selecting", event, {
                    selecting: selectee.element
                });
            }
        } else {
            // UNSELECT
            if (selectee.selecting) {
                if (event.metaKey && selectee.startselected) {
                    selectee.$element.removeClass('ui-selecting');
                    selectee.selecting = false;
                    selectee.$element.addClass('ui-selected');
                    selectee.selected = true;
                } else {
                    selectee.$element.removeClass('ui-selecting');
                    selectee.selecting = false;
                    if (selectee.startselected) {
                        selectee.$element.addClass('ui-unselecting');
                        selectee.unselecting = true;
                    }
                    // selectable UNSELECTING callback
                    self._trigger("unselecting", event, {
                        unselecting: selectee.element
                    });
                }
            }
            if (selectee.selected) {
                if (!event.metaKey && !selectee.startselected) {
                    selectee.$element.removeClass('ui-selected');
                    selectee.selected = false;

                    selectee.$element.addClass('ui-unselecting');
                    selectee.unselecting = true;
                    // selectable UNSELECTING callback
                    self._trigger("unselecting", event, {
                        unselecting: selectee.element
                    });
                }
            }
        }
    });

    return false;
},

_mouseStop: function(event) {
    var self = this;

    this.dragged = false;

    var options = this.options;

    $('.ui-unselecting', this.element[0]).each(function() {
        var selectee = $.data(this, "selectable-item");
        selectee.$element.removeClass('ui-unselecting');
        selectee.unselecting = false;
        selectee.startselected = false;
        self._trigger("unselected", event, {
            unselected: selectee.element
        });
    });
    $('.ui-selecting', this.element[0]).each(function() {
        var selectee = $.data(this, "selectable-item");
        selectee.$element.removeClass('ui-selecting').addClass('ui-selected');
        selectee.selecting = false;
        selectee.selected = true;
        selectee.startselected = true;
        self._trigger("selected", event, {
            selected: selectee.element
        });
    });
    this._trigger("stop", event);

    this.helper.remove();

    return false;
}
});
$.extend($.ui.selectable, {
version: "1.8.12"
});
})(jQuery);

Comments

1

i needed something like it once.

Here is a nice example about how to do it. I think it may give you some ideas.

http://www.joelanman.com/static/examples/multiple_selection/

Here is the tutorial link as well

http://www.joelanman.com/2009/03/simple-multiple-selection-with-checkbox-lists-and-jquery/

2 Comments

I guess that would mean building your own thing, I was looking to use the jqueryui.com/demos/selectable so I can take advantage of that functionality. I just need to make CTRL behavior the default one.
Links are dead.
1

honestly, I just did a find/replace for 'c.metaKey' and replaced it with 'true /* edited */' on the jqui script... Dirty, but effective.

Comments

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.