r1610 - in branches/dev/selectable: tests/visual ui
Author: paul.bakaus
Date: Thu Jan 15 09:17:02 2009
New Revision: 1610
Modified:
branches/dev/selectable/tests/visual/selectable_keyboard.html
branches/dev/selectable/ui/ui.selectable.js
Log:
dev-selectable: new version of selectable with lasso, candidate for
inclusion in 1.6
Modified: branches/dev/selectable/tests/visual/selectable_keyboard.html
==============================================================================
--- branches/dev/selectable/tests/visual/selectable_keyboard.html (original)
+++ branches/dev/selectable/tests/visual/selectable_keyboard.html Thu Jan
15 09:17:02 2009
@@ -3,8 +3,9 @@
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<title>keyboard_selection</title>
- <script type="text/javascript" src="../../jquery-1.2.6.js"></script>
- <script type="text/javascript" src="../../ui/ui.core.js"></script>
+ <script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.0/jquery.js"></script>
+ <script src="../../../../../trunk/ui/ui.core.js" type="text/javascript"
charset="utf-8"></script>
+
<script type="text/javascript" src="../../ui/ui.selectable.js"></script>
<style type="text/css" media="screen">
@@ -26,8 +27,14 @@
$("ul").selectable({
+ lasso: true,
+
select: function(event, ui) {
- //console.log(ui.selection);
+ console.log('select: ', ui.item);
+ },
+
+ unselect: function(event, ui) {
+ console.log('unselect', ui.item);
}
});
Modified: branches/dev/selectable/ui/ui.selectable.js
==============================================================================
--- branches/dev/selectable/ui/ui.selectable.js (original)
+++ branches/dev/selectable/ui/ui.selectable.js Thu Jan 15 09:17:02 2009
@@ -1,10 +1,10 @@
/*
* jQuery UI Selectable @VERSION
*
- * Copyright (c) 2008 Paul Bakaus
+ * Copyright (c) 2009 AUTHORS.txt (http://ui.jquery.com/about)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
- *
+ *
* http://docs.jquery.com/UI/Selectables
*
* Depends:
@@ -12,102 +12,214 @@
*/
(function($) {
- $.widget('ui.selectable', {
+ $.widget('ui.selectable', $.extend({}, $.ui.mouse, {
_init: function() {
var self = this;
+ this.element.addClass("ui-selectable");
//Set the currentFocus to the first item
this.currentFocus = $($(this.options.filter, this.element)[0]);
+
+ //Refresh item positions
+ this.refresh();
//Disable text selection
this.element.disableSelection();
+ //Prepare caret selection
+ if(this.options.lasso) this._mouseInit();
+
this.element
.bind('mousedown', function(event) {
- var item;
- $(event.target).parents().andSelf().each(function() {
- if ($(self.options.filter, self.element).index(this) != -1) item =
this;
- });
-
- if (!item)
- return;
+ var item = self._targetIsItem(event.target);
+ if (!item) return;
self._select(event, item);
self.element[0].focus();
event.preventDefault();
+
})
.bind('focus.selectable', function() {
- self.currentFocus.addClass(self.options.focusClass);
+ self.currentFocus.addClass('ui-focused');
})
.bind('blur.selectable', function() {
- self.currentFocus.removeClass(self.options.focusClass);
+ self.currentFocus.removeClass('ui-focused');
})
.bind('keydown.selectable', function(event) {
- if (event.keyCode == $.keyCode.DOWN || event.keyCode ==
$.keyCode.RIGHT) {
+ if(!self.options.keyboard)
+ return;
+
+ if (event.keyCode == $.ui.keyCode.DOWN || event.keyCode ==
$.ui.keyCode.RIGHT) {
self.selectNext(event);
event.preventDefault();
}
- if (event.keyCode == $.keyCode.UP || event.keyCode == $.keyCode.LEFT)
{
+ if (event.keyCode == $.ui.keyCode.UP || event.keyCode ==
$.ui.keyCode.LEFT) {
self.selectPrevious(event);
event.preventDefault();
}
- if ((event.ctrlKey || event.metaKey) && event.keyCode ==
$.keyCode.SPACE) {
- self._toggleSelection(self.currentFocus);
+ if ((event.ctrlKey || event.metaKey) && event.keyCode ==
$.ui.keyCode.SPACE) {
+ self._toggleSelection(self.currentFocus, event);
}
});
+ this.helper = $(document.createElement('div'))
+ .css({border:'1px dotted black'})
+ .addClass("ui-selectable-helper");
+
},
+ destroy: function() {
+ this.element
+ .removeClass("ui-selectable ui-selectable-disabled")
+ .removeData("selectable")
+ .unbind(".selectable");
+ this._mouseDestroy();
+ },
+
+ _mouseCapture: function(event) {
+ //If the item we start dragging on is a selectable, we bail (if
keyboard is used)
+ this.clickedOnItem = this._targetIsItem(event.target);
+ return !this.options.keyboard || !this.clickedOnItem;
+ },
+
+ _mouseStart: function(event) {
+
+ var self = this, o = this.options;
+ this.opos = [event.pageX, event.pageY];
+
+ if (o.disabled)
+ return;
+
+ //Cache positions
+ this.refresh();
+
+ //Trigger start event
+ this._trigger("start", event, this._uiHash());
+
+ // append and position helper (lasso)
+ $('body').append(this.helper);
+ this.helper.css({
+ zIndex: 100,
+ position: "absolute",
+ left: event.clientX,
+ top: event.clientY,
+ width: 0,
+ height: 0
+ });
+
+ //Tell the intersection that some start selected
+ $(this.options.filter,
this.element).filter('.ui-selected').each(function() {
+ if(event.metaKey) {
+ if(this != self.clickedOnItem)
$.data(this, "selectable-item").startSelected = true;
+ } else self._removeFromSelection($(this), event);
+ });
+
+ },
+
+ _mouseDrag: function(event) {
+
+ var self = this, o = this.options;
+
+ if (o.disabled)
+ return;
+
+ //Do the lasso magic
+ 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});
+
+ //Loop through all items and check overlaps
+ $(this.options.filter, this.element).each(function() {
+
+ var item = $.data(this, "selectable-item");
+
+ //prevent helper from being selected if appendTo: selectable
+ if (!item || item.element == self.element[0])
+ return;
+
+ var hit = false;
+ if (o.tolerance == 'touch') {
+ hit = ( !(item.left > x2 || item.right < x1 || item.top > y2 ||
item.bottom < y1) );
+ } else if (o.tolerance == 'fit') {
+ hit = (item.left > x1 && item.right < x2 && item.top > y1 &&
item.bottom < y2);
+ }
+
+ hit ?
+ item.startSelected ? self._removeFromSelection($(this), event) :
self._addToSelection($(this), event)
+ : !item.startSelected ? self._removeFromSelection($(this), event) :
self._addToSelection($(this), event);
+
+ });
+
+ return false;
+
+ },
+
+ _mouseStop: function(event) {
+ this._trigger("stop", event, this._uiHash());
+ this.helper.remove();
+ return false;
+ },
+
+ _targetIsItem: function(item) {
+ var test = false, self = this;
+ $(item).parents().andSelf().each(function() {
+ if ($(self.options.filter, self.element).index(this) != -1) test =
this;
+ });
+ return test;
+ },
+
_selection: [],
- _clearSelection: function() {
+ _clearSelection: function(triggerEvent) {
for (var i = this._selection.length - 1; i >= 0; i--){
- this._selection[i]
- .removeClass(this.options.selectClass)
- .data('ui-selected', false);
+ if(triggerEvent &&
this._selection[i].data('selectable-item').selected)
this._trigger('unselect', triggerEvent, this._uiHash(this._selection[i]));
+ this._selection[i].removeClass('ui-selected');
+ this._selection[i].data('selectable-item').selected = false;
};
this._selection = [];
},
- _toggleSelection: function(item) {
- if (item.data('ui-selected')) {
- this._removeFromSelection(item);
- } else {
- this._addToSelection(item);
- }
+ _toggleSelection: function(item, event) {
+ item.data('selectable-item').selected ?
this._removeFromSelection(item, event) : this._addToSelection(item);
},
- _addToSelection: function(item) {
+ _addToSelection: function(item, triggerEvent) {
- if (item.data('ui-selected'))
- return;
+ if (item.data('selectable-item').selected)
+ return null;
this._selection.push(item);
this.latestSelection = item;
- item
- .addClass(this.options.selectClass)
- .data('ui-selected', true);
+ item.addClass('ui-selected');
+ item.data('selectable-item').selected = true;
+
+ if(triggerEvent) {
+ this._trigger('select', triggerEvent, $.extend({ lasso: true },
this._uiHash(item)));
+ }
+
+ return item;
},
- _removeFromSelection: function(item) {
+ _removeFromSelection: function(item, triggerEvent) {
for (var i=0; i < this._selection.length; i++) {
if (this._selection[i][0] == item[0]) {
- this._selection[i]
- .removeClass(this.options.selectClass)
- .data('ui-selected', false);
+ this._selection[i].removeClass('ui-selected');
+ this._selection[i].data('selectable-item').selected = false;
this._selection.splice(i,1);
+ if(triggerEvent) this._trigger('unselect', triggerEvent,
this._uiHash($(item)));
break;
}
};
@@ -116,15 +228,17 @@
_updateSelectionMouse: function(event) {
+ var newlySelected = [];
+
if (event.shiftKey && this.options.multiple) {
//Clear the previous selection to make room for a shift selection
- this._clearSelection();
+ this._clearSelection(event);
var dir = $(this.options.filter,
this.element).index(this.latestWithoutModifier[0]) > $(this.options.filter,
this.element).index(this.currentFocus[0]) ? 'prev' : 'next';
- var i = this.latestWithoutModifier.data('ui-selected') ?
this.latestWithoutModifier[dir]() : this.latestWithoutModifier;
+ var i = this.latestWithoutModifier.data('selectable-item').selected ?
this.latestWithoutModifier[dir]() : this.latestWithoutModifier;
while(i.length && i[0] != this.currentFocus[0]) {
- this._addToSelection(i);
+ newlySelected.push(this._addToSelection(i));
i = i[dir]();
}
@@ -133,31 +247,35 @@
} else {
- if (event.ctrlKey || event.metaKey) {
- this._toggleSelection(this.currentFocus);
+ if (event.metaKey) {
+ this._toggleSelection(this.currentFocus, event);
} else {
- this._clearSelection();
- this._addToSelection(this.currentFocus);
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
this.latestWithoutModifier = this.currentFocus;
}
}
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
},
_updateSelection: function(event, dir) {
+ var newlySelected = [];
+
if (event.shiftKey && this.options.multiple) {
- if (this.currentFocus.data('ui-selected')) {
- this._removeFromSelection(this.previousFocus);
+ if (this.currentFocus.data('selectable-item').selected) {
+ this._removeFromSelection(this.previousFocus, event);
} else {
var dir2 = $(this.options.filter,
this.element).index(this.latestSelection[0]) > $(this.options.filter,
this.element).index(this.currentFocus[0]) ? 'next' : 'prev';
- if (!this.previousFocus.data('ui-selected')) {
+ if (!this.previousFocus.data('selectable-item').selected) {
var i = dir == dir2 ? this.previousFocus[dir2]() :
this.previousFocus;
- while(i.length && !i.data('ui-selected')) {
- this._addToSelection(i);
+ while(i.length && !i.data('selectable-item').selected) {
+ newlySelected.push(this._addToSelection(i));
i = i[dir2]();
}
}
@@ -169,14 +287,16 @@
} else {
//If the CTRL or Apple/Win key is pressed, only set focus
- if (event.ctrlKey || event.metaKey)
+ if (event.metaKey)
return;
- this._clearSelection();
- this._addToSelection(this.currentFocus);
+ this._clearSelection(event);
+ newlySelected.push(this._addToSelection(this.currentFocus));
this.latestWithoutModifier = this.currentFocus;
}
+
+ return $($.map(newlySelected, function(i) { return i[0]; }));
},
@@ -186,14 +306,14 @@
this.previousFocus = this.currentFocus;
this.currentFocus = $(item);
- this.previousFocus.removeClass(