Selectable: Style updates

Ref #14246
This commit is contained in:
Alexander Schmitz 2015-08-24 08:58:20 -04:00
parent e583a512d7
commit 9a015df3a3
5 changed files with 182 additions and 174 deletions

View File

@ -24,6 +24,6 @@ common.testWidget( "selectable", {
unselected: null, unselected: null,
unselecting: null unselecting: null
} }
}); } );
} ); } );

View File

@ -4,37 +4,37 @@ define( [
"ui/widgets/selectable" "ui/widgets/selectable"
], function( $, testHelpers ) { ], function( $, testHelpers ) {
module("selectable: events"); module( "selectable: events" );
test( "start", function() { test( "start", function() {
expect( 2 ); expect( 2 );
var el = $("#selectable1"); var el = $( "#selectable1" );
el.selectable({ el.selectable( {
start: function() { start: function() {
ok( true, "drag fired start callback" ); ok( true, "drag fired start callback" );
equal( this, el[0], "context of callback" ); equal( this, el[ 0 ], "context of callback" );
} }
}); } );
el.simulate( "drag", { el.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
}); } );
test( "stop", function() { test( "stop", function() {
expect( 2 ); expect( 2 );
var el = $("#selectable1"); var el = $( "#selectable1" );
el.selectable({ el.selectable( {
start: function() { start: function() {
ok( true, "drag fired stop callback" ); ok( true, "drag fired stop callback" );
equal( this, el[0], "context of callback" ); equal( this, el[ 0 ], "context of callback" );
} }
}); } );
el.simulate( "drag", { el.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
}); } );
test( "mousedown: initial position of helper", function() { test( "mousedown: initial position of helper", function() {
expect( 2 ); expect( 2 );
@ -48,7 +48,7 @@ test( "mousedown: initial position of helper", function() {
element.simulate( "mousedown", { element.simulate( "mousedown", {
clientX: 10, clientX: 10,
clientY: 10 clientY: 10
}); } );
helperOffset = $( ".ui-selectable-helper" ).offset(); helperOffset = $( ".ui-selectable-helper" ).offset();
ok( helperOffset.top, 110, "Scroll top should be accounted for." ); ok( helperOffset.top, 110, "Scroll top should be accounted for." );
@ -58,6 +58,6 @@ test( "mousedown: initial position of helper", function() {
element.simulate( "mouseup" ); element.simulate( "mouseup" );
contentToForceScroll.remove(); contentToForceScroll.remove();
$( window ).scrollTop( 0 ).scrollLeft( 0 ); $( window ).scrollTop( 0 ).scrollLeft( 0 );
}); } );
} ); } );

View File

@ -3,73 +3,73 @@ define( [
"ui/widgets/selectable" "ui/widgets/selectable"
], function( $ ) { ], function( $ ) {
module("selectable: methods"); module( "selectable: methods" );
test("init", function() { test( "init", function() {
expect( 5 ); expect( 5 );
$("<div></div>").appendTo("body").selectable().remove(); $( "<div></div>" ).appendTo( "body" ).selectable().remove();
ok(true, ".selectable() called on element"); ok( true, ".selectable() called on element" );
$([]).selectable().remove(); $( [] ).selectable().remove();
ok(true, ".selectable() called on empty collection"); ok( true, ".selectable() called on empty collection" );
$("<div></div>").selectable().remove(); $( "<div></div>" ).selectable().remove();
ok(true, ".selectable() called on disconnected DOMElement"); ok( true, ".selectable() called on disconnected DOMElement" );
var el = $("<div></div>").selectable(); var el = $( "<div></div>" ).selectable();
el.selectable("option", "foo"); el.selectable( "option", "foo" );
el.remove(); el.remove();
ok(true, "arbitrary option getter after init"); ok( true, "arbitrary option getter after init" );
$("<div></div>").selectable().selectable("option", "foo", "bar").remove(); $( "<div></div>" ).selectable().selectable( "option", "foo", "bar" ).remove();
ok(true, "arbitrary option setter after init"); ok( true, "arbitrary option setter after init" );
}); } );
test("destroy", function() { test( "destroy", function() {
expect( 4 ); expect( 4 );
$("<div></div>").appendTo("body").selectable().selectable("destroy").remove(); $( "<div></div>" ).appendTo( "body" ).selectable().selectable( "destroy" ).remove();
ok(true, ".selectable('destroy') called on element"); ok( true, ".selectable('destroy') called on element" );
$([]).selectable().selectable("destroy").remove(); $( [] ).selectable().selectable( "destroy" ).remove();
ok(true, ".selectable('destroy') called on empty collection"); ok( true, ".selectable('destroy') called on empty collection" );
$("<div></div>").selectable().selectable("destroy").remove(); $( "<div></div>" ).selectable().selectable( "destroy" ).remove();
ok(true, ".selectable('destroy') called on disconnected DOMElement"); ok( true, ".selectable('destroy') called on disconnected DOMElement" );
var expected = $("<div></div>").selectable(), var expected = $( "<div></div>" ).selectable(),
actual = expected.selectable("destroy"); actual = expected.selectable( "destroy" );
equal(actual, expected, "destroy is chainable"); equal( actual, expected, "destroy is chainable" );
}); } );
test("enable", function() { test( "enable", function() {
expect(3); expect( 3 );
var expected, actual, var expected, actual,
fired = false, fired = false,
el = $("#selectable1"); el = $( "#selectable1" );
el.selectable({ el.selectable( {
disabled: true, disabled: true,
start: function() { fired = true; } start: function() { fired = true; }
}); } );
el.simulate( "drag", { el.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
equal(fired, false, "start fired"); equal( fired, false, "start fired" );
el.selectable("enable"); el.selectable( "enable" );
el.simulate( "drag", { el.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
equal(fired, true, "start fired"); equal( fired, true, "start fired" );
el.selectable("destroy"); el.selectable( "destroy" );
expected = $("<div></div>").selectable(); expected = $( "<div></div>" ).selectable();
actual = expected.selectable("enable"); actual = expected.selectable( "enable" );
equal(actual, expected, "enable is chainable"); equal( actual, expected, "enable is chainable" );
}); } );
test( "disable", function( assert ) { test( "disable", function( assert ) {
expect( 6 ); expect( 6 );
@ -77,16 +77,16 @@ test( "disable", function( assert ) {
fired = false, fired = false,
element = $( "#selectable1" ); element = $( "#selectable1" );
element.selectable({ element.selectable( {
disabled: false, disabled: false,
start: function() { start: function() {
fired = true; fired = true;
} }
}); } );
element.simulate( "drag", { element.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
equal( fired, true, "start fired" ); equal( fired, true, "start fired" );
chainable = element.selectable( "disable" ); chainable = element.selectable( "disable" );
@ -95,7 +95,7 @@ test( "disable", function( assert ) {
element.simulate( "drag", { element.simulate( "drag", {
dx: 20, dx: 20,
dy: 20 dy: 20
}); } );
equal( fired, false, "start fired" ); equal( fired, false, "start fired" );
assert.lacksClasses( element.selectable( "widget" ), "ui-state-disabled" ); assert.lacksClasses( element.selectable( "widget" ), "ui-state-disabled" );
@ -106,6 +106,6 @@ test( "disable", function( assert ) {
element.selectable( "destroy" ); element.selectable( "destroy" );
equal( chainable, element, "disable is chainable" ); equal( chainable, element, "disable is chainable" );
}); } );
} ); } );

View File

@ -3,62 +3,62 @@ define( [
"ui/widgets/selectable" "ui/widgets/selectable"
], function( $ ) { ], function( $ ) {
module("selectable: options"); module( "selectable: options" );
test("autoRefresh", function() { test( "autoRefresh", function() {
expect(3); expect( 3 );
var actual = 0, var actual = 0,
el = $("#selectable1"), el = $( "#selectable1" ),
sel = $("*", el), sel = $( "*", el ),
selected = function() { actual += 1; }; selected = function() { actual += 1; };
el = $("#selectable1").selectable({ autoRefresh: false, selected: selected }); el = $( "#selectable1" ).selectable( { autoRefresh: false, selected: selected } );
sel.hide(); sel.hide();
el.simulate( "drag", { el.simulate( "drag", {
dx: 1000, dx: 1000,
dy: 1000 dy: 1000
}); } );
equal(actual, sel.length); equal( actual, sel.length );
el.selectable("destroy"); el.selectable( "destroy" );
actual = 0; actual = 0;
sel.show(); sel.show();
el = $("#selectable1").selectable({ autoRefresh: true, selected: selected }); el = $( "#selectable1" ).selectable( { autoRefresh: true, selected: selected } );
sel.hide(); sel.hide();
el.simulate( "drag", { el.simulate( "drag", {
dx: 1000, dx: 1000,
dy: 1000 dy: 1000
}); } );
equal(actual, 0); equal( actual, 0 );
sel.show(); sel.show();
$( sel[ 0 ] ).simulate( "drag", { $( sel[ 0 ] ).simulate( "drag", {
dx: 1000, dx: 1000,
dy: 1000 dy: 1000
}); } );
equal(actual, sel.length); equal( actual, sel.length );
el.selectable("destroy"); el.selectable( "destroy" );
sel.show(); sel.show();
}); } );
test("filter", function() { test( "filter", function() {
expect(2); expect( 2 );
var actual =0, var actual = 0,
el = $("#selectable1"), el = $( "#selectable1" ),
sel = $("*", el), sel = $( "*", el ),
selected = function() { actual += 1; }; selected = function() { actual += 1; };
el = $("#selectable1").selectable({ filter: ".special", selected: selected }); el = $( "#selectable1" ).selectable( { filter: ".special", selected: selected } );
el.simulate( "drag", { el.simulate( "drag", {
dx: 1000, dx: 1000,
dy: 1000 dy: 1000
}); } );
ok(sel.length !== 1, "this test assumes more than 1 selectee"); ok( sel.length !== 1, "this test assumes more than 1 selectee" );
equal(actual, 1); equal( actual, 1 );
el.selectable("destroy"); el.selectable( "destroy" );
}); } );
} ); } );

View File

@ -14,11 +14,11 @@
//>>demos: http://jqueryui.com/selectable/ //>>demos: http://jqueryui.com/selectable/
//>>css.structure: ../themes/base/selectable.css //>>css.structure: ../themes/base/selectable.css
(function( factory ) { ( function( factory ) {
if ( typeof define === "function" && define.amd ) { if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module. // AMD. Register as an anonymous module.
define([ define( [
"jquery", "jquery",
"./mouse", "./mouse",
"../version", "../version",
@ -29,9 +29,9 @@
// Browser globals // Browser globals
factory( jQuery ); factory( jQuery );
} }
}(function( $ ) { }( function( $ ) {
return $.widget("ui.selectable", $.ui.mouse, { return $.widget( "ui.selectable", $.ui.mouse, {
version: "@VERSION", version: "@VERSION",
options: { options: {
appendTo: "body", appendTo: "body",
@ -57,12 +57,12 @@ return $.widget("ui.selectable", $.ui.mouse, {
// Cache selectee children based on filter // Cache selectee children based on filter
this.refresh = function() { this.refresh = function() {
that.selectees = $(that.options.filter, that.element[0]); that.selectees = $( that.options.filter, that.element[ 0 ] );
that._addClass( that.selectees, "ui-selectee" ); that._addClass( that.selectees, "ui-selectee" );
that.selectees.each(function() { that.selectees.each( function() {
var $this = $(this), var $this = $( this ),
pos = $this.offset(); pos = $this.offset();
$.data(this, "selectable-item", { $.data( this, "selectable-item", {
element: this, element: this,
$element: $this, $element: $this,
left: pos.left, left: pos.left,
@ -70,150 +70,156 @@ return $.widget("ui.selectable", $.ui.mouse, {
right: pos.left + $this.outerWidth(), right: pos.left + $this.outerWidth(),
bottom: pos.top + $this.outerHeight(), bottom: pos.top + $this.outerHeight(),
startselected: false, startselected: false,
selected: $this.hasClass("ui-selected"), selected: $this.hasClass( "ui-selected" ),
selecting: $this.hasClass("ui-selecting"), selecting: $this.hasClass( "ui-selecting" ),
unselecting: $this.hasClass("ui-unselecting") unselecting: $this.hasClass( "ui-unselecting" )
}); } );
}); } );
}; };
this.refresh(); this.refresh();
this._mouseInit(); this._mouseInit();
this.helper = $("<div>"); this.helper = $( "<div>" );
this._addClass( this.helper, "ui-selectable-helper" ); this._addClass( this.helper, "ui-selectable-helper" );
}, },
_destroy: function() { _destroy: function() {
this.selectees.removeData("selectable-item"); this.selectees.removeData( "selectable-item" );
this._mouseDestroy(); this._mouseDestroy();
}, },
_mouseStart: function(event) { _mouseStart: function( event ) {
var that = this, var that = this,
options = this.options; options = this.options;
this.opos = [ event.pageX, event.pageY ]; this.opos = [ event.pageX, event.pageY ];
if (this.options.disabled) { if ( this.options.disabled ) {
return; return;
} }
this.selectees = $(options.filter, this.element[0]); this.selectees = $( options.filter, this.element[ 0 ] );
this._trigger("start", event); this._trigger( "start", event );
$( options.appendTo ).append( this.helper );
$(options.appendTo).append(this.helper);
// position helper (lasso) // position helper (lasso)
this.helper.css({ this.helper.css( {
"left": event.pageX, "left": event.pageX,
"top": event.pageY, "top": event.pageY,
"width": 0, "width": 0,
"height": 0 "height": 0
}); } );
if (options.autoRefresh) { if ( options.autoRefresh ) {
this.refresh(); this.refresh();
} }
this.selectees.filter(".ui-selected").each(function() { this.selectees.filter( ".ui-selected" ).each( function() {
var selectee = $.data(this, "selectable-item"); var selectee = $.data( this, "selectable-item" );
selectee.startselected = true; selectee.startselected = true;
if (!event.metaKey && !event.ctrlKey) { if ( !event.metaKey && !event.ctrlKey ) {
that._removeClass( selectee.$element, "ui-selected" ); that._removeClass( selectee.$element, "ui-selected" );
selectee.selected = false; selectee.selected = false;
that._addClass( selectee.$element, "ui-unselecting" ); that._addClass( selectee.$element, "ui-unselecting" );
selectee.unselecting = true; selectee.unselecting = true;
// selectable UNSELECTING callback
that._trigger("unselecting", event, {
unselecting: selectee.element
});
}
});
$(event.target).parents().addBack().each(function() { // selectable UNSELECTING callback
that._trigger( "unselecting", event, {
unselecting: selectee.element
} );
}
} );
$( event.target ).parents().addBack().each( function() {
var doSelect, var doSelect,
selectee = $.data(this, "selectable-item"); selectee = $.data( this, "selectable-item" );
if (selectee) { if ( selectee ) {
doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected"); doSelect = ( !event.metaKey && !event.ctrlKey ) || !selectee.$element.hasClass( "ui-selected" );
that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" ) that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" ); ._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
selectee.unselecting = !doSelect; selectee.unselecting = !doSelect;
selectee.selecting = doSelect; selectee.selecting = doSelect;
selectee.selected = doSelect; selectee.selected = doSelect;
// selectable (UN)SELECTING callback // selectable (UN)SELECTING callback
if (doSelect) { if ( doSelect ) {
that._trigger("selecting", event, { that._trigger( "selecting", event, {
selecting: selectee.element selecting: selectee.element
}); } );
} else { } else {
that._trigger("unselecting", event, { that._trigger( "unselecting", event, {
unselecting: selectee.element unselecting: selectee.element
}); } );
} }
return false; return false;
} }
}); } );
}, },
_mouseDrag: function(event) { _mouseDrag: function( event ) {
this.dragged = true; this.dragged = true;
if (this.options.disabled) { if ( this.options.disabled ) {
return; return;
} }
var tmp, var tmp,
that = this, that = this,
options = this.options, options = this.options,
x1 = this.opos[0], x1 = this.opos[ 0 ],
y1 = this.opos[1], y1 = this.opos[ 1 ],
x2 = event.pageX, x2 = event.pageX,
y2 = event.pageY; y2 = event.pageY;
if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; } if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; } if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
this.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 }); this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
this.selectees.each(function() { this.selectees.each( function() {
var selectee = $.data(this, "selectable-item"), var selectee = $.data( this, "selectable-item" ),
hit = false; hit = false;
//prevent helper from being selected if appendTo: selectable //prevent helper from being selected if appendTo: selectable
if (!selectee || selectee.element === that.element[0]) { if ( !selectee || selectee.element === that.element[ 0 ] ) {
return; return;
} }
if (options.tolerance === "touch") { if ( options.tolerance === "touch" ) {
hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) ); hit = ( !( selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1 ) );
} else if (options.tolerance === "fit") { } else if ( options.tolerance === "fit" ) {
hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2); hit = ( selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2 );
} }
if (hit) { if ( hit ) {
// SELECT // SELECT
if (selectee.selected) { if ( selectee.selected ) {
that._removeClass( selectee.$element, "ui-selected" ); that._removeClass( selectee.$element, "ui-selected" );
selectee.selected = false; selectee.selected = false;
} }
if (selectee.unselecting) { if ( selectee.unselecting ) {
that._removeClass( selectee.$element, "ui-unselecting" ); that._removeClass( selectee.$element, "ui-unselecting" );
selectee.unselecting = false; selectee.unselecting = false;
} }
if (!selectee.selecting) { if ( !selectee.selecting ) {
that._addClass( selectee.$element, "ui-selecting" ); that._addClass( selectee.$element, "ui-selecting" );
selectee.selecting = true; selectee.selecting = true;
// selectable SELECTING callback // selectable SELECTING callback
that._trigger("selecting", event, { that._trigger( "selecting", event, {
selecting: selectee.element selecting: selectee.element
}); } );
} }
} else { } else {
// UNSELECT // UNSELECT
if (selectee.selecting) { if ( selectee.selecting ) {
if ((event.metaKey || event.ctrlKey) && selectee.startselected) { if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
that._removeClass( selectee.$element, "ui-selecting" ); that._removeClass( selectee.$element, "ui-selecting" );
selectee.selecting = false; selectee.selecting = false;
that._addClass( selectee.$element, "ui-selected" ); that._addClass( selectee.$element, "ui-selected" );
@ -221,67 +227,69 @@ return $.widget("ui.selectable", $.ui.mouse, {
} else { } else {
that._removeClass( selectee.$element, "ui-selecting" ); that._removeClass( selectee.$element, "ui-selecting" );
selectee.selecting = false; selectee.selecting = false;
if (selectee.startselected) { if ( selectee.startselected ) {
that._addClass( selectee.$element, "ui-unselecting" ); that._addClass( selectee.$element, "ui-unselecting" );
selectee.unselecting = true; selectee.unselecting = true;
} }
// selectable UNSELECTING callback // selectable UNSELECTING callback
that._trigger("unselecting", event, { that._trigger( "unselecting", event, {
unselecting: selectee.element unselecting: selectee.element
}); } );
} }
} }
if (selectee.selected) { if ( selectee.selected ) {
if (!event.metaKey && !event.ctrlKey && !selectee.startselected) { if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
that._removeClass( selectee.$element, "ui-selected" ); that._removeClass( selectee.$element, "ui-selected" );
selectee.selected = false; selectee.selected = false;
that._addClass( selectee.$element, "ui-unselecting" ); that._addClass( selectee.$element, "ui-unselecting" );
selectee.unselecting = true; selectee.unselecting = true;
// selectable UNSELECTING callback // selectable UNSELECTING callback
that._trigger("unselecting", event, { that._trigger( "unselecting", event, {
unselecting: selectee.element unselecting: selectee.element
}); } );
} }
} }
} }
}); } );
return false; return false;
}, },
_mouseStop: function(event) { _mouseStop: function( event ) {
var that = this; var that = this;
this.dragged = false; this.dragged = false;
$(".ui-unselecting", this.element[0]).each(function() { $( ".ui-unselecting", this.element[ 0 ] ).each( function() {
var selectee = $.data(this, "selectable-item"); var selectee = $.data( this, "selectable-item" );
that._removeClass( selectee.$element, "ui-unselecting" ); that._removeClass( selectee.$element, "ui-unselecting" );
selectee.unselecting = false; selectee.unselecting = false;
selectee.startselected = false; selectee.startselected = false;
that._trigger("unselected", event, { that._trigger( "unselected", event, {
unselected: selectee.element unselected: selectee.element
}); } );
}); } );
$(".ui-selecting", this.element[0]).each(function() { $( ".ui-selecting", this.element[ 0 ] ).each( function() {
var selectee = $.data(this, "selectable-item"); var selectee = $.data( this, "selectable-item" );
that._removeClass( selectee.$element, "ui-selecting" ) that._removeClass( selectee.$element, "ui-selecting" )
._addClass( selectee.$element, "ui-selected" ); ._addClass( selectee.$element, "ui-selected" );
selectee.selecting = false; selectee.selecting = false;
selectee.selected = true; selectee.selected = true;
selectee.startselected = true; selectee.startselected = true;
that._trigger("selected", event, { that._trigger( "selected", event, {
selected: selectee.element selected: selectee.element
}); } );
}); } );
this._trigger("stop", event); this._trigger( "stop", event );
this.helper.remove(); this.helper.remove();
return false; return false;
} }
}); } );
})); } ) );