forked from petele/WebApp-CodeLab
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add wUp directive for handling keydowns
I had to move almost all the logic into the root controller, which is not nice, but I will refractor it into a service later...
- Loading branch information
Showing
2 changed files
with
109 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -80,7 +80,7 @@ function DataController($scope, $http, $filter) { | |
// Load items from the server after we've loaded everything from the local | ||
// data store. | ||
$scope.getItemsFromServer(); | ||
|
||
//$scope.clearFilter(); // Show all items by default. | ||
}); | ||
}; | ||
|
@@ -179,6 +179,33 @@ function DataController($scope, $http, $filter) { | |
return $scope.allItems.filter(function(val, i) { return val.starred }).length; | ||
}; | ||
|
||
// Advances to the next item. | ||
$scope.navDown = function(opt_delta) { | ||
var delta = opt_delta || 1; | ||
var selectedItem = $scope.selectedItem(); | ||
var index = selectedItem.item != null ? selectedItem.index + delta : 0; | ||
|
||
if (0 <= index && index < $scope.items.length) { | ||
$scope.selectItem(index); | ||
} | ||
}; | ||
|
||
// Goes back to the previous item. | ||
$scope.navUp = function() { | ||
$scope.navDown(-1); | ||
}; | ||
|
||
// Click handler to toggle the selected items star status | ||
$scope.toggleStar = function() { | ||
$scope.$parent.toggleStar(); | ||
}; | ||
|
||
// Click handler to toggle the selected items read status | ||
$scope.toggleRead = function() { | ||
$scope.$parent.toggleRead(); | ||
}; | ||
|
||
// Click handler to mark all as read | ||
$scope.markAllRead = function() { | ||
// Iterate through all items, and set read=true in the data controller | ||
// then set read=true in the data store. | ||
|
@@ -188,6 +215,16 @@ function DataController($scope, $http, $filter) { | |
}); | ||
}; | ||
|
||
$scope.selectedItem = function() { | ||
for (var i = 0, item; item = $scope.items[i]; ++i) { | ||
if (item.selected == true) { | ||
return {item: item, index: i}; | ||
} | ||
} | ||
return {item: null, index: null}; | ||
}; | ||
|
||
|
||
$scope.clearFilter = function() { | ||
$scope.items = $scope.allItems; | ||
}; | ||
|
@@ -198,46 +235,26 @@ function DataController($scope, $http, $filter) { | |
}); | ||
}; | ||
|
||
// Fetch items when the constructor is called. | ||
$scope.getItemsFromDataStore(); | ||
} | ||
|
||
DataController.$inject = ['$scope', '$http', '$filter']; // For JS compilers. | ||
|
||
|
||
function ItemsController($scope) { //{, $location) { | ||
// A special observer that will watch for when the 'selectedItem' is updated | ||
// and ensure that we scroll into a view so that the selected item is visible | ||
// in the summary list view. | ||
$scope.$watch('selectedItem().index', function(newVal, oldVal, scope) { | ||
// TODO: Performing scrolling like this doesn't seem very Angular-ly. | ||
// Need the setTimeout to prevent race condition with item being selected. | ||
if (newVal != null) { | ||
window.setTimeout(function() { | ||
var curScrollPos = $('.summaries').scrollTop(); | ||
var itemTop = $('.summary.active').offset().top - 60; | ||
$('.summaries').animate({'scrollTop': curScrollPos + itemTop}, 200); | ||
}, 0); | ||
} | ||
}); | ||
|
||
$scope.selectedItem = function() { | ||
for (var i = 0, item; item = $scope.$parent.items[i]; ++i) { | ||
if (item.selected == true) { | ||
return {item: item, index: i}; | ||
} | ||
$scope.handleSpace = function() { | ||
var itemHeight = $('.entry.active').height() + 60; | ||
var winHeight = $(window).height(); | ||
var curScroll = $('.entries').scrollTop(); | ||
var scroll = curScroll + winHeight; | ||
if (scroll < itemHeight) { | ||
$('.entries').scrollTop(scroll); | ||
} else { | ||
$scope.navDown(); | ||
} | ||
return {item: null, index: null}; | ||
}; | ||
|
||
$scope.hasNext = function() { | ||
var selectedItem = $scope.selectedItem(); | ||
if (selectedItem.index == null) { | ||
return true; | ||
} | ||
return selectedItem.index < $scope.$parent.items.length - 1; | ||
return selectedItem.index < $scope.items.length - 1; | ||
}; | ||
|
||
$scope.hasPrev = function() { | ||
var selectedItem = $scope.selectedItem(); | ||
if (selectedItem.index == null) { | ||
|
@@ -256,7 +273,7 @@ function ItemsController($scope) { //{, $location) { | |
} | ||
|
||
if (opt_idx != undefined) { | ||
selectedItem = $scope.$parent.items[opt_idx]; | ||
selectedItem = $scope.items[opt_idx]; | ||
selectedItem.selected = true; | ||
} else { | ||
this.item.selected = true; | ||
|
@@ -273,18 +290,7 @@ function ItemsController($scope) { //{, $location) { | |
//history.pushState(item.get('item_id'), 'title', url + item_url); | ||
}; | ||
|
||
// Advances to the next item. | ||
$scope.next = function(opt_delta) { | ||
var delta = opt_delta || 1; | ||
|
||
var selectedItem = $scope.selectedItem(); | ||
$scope.selectItem(selectedItem.item != null ? selectedItem.index + delta : 0); | ||
}; | ||
|
||
// Goes back to the previous item. | ||
$scope.prev = function() { | ||
$scope.next(-1); | ||
}; | ||
|
||
// Toggles or sets the read state with an optional boolean | ||
$scope.toggleRead = function(opt_read) { | ||
|
@@ -303,14 +309,41 @@ function ItemsController($scope) { //{, $location) { | |
var key = selectedItem.item_id; | ||
store.toggleStar(key, star); | ||
}; | ||
|
||
// Fetch items when the constructor is called. | ||
$scope.getItemsFromDataStore(); | ||
} | ||
|
||
DataController.$inject = ['$scope', '$http', '$filter']; // For JS compilers. | ||
|
||
|
||
function ItemsController($scope) { //{, $location) { | ||
// A special observer that will watch for when the 'selectedItem' is updated | ||
// and ensure that we scroll into a view so that the selected item is visible | ||
// in the summary list view. | ||
$scope.$watch('selectedItem().index', function(newVal, oldVal, scope) { | ||
// TODO: Performing scrolling like this doesn't seem very Angular-ly. | ||
// Need the setTimeout to prevent race condition with item being selected. | ||
if (newVal != null) { | ||
window.setTimeout(function() { | ||
var curScrollPos = $('.summaries').scrollTop(); | ||
var itemTop = $('.summary.active').offset().top - 60; | ||
$('.summaries').animate({'scrollTop': curScrollPos + itemTop}, 200); | ||
}, 0); | ||
} | ||
}); | ||
|
||
|
||
|
||
|
||
} | ||
|
||
ItemsController.$inject = ['$scope'];//, '$location']; // For JS compilers. | ||
//ItemsController.prototype = Object.create(DataController.prototype); | ||
|
||
// Top Menu/Nav Bar | ||
function NavBarController($scope) {//, $injector) { | ||
//$injector.invoke(ItemsController, this, {$scope: $scope}); | ||
//$injector.invoke(ItemsController, this, {$scope: $scope}); | ||
|
||
// Click handler for menu bar | ||
$scope.showAll = function() { | ||
|
@@ -345,86 +378,47 @@ NavBarController.$inject = ['$scope']; // For JS compilers. | |
|
||
function NavControlsView($scope) { | ||
|
||
// Click handler for up/previous button | ||
$scope.navUp = function() { | ||
$scope.$parent.prev(); | ||
}; | ||
|
||
// Click handler for down/next button | ||
$scope.navDown = function() { | ||
$scope.$parent.next(); | ||
}; | ||
|
||
// Click handler to toggle the selected items star status | ||
$scope.toggleStar = function() { | ||
$scope.$parent.toggleStar(); | ||
}; | ||
|
||
// Click handler to toggle the selected items read status | ||
$scope.toggleRead = function() { | ||
$scope.$parent.toggleRead(); | ||
}; | ||
|
||
// Click handler to mark all as read | ||
$scope.markAllRead = function() { | ||
$scope.$parent.markAllRead(); | ||
}; | ||
|
||
// Click handler for refresh | ||
$scope.refresh = function() { | ||
$scope.getItemsFromServer(); | ||
}; | ||
} | ||
|
||
wReader.directive('wUp', function() { | ||
This comment has been minimized.
Sorry, something went wrong.
This comment has been minimized.
Sorry, something went wrong.
vojtajina
Author
Owner
|
||
return function(scope, elm, attr) { | ||
elm.bind('keydown', function(e) { | ||
switch (e.keyCode) { | ||
case 34: // PgDn | ||
case 39: // right arrow | ||
case 40: // down arrow | ||
case 74: // j | ||
return scope.$apply(attr.wDown); | ||
|
||
case 32: // Space | ||
e.preventDefault(); | ||
return scope.$apply(attr.wSpace); | ||
|
||
case 33: // PgUp | ||
case 37: // left arrow | ||
case 38: // up arrow | ||
case 75: // k | ||
return scope.$apply(attr.wUp); | ||
|
||
case 85: // U | ||
return scope.$apply(attr.wRead); | ||
|
||
case 72: // H | ||
return scope.$apply(attr.wStar); | ||
} | ||
}); | ||
}; | ||
}); | ||
|
||
function handleSpace() { | ||
var itemHeight = $('.entry.active').height() + 60; | ||
var winHeight = $(window).height(); | ||
var curScroll = $('.entries').scrollTop(); | ||
var scroll = curScroll + winHeight; | ||
if (scroll < itemHeight) { | ||
$('.entries').scrollTop(scroll); | ||
} else { | ||
$('.controls button[ng-click="navDown()"]').click(); | ||
} | ||
}; | ||
|
||
function handleBodyKeyDown(e) { | ||
switch (e.keyCode) { | ||
case 34: // PgDn | ||
case 39: // right arrow | ||
case 40: // down arrow | ||
case 74: // j | ||
$('.controls button[ng-click="navDown()"]').click(); // TODO: figure out angular way | ||
break; | ||
|
||
case 32: // Space | ||
handleSpace(); | ||
e.preventDefault(); | ||
break; | ||
|
||
case 33: // PgUp | ||
case 37: // left arrow | ||
case 38: // up arrow | ||
case 75: // k | ||
$('.controls button[ng-click="navUp()"]').click(); | ||
break; | ||
|
||
case 85: // U | ||
$('.controls button[ng-click="toggleRead()"]').click(); | ||
break; | ||
|
||
case 72: // H | ||
$('.controls button[ng-click="toggleStar()"]').click(); | ||
break; | ||
} | ||
} | ||
|
||
function handlePopState(e) { | ||
//console.log("Pop State", e); | ||
} | ||
|
||
document.body.addEventListener('keydown', handleBodyKeyDown, false); | ||
window.addEventListener('popstate', handlePopState, false); | ||
|
||
document.addEventListener('DOMContentLoaded', function(e) { | ||
|
This is really weird since w-up actually binds lots of keyboard handling that's not "up". I'm not sure this follows best practice you'd want in a demo app. Feels like a hack.