Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

fix(timepicker): added wheel event to enable mousewheel on Firefox #684

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions src/timepicker/test/timepicker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ describe('timepicker directive', function () {
e.wheelDelta = delta;
return e;
}

function wheelThatOtherMouse(delta) {
var e = $.Event('wheel');
e.deltaY = delta;
return e;
}

it('contains three row & three input elements', function() {
expect(element.find('tr').length).toBe(3);
Expand Down Expand Up @@ -304,6 +310,58 @@ describe('timepicker directive', function () {
expect(getModelState()).toEqual([14, 40]);
});

it('responds properly on "wheel" events', function() {
var inputs = element.find('input');
var hoursEl = inputs.eq(0), minutesEl = inputs.eq(1);
var upMouseWheelEvent = wheelThatOtherMouse(-1);
var downMouseWheelEvent = wheelThatOtherMouse(1);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added separate test for the wheel event

the logic of deltaY is opposite of wheelDelta that why the values on up and down are inverted


expect(getTimeState()).toEqual(['02', '40', 'PM']);
expect(getModelState()).toEqual([14, 40]);

// UP
hoursEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['03', '40', 'PM']);
expect(getModelState()).toEqual([15, 40]);

hoursEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '40', 'PM']);
expect(getModelState()).toEqual([16, 40]);

minutesEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '41', 'PM']);
expect(getModelState()).toEqual([16, 41]);

minutesEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '42', 'PM']);
expect(getModelState()).toEqual([16, 42]);

// DOWN
minutesEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '41', 'PM']);
expect(getModelState()).toEqual([16, 41]);

minutesEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '40', 'PM']);
expect(getModelState()).toEqual([16, 40]);

hoursEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['03', '40', 'PM']);
expect(getModelState()).toEqual([15, 40]);

hoursEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['02', '40', 'PM']);
expect(getModelState()).toEqual([14, 40]);
});

describe('attributes', function () {
beforeEach(function() {
$rootScope.hstep = 2;
Expand Down Expand Up @@ -413,6 +471,38 @@ describe('timepicker directive', function () {
expect(getTimeState()).toEqual(['02', '00', 'PM']);
expect(getModelState()).toEqual([14, 0]);
});

it('responds properly on "wheel" events with configurable steps', function() {
var inputs = element.find('input');
var hoursEl = inputs.eq(0), minutesEl = inputs.eq(1);
var upMouseWheelEvent = wheelThatOtherMouse(-1);
var downMouseWheelEvent = wheelThatOtherMouse(1);

expect(getTimeState()).toEqual(['02', '00', 'PM']);
expect(getModelState()).toEqual([14, 0]);

// UP
hoursEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '00', 'PM']);
expect(getModelState()).toEqual([16, 0]);

minutesEl.trigger( upMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '30', 'PM']);
expect(getModelState()).toEqual([16, 30]);

// DOWN
minutesEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['04', '00', 'PM']);
expect(getModelState()).toEqual([16, 0]);

hoursEl.trigger( downMouseWheelEvent );
$rootScope.$digest();
expect(getTimeState()).toEqual(['02', '00', 'PM']);
expect(getModelState()).toEqual([14, 0]);
});

it('can handle strings as steps', function() {
var upHours = getHoursButton(true);
Expand Down
14 changes: 8 additions & 6 deletions src/timepicker/timepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,22 @@ angular.module('ui.bootstrap.timepicker', [])
// Respond on mousewheel spin
var mousewheel = (angular.isDefined(attrs.mousewheel)) ? scope.$eval(attrs.mousewheel) : timepickerConfig.mousewheel;
if ( mousewheel ) {

var isScrollingUp = function(e) {
if (e.originalEvent) {
e = e.originalEvent;
}
return (e.detail || e.wheelDelta > 0);
//pick correct delta variable depending on event
var delta = (e.wheelDelta) ? e.wheelDelta : -e.deltaY;
return (e.detail || delta > 0);
};

hoursInputEl.bind('mousewheel', function(e) {
hoursInputEl.bind('mousewheel wheel', function(e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added the wheel event so if the browser supports one or the other both work

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed mousewheel is deprecated in favor of the standard wheel event. What about just replacing mousewheel with wheel? Which browsers we will "lose"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make some test to check

scope.$apply( (isScrollingUp(e)) ? scope.incrementHours() : scope.decrementHours() );
e.preventDefault();
});

minutesInputEl.bind('mousewheel', function(e) {
minutesInputEl.bind('mousewheel wheel', function(e) {
scope.$apply( (isScrollingUp(e)) ? scope.incrementMinutes() : scope.decrementMinutes() );
e.preventDefault();
});
Expand Down Expand Up @@ -212,4 +214,4 @@ angular.module('ui.bootstrap.timepicker', [])
};
}
};
}]);
}]);