list updates

This commit is contained in:
Adam Bradley
2013-12-12 10:46:04 -06:00
parent 2720727179
commit d9eb0440e6
10 changed files with 1070 additions and 494 deletions

27
dist/css/ionic.css vendored
View File

@@ -1,4 +1,3 @@
@charset "UTF-8";
/*!
* Copyright 2013 Drifty Co.
* http://drifty.com/
@@ -4161,7 +4160,7 @@ button.item-button-right:after {
line-height: 100%; }
.item-edit .button {
height: 100%; }
.item-edit .button .icon, .item-edit .button i {
.item-edit .button.icon {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
@@ -4175,6 +4174,7 @@ button.item-button-right:after {
align-items: center;
position: absolute;
top: 0;
left: 0;
height: 100%;
color: #ef4e3a;
font-size: 24px; }
@@ -4202,12 +4202,13 @@ button.item-button-right:after {
top: 0;
right: 0;
z-index: 0;
height: 100%; }
width: 50px;
height: 100%;
background: inherit; }
.item-drag .button {
height: 100%;
border: none;
border-radius: 0; }
.item-drag .button .icon, .item-drag .button i {
min-width: 42px; }
.item-drag .button.icon:before {
display: -webkit-box;
display: -webkit-flex;
display: -moz-box;
@@ -4222,7 +4223,7 @@ button.item-button-right:after {
position: absolute;
top: 0;
height: 100%;
font-size: 24px; }
font-size: 32px; }
/**
* The hidden right-side buttons that can be exposed under a list item
@@ -4239,6 +4240,9 @@ button.item-button-right:after {
border: none;
border-radius: 0; }
.item-options-hide .item-options {
display: none; }
/**
* Lists
* --------------------------------------------------
@@ -4252,12 +4256,16 @@ button.item-button-right:after {
/**
* List editing styles. These trigger when the entire list goes into
* "edit mode"
* "edit mode" or reordering list items
*/
.list-editing .item-content {
margin-right: 50px;
margin-left: 50px; }
.list-reordering .item-content {
margin-right: 50px; }
.list-reordering .item-drag {
z-index: 1; }
/**
* List Header
* --------------------------------------------------
@@ -5389,7 +5397,6 @@ input[type="range"] {
padding: 0 6px;
min-width: initial;
border-color: transparent;
background: none;
background: none; }
.button-icon.button:active, .button-icon.button.active {
border-color: transparent;

View File

@@ -1,4 +1,3 @@
@charset "UTF-8";
/*!
* Copyright 2013 Drifty Co.
* http://drifty.com/

View File

@@ -801,191 +801,222 @@ angular.module('ionic.ui.content', [])
angular.module('ionic.ui.list', ['ngAnimate'])
.directive('linkItem', ['$timeout', function($timeout) {
.directive('item', ['$timeout', function($timeout) {
return {
restrict: 'E',
require: ['?^list'],
require: '?^list',
replace: true,
transclude: true,
scope: {
item: '=',
onSelect: '&',
onDelete: '&',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
buttons: '=',
type: '@',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@'
},
template: '<div class="item item-complex" ng-class="itemClass" ng-click="selectClick()">\
<div class="item-edit" ng-if="deleteClick !== undefined">\
<button class="button button-icon icon" ng-class="deleteIconClass" ng-click="deleteClick()"></button>\
</div>\
<div class="item-content" ng-transclude></div>\
<div class="item-drag" ng-if="reorderIconClass !== undefined">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIconClass"></button>\
</div>\
<div class="item-options" ng-if="itemOptionButtons">\
<button ng-click="b.onClick(item, b)" class="button" ng-class="b.type" ng-repeat="b in itemOptionButtons" ng-bind="b.text"></button>\
</div>\
</div>',
link: function($scope, $element, $attr, list) {
if(!list) return;
var $parentScope = list.scope;
var $parentAttrs = list.attrs;
// Set this item's class, first from the item directive attr, and then the list attr if item not set
$scope.itemClass = $scope.itemType || $parentScope.itemType;
// Decide if this item can do stuff, and follow a certain priority
// depending on where the value comes from
if(($attr.canDelete ? $scope.canDelete : $parentScope.canDelete) !== "false") {
if($attr.onDelete || $parentAttrs.onDelete) {
// only assign this method when we need to
// and use its existence to decide if the delete should show or not
$scope.deleteClick = function() {
if($attr.onDelete) {
// this item has an on-delete attribute
$scope.onDelete($scope.item);
} else if($parentAttrs.onDelete) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onDelete($scope.item);
}
};
// Set which icons to use for deleting
$scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled';
}
}
if($attr.onSelect || $parentAttrs.onSelect) {
// only assign this method when we need to
$scope.selectClick = function() {
if($attr.onSelect) {
// this item has an on-delete attribute
$scope.onSelect($scope.item);
} else if($parentAttrs.onSelect) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onSelect($scope.item);
}
};
}
// set the reorder Icon Class only if the item or list set can-reorder="true"
if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") {
$scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon';
}
// Set the option buttons which can be revealed by swiping to the left
// if canSwipe was set to false don't even bother
if(($attr.canSwipe ? $scope.canSwipe : $parentScope.canSwipe) !== "false") {
$scope.itemOptionButtons = $scope.optionButtons();
if(typeof $scope.itemOptionButtons === "undefined") {
$scope.itemOptionButtons = $parentScope.optionButtons();
}
}
}
};
}])
.directive('linkItem', [function() {
return {
restrict: 'E',
require: '?^list',
replace: true,
transclude: true,
scope: {
item: '=',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@',
href: '@'
},
template: '<a href="{{href}}" ng-click="onSelect()" class="item">\
<div class="item-edit" ng-if="canDelete && isEditing">\
<button class="button button-icon icon" ng-class="deleteIcon" ng-click="onDelete()"></button>\
template: '<a class="item item-complex" ng-class="itemClass" ng-href="{{ href }}" ng-click="onSelect()">\
<div class="item-edit" ng-if="deleteClick !== undefined">\
<button class="button button-icon icon" ng-class="deleteIconClass" ng-click="deleteClick()"></button>\
</div>\
<div class="item-content slide-left" ng-transclude>\
<div class="item-content" ng-transclude></div>\
<div class="item-drag" ng-if="reorderIconClass !== undefined">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIconClass"></button>\
</div>\
<div class="item-drag" ng-if="canReorder && isEditing">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIcon"></button>\
</div>\
<div class="item-options" ng-if="canSwipe && !isEditing && showOptions">\
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
<div class="item-options" ng-if="itemOptionButtons">\
<button ng-click="b.onClick(item, b)" class="button" ng-class="b.type" ng-repeat="b in itemOptionButtons" ng-bind="b.text"></button>\
</div>\
</a>',
link: function($scope, $element, $attr, list) {
// Grab the parent list controller
if(list[0]) {
list = list[0];
} else if(list[1]) {
list = list[1];
}
if(!list) return;
var $parentScope = list.scope;
var $parentAttrs = list.attrs;
$attr.$observe('href', function(value) {
$scope.href = value;
if(value) $scope.href = value.trim();
});
// Add the list item type class
$element.addClass($attr.type || 'item-complex');
// Set this item's class, first from the item directive attr, and then the list attr if item not set
$scope.itemClass = $scope.itemType || $parentScope.itemType;
if($attr.type !== 'item-complex') {
$scope.canSwipe = false;
// Decide if this item can do stuff, and follow a certain priority
// depending on where the value comes from
if(($attr.canDelete ? $scope.canDelete : $parentScope.canDelete) !== "false") {
if($attr.onDelete || $parentAttrs.onDelete) {
// only assign this method when we need to
// and use its existence to decide if the delete should show or not
$scope.deleteClick = function() {
if($attr.onDelete) {
// this item has an on-delete attribute
$scope.onDelete($scope.item);
} else if($parentAttrs.onDelete) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onDelete($scope.item);
}
};
// Set which icons to use for deleting
$scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled';
}
}
$scope.isEditing = false;
$scope.deleteIcon = list.scope.deleteIcon;
$scope.reorderIcon = list.scope.reorderIcon;
$scope.showOptions = true;
// set the reorder Icon Class only if the item or list set can-reorder="true"
if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") {
$scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon';
}
$scope.buttonClicked = function(button) {
button.onButtonClicked && button.onButtonClicked($scope.item, button);
};
var deregisterListWatch = list.scope.$watch('isEditing', function(v) {
$scope.isEditing = v;
// Add a delay before we allow the options layer to show, to avoid any odd
// animation issues
if(!v) {
$timeout(function() {
$scope.showOptions = true;
}, 200);
} else {
$scope.showOptions = false;
// Set the option buttons which can be revealed by swiping to the left
// if canSwipe was set to false don't even bother
if(($attr.canSwipe ? $scope.canSwipe : $parentScope.canSwipe) !== "false") {
$scope.itemOptionButtons = $scope.optionButtons();
if(typeof $scope.itemOptionButtons === "undefined") {
$scope.itemOptionButtons = $parentScope.optionButtons();
}
});
}
$scope.$on('$destroy', function () {
deregisterListWatch();
});
}
};
}])
.directive('item', ['$timeout', function($timeout) {
.directive('list', ['$timeout', function($timeout) {
return {
restrict: 'E',
require: ['?^list'],
replace: true,
transclude: true,
scope: {
item: '=',
onSelect: '&',
onDelete: '&',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
buttons: '=',
type: '@',
},
template: '<li ng-click="onSelect()" class="item">\
<div class="item-edit" ng-if="canDelete && isEditing">\
<button class="button button-icon icon" ng-class="deleteIcon" ng-click="onDelete()"></button>\
</div>\
<div class="item-content slide-left" ng-transclude>\
</div>\
<div class="item-drag" ng-if="canReorder && isEditing">\
<button data-ionic-action="reorder" class="button button-icon"><i ng-class="reorderIcon"></i></button>\
</div>\
<div class="item-options" ng-if="canSwipe && !isEditing && showOptions">\
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
</div>\
</li>',
link: function($scope, $element, $attr, list) {
// Grab the parent list controller
if(list[0]) {
list = list[0];
} else if(list[1]) {
list = list[1];
}
// Add the list item type class
$element.addClass($attr.type || 'item-complex');
if($attr.type !== 'item-complex') {
$scope.canSwipe = false;
}
$scope.isEditing = false;
$scope.deleteIcon = list.scope.deleteIcon;
$scope.reorderIcon = list.scope.reorderIcon;
$scope.showOptions = true;
$scope.buttonClicked = function(button) {
button.onButtonClicked && button.onButtonClicked($scope.item, button);
};
var deregisterListWatch = list.scope.$watch('isEditing', function(v) {
$scope.isEditing = v;
// Add a delay before we allow the options layer to show, to avoid any odd
// animation issues
if(!v) {
$timeout(function() {
$scope.showOptions = true;
}, 200);
} else {
$scope.showOptions = false;
}
});
$scope.$on('$destroy', function () {
deregisterListWatch();
});
}
};
}])
.directive('list', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
isEditing: '=',
deleteIcon: '@',
reorderIcon: '@',
showDelete: '=',
showReorder: '=',
hasPullToRefresh: '@',
onRefresh: '&',
onRefreshOpening: '&',
onReorder: '&',
refreshComplete: '='
refreshComplete: '=',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@'
},
controller: function($scope) {
var _this = this;
template: '<div class="list" ng-class="{\'list-editing\': showDelete, \'list-reordering\': showReorder}" ng-transclude></div>',
controller: function($scope, $attrs) {
this.scope = $scope;
$scope.$watch('isEditing', function(v) {
_this.isEditing = true;
});
this.attrs = $attrs;
},
template: '<ul class="list" ng-class="{\'list-editing\': isEditing}" ng-transclude>\
</ul>',
link: function($scope, $element, $attr) {
var lv = new ionic.views.ListView({
el: $element[0],
@@ -1000,7 +1031,6 @@ angular.module('ionic.ui.list', ['ngAnimate'])
$scope.$parent.$broadcast('scroll.onRefreshOpening', amt);
},
onReorder: function(el, oldIndex, newIndex) {
console.log('Moved', el,oldIndex,newIndex);
$scope.$apply(function() {
$scope.onReorder({el: el, start: oldIndex, end: newIndex});
});
@@ -1017,11 +1047,28 @@ angular.module('ionic.ui.list', ['ngAnimate'])
}
if($attr.animation) {
$element.addClass($attr.animation);
$element[0].classList.add($attr.animation);
}
var destroyShowReorderWatch = $scope.$watch('showReorder', function(val) {
if(val) {
$element[0].classList.add('item-options-hide');
} else if(val === false) {
// false checking is because it could be undefined
// if its undefined then we don't care to do anything
$timeout(function(){
$element[0].classList.remove('item-options-hide');
}, 250);
}
});
$scope.$on('$destroy', function () {
destroyShowReorderWatch();
});
}
};
});
}]);
})();
;

View File

@@ -3,191 +3,222 @@
angular.module('ionic.ui.list', ['ngAnimate'])
.directive('linkItem', ['$timeout', function($timeout) {
.directive('item', ['$timeout', function($timeout) {
return {
restrict: 'E',
require: ['?^list'],
require: '?^list',
replace: true,
transclude: true,
scope: {
item: '=',
onSelect: '&',
onDelete: '&',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
buttons: '=',
type: '@',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@'
},
template: '<div class="item item-complex" ng-class="itemClass" ng-click="selectClick()">\
<div class="item-edit" ng-if="deleteClick !== undefined">\
<button class="button button-icon icon" ng-class="deleteIconClass" ng-click="deleteClick()"></button>\
</div>\
<div class="item-content" ng-transclude></div>\
<div class="item-drag" ng-if="reorderIconClass !== undefined">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIconClass"></button>\
</div>\
<div class="item-options" ng-if="itemOptionButtons">\
<button ng-click="b.onClick(item, b)" class="button" ng-class="b.type" ng-repeat="b in itemOptionButtons" ng-bind="b.text"></button>\
</div>\
</div>',
link: function($scope, $element, $attr, list) {
if(!list) return;
var $parentScope = list.scope;
var $parentAttrs = list.attrs;
// Set this item's class, first from the item directive attr, and then the list attr if item not set
$scope.itemClass = $scope.itemType || $parentScope.itemType;
// Decide if this item can do stuff, and follow a certain priority
// depending on where the value comes from
if(($attr.canDelete ? $scope.canDelete : $parentScope.canDelete) !== "false") {
if($attr.onDelete || $parentAttrs.onDelete) {
// only assign this method when we need to
// and use its existence to decide if the delete should show or not
$scope.deleteClick = function() {
if($attr.onDelete) {
// this item has an on-delete attribute
$scope.onDelete($scope.item);
} else if($parentAttrs.onDelete) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onDelete($scope.item);
}
};
// Set which icons to use for deleting
$scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled';
}
}
if($attr.onSelect || $parentAttrs.onSelect) {
// only assign this method when we need to
$scope.selectClick = function() {
if($attr.onSelect) {
// this item has an on-delete attribute
$scope.onSelect($scope.item);
} else if($parentAttrs.onSelect) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onSelect($scope.item);
}
};
}
// set the reorder Icon Class only if the item or list set can-reorder="true"
if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") {
$scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon';
}
// Set the option buttons which can be revealed by swiping to the left
// if canSwipe was set to false don't even bother
if(($attr.canSwipe ? $scope.canSwipe : $parentScope.canSwipe) !== "false") {
$scope.itemOptionButtons = $scope.optionButtons();
if(typeof $scope.itemOptionButtons === "undefined") {
$scope.itemOptionButtons = $parentScope.optionButtons();
}
}
}
};
}])
.directive('linkItem', [function() {
return {
restrict: 'E',
require: '?^list',
replace: true,
transclude: true,
scope: {
item: '=',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@',
href: '@'
},
template: '<a href="{{href}}" ng-click="onSelect()" class="item">\
<div class="item-edit" ng-if="canDelete && isEditing">\
<button class="button button-icon icon" ng-class="deleteIcon" ng-click="onDelete()"></button>\
template: '<a class="item item-complex" ng-class="itemClass" ng-href="{{ href }}" ng-click="onSelect()">\
<div class="item-edit" ng-if="deleteClick !== undefined">\
<button class="button button-icon icon" ng-class="deleteIconClass" ng-click="deleteClick()"></button>\
</div>\
<div class="item-content slide-left" ng-transclude>\
<div class="item-content" ng-transclude></div>\
<div class="item-drag" ng-if="reorderIconClass !== undefined">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIconClass"></button>\
</div>\
<div class="item-drag" ng-if="canReorder && isEditing">\
<button data-ionic-action="reorder" class="button button-icon icon" ng-class="reorderIcon"></button>\
</div>\
<div class="item-options" ng-if="canSwipe && !isEditing && showOptions">\
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
<div class="item-options" ng-if="itemOptionButtons">\
<button ng-click="b.onClick(item, b)" class="button" ng-class="b.type" ng-repeat="b in itemOptionButtons" ng-bind="b.text"></button>\
</div>\
</a>',
link: function($scope, $element, $attr, list) {
// Grab the parent list controller
if(list[0]) {
list = list[0];
} else if(list[1]) {
list = list[1];
}
if(!list) return;
var $parentScope = list.scope;
var $parentAttrs = list.attrs;
$attr.$observe('href', function(value) {
$scope.href = value;
if(value) $scope.href = value.trim();
});
// Add the list item type class
$element.addClass($attr.type || 'item-complex');
// Set this item's class, first from the item directive attr, and then the list attr if item not set
$scope.itemClass = $scope.itemType || $parentScope.itemType;
if($attr.type !== 'item-complex') {
$scope.canSwipe = false;
// Decide if this item can do stuff, and follow a certain priority
// depending on where the value comes from
if(($attr.canDelete ? $scope.canDelete : $parentScope.canDelete) !== "false") {
if($attr.onDelete || $parentAttrs.onDelete) {
// only assign this method when we need to
// and use its existence to decide if the delete should show or not
$scope.deleteClick = function() {
if($attr.onDelete) {
// this item has an on-delete attribute
$scope.onDelete($scope.item);
} else if($parentAttrs.onDelete) {
// run the parent list's onDelete method
// if it doesn't exist nothing will happen
$parentScope.onDelete($scope.item);
}
};
// Set which icons to use for deleting
$scope.deleteIconClass = $scope.deleteIcon || $parentScope.deleteIcon || 'ion-minus-circled';
}
}
$scope.isEditing = false;
$scope.deleteIcon = list.scope.deleteIcon;
$scope.reorderIcon = list.scope.reorderIcon;
$scope.showOptions = true;
// set the reorder Icon Class only if the item or list set can-reorder="true"
if(($attr.canReorder ? $scope.canReorder : $parentScope.canReorder) === "true") {
$scope.reorderIconClass = $scope.reorderIcon || $parentScope.reorderIcon || 'ion-navicon';
}
$scope.buttonClicked = function(button) {
button.onButtonClicked && button.onButtonClicked($scope.item, button);
};
var deregisterListWatch = list.scope.$watch('isEditing', function(v) {
$scope.isEditing = v;
// Add a delay before we allow the options layer to show, to avoid any odd
// animation issues
if(!v) {
$timeout(function() {
$scope.showOptions = true;
}, 200);
} else {
$scope.showOptions = false;
// Set the option buttons which can be revealed by swiping to the left
// if canSwipe was set to false don't even bother
if(($attr.canSwipe ? $scope.canSwipe : $parentScope.canSwipe) !== "false") {
$scope.itemOptionButtons = $scope.optionButtons();
if(typeof $scope.itemOptionButtons === "undefined") {
$scope.itemOptionButtons = $parentScope.optionButtons();
}
});
}
$scope.$on('$destroy', function () {
deregisterListWatch();
});
}
};
}])
.directive('item', ['$timeout', function($timeout) {
.directive('list', ['$timeout', function($timeout) {
return {
restrict: 'E',
require: ['?^list'],
replace: true,
transclude: true,
scope: {
item: '=',
onSelect: '&',
onDelete: '&',
itemType: '@',
canDelete: '@',
canReorder: '@',
canSwipe: '@',
buttons: '=',
type: '@',
},
template: '<li ng-click="onSelect()" class="item">\
<div class="item-edit" ng-if="canDelete && isEditing">\
<button class="button button-icon icon" ng-class="deleteIcon" ng-click="onDelete()"></button>\
</div>\
<div class="item-content slide-left" ng-transclude>\
</div>\
<div class="item-drag" ng-if="canReorder && isEditing">\
<button data-ionic-action="reorder" class="button button-icon"><i ng-class="reorderIcon"></i></button>\
</div>\
<div class="item-options" ng-if="canSwipe && !isEditing && showOptions">\
<button ng-click="buttonClicked(button)" class="button" ng-class="button.type" ng-repeat="button in buttons">{{button.text}}</button>\
</div>\
</li>',
link: function($scope, $element, $attr, list) {
// Grab the parent list controller
if(list[0]) {
list = list[0];
} else if(list[1]) {
list = list[1];
}
// Add the list item type class
$element.addClass($attr.type || 'item-complex');
if($attr.type !== 'item-complex') {
$scope.canSwipe = false;
}
$scope.isEditing = false;
$scope.deleteIcon = list.scope.deleteIcon;
$scope.reorderIcon = list.scope.reorderIcon;
$scope.showOptions = true;
$scope.buttonClicked = function(button) {
button.onButtonClicked && button.onButtonClicked($scope.item, button);
};
var deregisterListWatch = list.scope.$watch('isEditing', function(v) {
$scope.isEditing = v;
// Add a delay before we allow the options layer to show, to avoid any odd
// animation issues
if(!v) {
$timeout(function() {
$scope.showOptions = true;
}, 200);
} else {
$scope.showOptions = false;
}
});
$scope.$on('$destroy', function () {
deregisterListWatch();
});
}
};
}])
.directive('list', function() {
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {
isEditing: '=',
deleteIcon: '@',
reorderIcon: '@',
showDelete: '=',
showReorder: '=',
hasPullToRefresh: '@',
onRefresh: '&',
onRefreshOpening: '&',
onReorder: '&',
refreshComplete: '='
refreshComplete: '=',
onSelect: '&',
onDelete: '&',
optionButtons: '&',
deleteIcon: '@',
reorderIcon: '@'
},
controller: function($scope) {
var _this = this;
template: '<div class="list" ng-class="{\'list-editing\': showDelete, \'list-reordering\': showReorder}" ng-transclude></div>',
controller: function($scope, $attrs) {
this.scope = $scope;
$scope.$watch('isEditing', function(v) {
_this.isEditing = true;
});
this.attrs = $attrs;
},
template: '<ul class="list" ng-class="{\'list-editing\': isEditing}" ng-transclude>\
</ul>',
link: function($scope, $element, $attr) {
var lv = new ionic.views.ListView({
el: $element[0],
@@ -202,7 +233,6 @@ angular.module('ionic.ui.list', ['ngAnimate'])
$scope.$parent.$broadcast('scroll.onRefreshOpening', amt);
},
onReorder: function(el, oldIndex, newIndex) {
console.log('Moved', el,oldIndex,newIndex);
$scope.$apply(function() {
$scope.onReorder({el: el, start: oldIndex, end: newIndex});
});
@@ -219,10 +249,27 @@ angular.module('ionic.ui.list', ['ngAnimate'])
}
if($attr.animation) {
$element.addClass($attr.animation);
$element[0].classList.add($attr.animation);
}
var destroyShowReorderWatch = $scope.$watch('showReorder', function(val) {
if(val) {
$element[0].classList.add('item-options-hide');
} else if(val === false) {
// false checking is because it could be undefined
// if its undefined then we don't care to do anything
$timeout(function(){
$element[0].classList.remove('item-options-hide');
}, 250);
}
});
$scope.$on('$destroy', function () {
destroyShowReorderWatch();
});
}
};
});
}]);
})();

View File

@@ -1,7 +1,7 @@
'use strict';
describe('Ionic List', function() {
var compile, scope;
var compile, scope, listElement, listCtrl;
beforeEach(module('ionic.ui.list'));
@@ -10,116 +10,390 @@ describe('Ionic List', function() {
scope = $rootScope;
}));
beforeEach(inject(function (_$compile_, _$rootScope_) {
scope.showDelete = false;
scope.showReorder = false;
listElement = angular.element('<list show-delete="showDelete" show-reorder="showReorder">');
listElement = _$compile_(listElement)(scope);
listCtrl = listElement.controller('list');
scope.$digest();
}));
it('Should init', function() {
var element = compile('<list>' +
'<list-item></list-item>' +
'<list-item></list-item>' +
'<item></item>' +
'<item></item>' +
'</list>')(scope);
expect(element.children().length).toBe(2);
});
});
describe('Ionic Link Item Directive', function () {
var $rootScope, element, listCtrl, options, scope;
it('Should add animation class', function() {
var element = compile('<list animation="my-animation">')(scope);
expect(element.hasClass('my-animation')).toBe(true);
});
beforeEach(module('ionic.ui.list'));
it('Should add list-editing class', function() {
expect(listElement.hasClass('list-editing')).toBe(false);
scope.showDelete = true;
scope.$digest();
expect(listElement.hasClass('list-editing')).toBe(true);
});
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$rootScope.isEditing = false;
it('Should add list-reordering class', function() {
expect(listElement.hasClass('list-reordering')).toBe(false);
scope.showReorder = true;
scope.$digest();
expect(listElement.hasClass('list-reordering')).toBe(true);
});
var list = angular.element('<list is-editing="isEditing">');
list = _$compile_(list)($rootScope);
listCtrl = list.controller('list');
$rootScope.buttons = [];
element = angular.element('<link-item>').appendTo(list);
element = _$compile_(element)($rootScope);
$rootScope.$digest();
scope = element.isolateScope();
}));
it('Should show options when the list is not in edit mode', inject(function ($timeout) {
scope.canSwipe = true;
$rootScope.$digest();
$timeout.flush();
expect(scope.isEditing).toBe(false);
expect(element.find('.item-options').length).toBe(1);
}));
it('Should hide options when the list is in edit mode', inject(function ($timeout) {
scope.canSwipe = true;
$rootScope.isEditing = true;
$rootScope.$digest();
$timeout.flush();
expect(scope.isEditing).toBe(true);
expect(element.find('.item-options').length).toBe(0);
}));
it('Should deregister watcher when scope destroyed', inject(function ($timeout) {
$rootScope.isEditing = true;
scope.$destroy();
$rootScope.$digest();
$timeout.flush();
expect(scope.isEditing).toBe(false);
}));
it('Should add item-options-hide class', function() {
expect(listElement.hasClass('item-options-hide')).toBe(false);
scope.showReorder = true;
scope.$digest();
expect(listElement.hasClass('item-options-hide')).toBe(true);
});
});
describe('Ionic Item Directive', function () {
var $rootScope, element, listCtrl, options, scope;
var $rootScope, $compile, listCtrl, options, listScope, itemScope, listElement, itemElement;
beforeEach(module('ionic.ui.list'));
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$rootScope.isEditing = false;
$compile = _$compile_;
$rootScope.showDelete = false;
var list = angular.element('<list is-editing="isEditing">');
list = _$compile_(list)($rootScope);
listElement = angular.element('<list show-delete="showDelete">');
listElement = _$compile_(listElement)($rootScope);
listScope = listElement.isolateScope();
listCtrl = list.controller('list');
listCtrl = listElement.controller('list');
$rootScope.buttons = [];
element = angular.element('<item>').appendTo(list);
element = _$compile_(element)($rootScope);
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = _$compile_(itemElement)($rootScope);
$rootScope.$digest();
scope = element.isolateScope();
itemScope = itemElement.isolateScope();
}));
it('Should show options when the list is not in edit mode', inject(function ($timeout) {
scope.canSwipe = true;
it('Should set item type from item attribute', inject(function ($timeout) {
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
$timeout.flush();
itemScope = itemElement.isolateScope();
expect(itemScope.itemClass).toBe(undefined);
expect(scope.isEditing).toBe(false);
expect(element.find('.item-options').length).toBe(1);
}));
it('Should hide options when the list is in edit mode', inject(function ($timeout) {
scope.canSwipe = true;
$rootScope.isEditing = true;
itemElement = angular.element('<item item-type="item-type-test">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
$timeout.flush();
expect(scope.isEditing).toBe(true);
expect(element.find('.item-options').length).toBe(0);
itemScope = itemElement.isolateScope();
expect(itemScope.itemClass).toBe("item-type-test");
expect(itemElement.hasClass('item-type-test')).toBe(true);
}));
it('Should deregister watcher when scope destroyed', inject(function ($timeout) {
$rootScope.isEditing = true;
scope.$destroy();
it('Should set item type from list attribute', inject(function ($timeout) {
listElement = angular.element('<list item-type="list-item-type-test">');
listElement = $compile(listElement)($rootScope);
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
$timeout.flush();
expect(scope.isEditing).toBe(false);
itemScope = itemElement.isolateScope();
expect(itemScope.itemClass).toBe('list-item-type-test');
expect(itemElement.hasClass('list-item-type-test')).toBe(true);
}));
it('Should item option buttons from item attribute', inject(function ($timeout) {
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.optionButtons()).toBe(undefined);
expect(itemScope.itemOptionButtons).toBe(undefined);
expect(itemElement.find('.item-options').length).toBe(0);
$rootScope.buttons = [
{ text: 'Edit' }, { text: 'Cancel' }
];
itemElement = angular.element('<item option-buttons="buttons">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.optionButtons().length).toBe(2);
expect(itemScope.itemOptionButtons.length).toBe(2);
expect(itemElement.find('.item-options').find('button').length).toBe(2);
}));
it('Should item option buttons from list attribute', inject(function ($timeout) {
$rootScope.buttons = [
{ text: 'Edit' }, { text: 'Cancel' }
];
listElement = angular.element('<list option-buttons="buttons">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
expect(listScope.optionButtons().length ).toBe(2);
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.optionButtons()).toBe(undefined);
expect(itemScope.itemOptionButtons.length).toBe(2);
expect(itemElement.find('.item-options').find('button').length).toBe(2);
}));
it('Should have no option buttons by disabling item canSwipe', inject(function ($timeout) {
$rootScope.buttons = [
{ text: 'Edit' }, { text: 'Cancel' }
];
itemElement = angular.element('<item can-swipe="false" option-buttons="buttons">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons).toBe(undefined);
}));
it('Should have no option buttons by disabling list canSwipe', inject(function ($timeout) {
$rootScope.buttons = [
{ text: 'Edit' }, { text: 'Cancel' }
];
listElement = angular.element('<list can-swipe="false" option-buttons="buttons">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
expect(listScope.optionButtons().length ).toBe(2);
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons).toBe(undefined);
}));
it('Should hide delete w/ item can-delete attribute true but no list or item onDelete', inject(function ($timeout) {
itemElement = angular.element('<item can-delete="true">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(0);
}));
it('Should hide delete w/ item can-delete attribute false but with item onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
itemElement = angular.element('<item can-delete="false" on-delete="onDelete">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(0);
}));
it('Should show delete w/ no item can-delete attribute but with item onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
itemElement = angular.element('<item on-delete="onDelete" delete-icon="test-icon">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).not.toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(1);
expect(itemScope.deleteIconClass).toBe("test-icon");
}));
it('Should hide delete w/ list can-delete attribute true but no list or item onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
listElement = angular.element('<list can-delete="true">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(0);
}));
it('Should hide delete w/ list can-delete attribute false but with list onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
listElement = angular.element('<list can-delete="false" on-delete="onDelete">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(0);
}));
it('Should hide delete w/ list can-delete attribute false but with item onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
listElement = angular.element('<list can-delete="false">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item on-delete="onDelete">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(0);
}));
it('Should show delete w/ no can-delete attribute but with list onDelete', inject(function ($timeout) {
$rootScope.onDelete = function() {};
listElement = angular.element('<list on-delete="onDelete" delete-icon="test-icon">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.deleteClick).not.toBe(undefined);
expect(itemElement.find('.item-edit').length).toBe(1);
expect(itemScope.deleteIconClass).toBe("test-icon");
}));
it('Should not be able to reorder cuz no item or list can-reorder attribute true', inject(function ($timeout) {
itemElement = angular.element('<item reorder-icon="test-icon">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.reorderIconClass).toBe(undefined);
expect(itemElement.find('.item-drag').length).toBe(0);
}));
it('Should be able to reorder cuz item can-reorder attribute true', inject(function ($timeout) {
itemElement = angular.element('<item can-reorder="true" reorder-icon="test-icon">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.reorderIconClass).toBe('test-icon');
expect(itemElement.find('.item-drag').length).toBe(1);
}));
it('Should be able to reorder cuz list can-reorder attribute true', inject(function ($timeout) {
listElement = angular.element('<list can-reorder="true" reorder-icon="test-icon">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.reorderIconClass).toBe('test-icon');
expect(itemElement.find('.item-drag').length).toBe(1);
}));
it('Should not have options cuz no optionButtons', inject(function ($timeout) {
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons).toBe(undefined);
expect(itemElement.find('.item-options').length).toBe(0);
}));
it('Should be able to reorder cuz list can-reorder attribute false and item can-reorder true', inject(function ($timeout) {
listElement = angular.element('<list can-reorder="false">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item can-reorder="true">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.reorderIconClass).toBe('ion-navicon');
expect(itemElement.find('.item-drag').length).toBe(1);
}));
it('Should not have options cuz item can-swipe false', inject(function ($timeout) {
$rootScope.optionButtons = [{text:'BUTTON'}];
itemElement = angular.element('<item option-buttons="optionButtons" can-swipe="false">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons).toBe(undefined);
expect(itemElement.find('.item-options').length).toBe(0);
}));
it('Should not have options cuz list can-swipe false', inject(function ($timeout) {
$rootScope.optionButtons = [{text:'BUTTON'}];
listElement = angular.element('<list option-buttons="optionButtons" can-swipe="false">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons).toBe(undefined);
expect(itemElement.find('.item-options').length).toBe(0);
}));
it('Should have options cuz item option-buttons and no can-swipe false', inject(function ($timeout) {
$rootScope.optionButtons = [{text:'BUTTON'}];
itemElement = angular.element('<item option-buttons="optionButtons">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons.length).toBe(1);
expect(itemElement.find('.item-options').find('button').length).toBe(1);
}));
it('Should have options cuz list option-buttons and no can-swipe false', inject(function ($timeout) {
$rootScope.optionButtons = [{text:'BUTTON'}];
listElement = angular.element('<list option-buttons="optionButtons">');
listElement = $compile(listElement)($rootScope);
listScope = listElement.isolateScope();
itemElement = angular.element('<item>').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.itemOptionButtons.length).toBe(1);
expect(itemElement.find('.item-options').find('button').length).toBe(1);
}));
});
describe('Ionic Link Item Directive', function () {
var $rootScope, $compile, listCtrl, options, listScope, itemScope, listElement, itemElement;
beforeEach(module('ionic.ui.list'));
beforeEach(inject(function (_$compile_, _$rootScope_) {
$rootScope = _$rootScope_;
$compile = _$compile_;
listElement = angular.element('<list>');
listElement = _$compile_(listElement)($rootScope);
listScope = listElement.isolateScope();
listCtrl = listElement.controller('list');
itemElement = angular.element('<link-item>').appendTo(listElement);
itemElement = _$compile_(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
}));
it('Should set link-item href', inject(function ($timeout) {
itemElement = angular.element('<link-item href="http://drifty.com/">').appendTo(listElement);
itemElement = $compile(itemElement)($rootScope);
$rootScope.$digest();
itemScope = itemElement.isolateScope();
expect(itemScope.href).toBe("http://drifty.com/");
expect(itemElement.attr('href')).toBe("http://drifty.com/");
}));
});

View File

@@ -7,86 +7,128 @@
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
<style>
.my-repeat-animation > .ng-enter,
.my-repeat-animation > .ng-leave,
.my-repeat-animation > .ng-move {
-webkit-transition: 0.2s linear all;
transition: 0.2s linear all;
position:relative;
}
.my-repeat-animation > .ng-enter,
.my-repeat-animation > .ng-leave,
.my-repeat-animation > .ng-move {
-webkit-transition: 0.2s linear all;
transition: 0.2s linear all;
position:relative;
}
.my-repeat-animation > .ng-enter {
left:-10px;
opacity:0;
z-index: 10;
}
.my-repeat-animation > .ng-enter.ng-enter-active {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-enter {
left:-10px;
opacity:0;
z-index: 10;
}
.my-repeat-animation > .ng-enter.ng-enter-active {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-leave {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-leave.ng-leave-active {
left:-10px;
opacity:0;
}
.my-repeat-animation > .ng-leave {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-leave.ng-leave-active {
left:-10px;
opacity:0;
}
.my-repeat-animation > .ng-move {
opacity:0.5;
}
.my-repeat-animation > .ng-move.ng-move-active {
opacity:1;
}
.spinner {
width: 40px;
height: 40px;
border: 2px solid rgba(255,255,255,0.4);
border-radius: 40px;
margin: auto;
margin-bottom: 100px;
}
.spin-thing {
width: 10px;
height: 10px;
background-color: #4a87ee;
border-radius: 10px;
}
.my-repeat-animation > .ng-move {
opacity:0.5;
}
.my-repeat-animation > .ng-move.ng-move-active {
opacity:1;
}
</style>
</head>
<body>
<body ng-controller="TestCtrl">
<pane>
<div ng-controller="TestCtrl">
<content on-refresh="refreshProjects()"
refresh-complete="refreshComplete">
<list is-editing="isEditingItems"
animation="my-repeat-animation"
delete-icon="icon ion-minus-circled"
reorder-icon="icon ion-navicon">
<refresher></refresher>
<header class="bar bar-header bar-positive">
<div class="buttons">
<button ng-click="toggleDelete()" class="button button-clear">{{ editBtnText }}</button>
</div>
<h1 class="title">List Tests</h1>
<div class="buttons">
<button ng-click="toggleReorder()" class="button button-clear">{{ reorderBtnText }}</button>
</div>
</header>
<item
ng-repeat="item in items"
buttons="item.buttons"
<content has-header="true">
<list show-delete="isDeletingItems"
show-reorder="isReorderingItems"
on-refresh-holding="refreshHolding()"
on-refresh-opening="refreshOpening(ratio)"
on-refresh="refreshItems()"
refresh-complete="refreshComplete"
on-delete="deleteListItem()"
delete-icon="ion-minus-circled"
reorder-icon="ion-navicon"
animation="my-repeat-animation"
can-delete="true"
can-reorder="true"
can-swipe="true"
option-buttons="optionButtons1"
item-type="item-icon-left">
<!-- shows that the item directive does not need attributes and can get values from the list attributes -->
<item ng-repeat="item in items"
item="item">
<i class="icon ion-chatbox"></i>
Repeat Item: {{ item.text }}
</item>
<!-- shows how a divider could be included-->
<div class="item item-divider">
Me Divider, just plain ol' HTML nested in the list directive.
</div>
<!-- shows it can override the attributes set by the list -->
<item can-delete="false"
can-reorder="false"
can-swipe="false"
item-type="item-icon-left item-icon-right">
<i class="icon ion-stats-bars"></i>
Individual item directive, but can't do much. Overrides list attributes with its own left and right icons.
<i class="icon ion-arrow-graph-up-right"></i>
</item>
<!-- shows that the item directive can receive many attributes and overrides the list attributes -->
<item on-delete="deleteItem()"
delete-icon="ion-trash-a"
reorder-icon="ion-navicon-round"
can-delete="true"
can-reorder="true"
can-swipe="true"
on-delete="deleteProject(item)"
on-select="selectProject(item)">
<i class="icon ion-email ion-primary"></i>
{{item.text}}
<i class="{{item.icon}}"></i>
</item>
</list>
<button ng-click="edit()" class="button button-success">Edit</button>
</content>
</div>
option-buttons="optionButtons2">
<i class="icon ion-person-stalker"></i>
Individual item directive and overrides list attrs with item attributes
</item>
<!-- shows how a divider could be included-->
<div class="item item-divider">
Below is NOT using the item directive, but just nested HTML
</div>
<!-- shows how very simple lists don't need the item directive at all -->
<div class="item item-thumbnail-left">
<img src="http://pbs.twimg.com/profile_images/2913427048/ed94193baa04ace85aa8a8bf4bf6c5a9.jpeg">
<h2>Nic Cage</h2>
<p>I am not a demon. I am a lizard, a shark, a heat-seeking panther. I want to be Bob Denver on acid playing the accordion.</p>
</div>
<a class="item item-icon-left" href="{{ item.url }}" ng-repeat="item in urlItems">
<i class="icon {{ item.icon }}"></i>
{{ item.text }}
</a>
</list>
</content>
</pane>
<script src="../../../../dist/js/ionic.js"></script>
@@ -97,58 +139,70 @@
<script src="../../../../dist/js/angular/angular-sanitize.js"></script>
<script src="../../../../dist/js/ionic-angular.js"></script>
<script>
angular.module('navTest', ['ionic.ui.list', 'ionic.ui.content', 'ngAnimate'])
angular.module('navTest', ['ionic.ui.list', 'ionic.ui.content'])
.controller('TestCtrl', function($scope, $timeout) {
$scope.refreshRatio = { ratio: 0 };
var removeItem = function(item) {
// Remove ourselves
$scope.items.splice($scope.items.indexOf(item), 1);
};
$scope.selectProject = function(project) {
console.log('Selected project', project);
};
$scope.almostRefreshing = function() {
console.log('HOLDING FOR REFRESH');
};
$scope.almostRefreshProjects = function(amt) {
console.log('ALMOST REFRESHING', amt);
$scope.refreshRatio.ratio = amt;
$scope.$apply();
};
$scope.refreshProjects = function() {
console.log("REFRESHING");
$timeout(function() {
$scope.$broadcast('scroll.refreshComplete');
}, 2000);
};
// Build Mock Data
$scope.items = [];
for(var i = 0; i < 20; i++) {
for(var i = 0; i < 3; i++) {
$scope.items.push({
text: 'Item ' + i,
canDelete: true,
canSwipe: true,
canReorder: true,
icon: 'icon-chevron-right',
hide: false,
deleteItem: removeItem,
buttons: [{
text: 'Kill',
type: 'button-danger',
buttonClicked: removeItem,
}]
text: i
});
}
$scope.edit = function() {
$scope.isEditingItems = !$scope.isEditingItems;
}
});
// List Toggles
$scope.editBtnText = 'Edit';
$scope.toggleDelete = function() {
$scope.isDeletingItems = !$scope.isDeletingItems;
$scope.isReorderingItems = false;
$scope.editBtnText = ($scope.isDeletingItems ? 'Done' : 'Edit');
};
$scope.reorderBtnText = 'Reorder';
$scope.toggleReorder = function() {
$scope.isReorderingItems = !$scope.isReorderingItems;
$scope.isDeletingItems = false;
$scope.reorderBtnText = ($scope.isReorderingItems ? 'Done' : 'Reorder');
};
// Item Methods/Properties
$scope.deleteItem = function(item) {
alert('onDelete from the "item" directive on-delete attribute. Lets not delete this item today ok!');
};
$scope.deleteListItem = function(item) {
alert('onDelete from the "list" on-delete attribute');
$scope.items.splice($scope.items.indexOf(item), 1);
};
$scope.optionButtons1 = [
{
text: 'Edit',
onClick: function(item, button) { alert(button.text + ' Button: ' + item.text) }
},
{
text: 'Share',
onClick: function(item, button) { alert(button.text + ' Button: ' + item.text) }
}
];
$scope.optionButtons2 = [
{
text: 'Cancel',
onClick: function() { alert('CANCEL!') }
},
{
text: 'Submit',
onClick: function() { alert('SUBMIT!') }
}
];
$scope.urlItems = [
{ text: 'Biography', icon: 'ion-person', url: 'http://en.wikipedia.org/wiki/Nicolas_Cage' },
{ text: 'Fan Club', icon: 'ion-star', url: 'http://cagealot.com/' }
];
});
</script>
</body>
</html>

View File

@@ -0,0 +1,134 @@
<html ng-app="navTest">
<head>
<meta charset="utf-8">
<title>Pull To Refresh</title>
<!-- Sets initial viewport load and disables zooming -->
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" href="../../../../dist/css/ionic.css">
<style>
.my-repeat-animation > .ng-enter,
.my-repeat-animation > .ng-leave,
.my-repeat-animation > .ng-move {
-webkit-transition: 0.2s linear all;
transition: 0.2s linear all;
position:relative;
}
.my-repeat-animation > .ng-enter {
left:-10px;
opacity:0;
z-index: 10;
}
.my-repeat-animation > .ng-enter.ng-enter-active {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-leave {
left:0;
opacity:1;
}
.my-repeat-animation > .ng-leave.ng-leave-active {
left:-10px;
opacity:0;
}
.my-repeat-animation > .ng-move {
opacity:0.5;
}
.my-repeat-animation > .ng-move.ng-move-active {
opacity:1;
}
</style>
</head>
<body ng-controller="TestCtrl">
<pane>
<header class="bar bar-header bar-positive">
<div class="buttons">
<button ng-click="toggleDelete()" class="button button-clear">{{ editBtnText }}</button>
</div>
<h1 class="title">Pull To Refresh</h1>
</header>
<content has-header="true"
on-refresh-holding="refreshHolding()"
on-refresh-opening="refreshOpening(ratio)"
on-refresh="refreshItems()"
refresh-complete="refreshComplete">
<list show-delete="isDeletingItems" animation="my-repeat-animation">
<refresher></refresher>
<item ng-repeat="item in items"
item="item"
on-delete="deleteListItem(item)">
Item: {{ item.text }}
</item>
</list>
</content>
</pane>
<script src="../../../../dist/js/ionic.js"></script>
<script src="../../../../dist/js/angular/angular.js"></script>
<script src="../../../../dist/js/angular/angular-animate.js"></script>
<script src="../../../../dist/js/angular/angular-route.js"></script>
<script src="../../../../dist/js/angular/angular-touch.js"></script>
<script src="../../../../dist/js/angular/angular-sanitize.js"></script>
<script src="../../../../dist/js/ionic-angular.js"></script>
<script>
angular.module('navTest', ['ionic.ui.list', 'ionic.ui.content'])
.controller('TestCtrl', function($scope, $timeout) {
// Build Mock Data
function buildMockData() {
$scope.items = [];
for(var i = 0; i < 20; i++) {
$scope.items.push({
text: i
});
}
}
buildMockData();
// List Methods/Properties
$scope.refreshHolding = function() {
console.log('HOLDING FOR REFRESH');
};
$scope.refreshOpening = function(amt) {
console.log('REFRESH OPENING', amt);
$scope.refreshRatio.ratio = amt;
$scope.$apply();
};
$scope.refreshItems = function() {
console.log("REFRESHING");
$timeout(function() {
buildMockData();
$scope.refreshComplete();
}, 1500);
};
$scope.refreshRatio = { ratio: 0 };
$scope.editBtnText = 'Edit';
$scope.toggleDelete = function() {
$scope.isDeletingItems = !$scope.isDeletingItems;
$scope.editBtnText = ($scope.isDeletingItems ? 'Done' : 'Edit');
};
$scope.deleteListItem = function(item) {
$scope.items.splice($scope.items.indexOf(item), 1);
};
});
</script>
</body>
</html>

View File

@@ -148,7 +148,6 @@
min-width: initial;
border-color: transparent;
background: none;
background: none;
&.button:active, &.button.active {
border-color: transparent;

View File

@@ -496,7 +496,7 @@ button.item-button-right:after {
}
// Item Animations
// Item Editing
// -------------------------------
.item-sliding {
@@ -512,12 +512,12 @@ button.item-button-right:after {
opacity: 0.7;
}
/**
* The left-side edit area of a complex list item. This area shows
* whe the list item is in edit mode.
*/
.item-edit {
@include transition(left 0.2s ease-in-out, opacity 0.2s ease-in-out);
position: absolute;
top: 0;
@@ -529,11 +529,13 @@ button.item-button-right:after {
.button {
height: 100%;
.icon, i {
&.icon {
@include display-flex();
@include align-items(center);
position: absolute;
top: 0;
left: 0;
height: 100%;
color: $assertive;
font-size: 24px;
@@ -564,20 +566,22 @@ button.item-button-right:after {
position: absolute;
top: 0;
right: 0;
z-index: $z-index-item-drag;
z-index: 0;
width: 50px;
height: 100%;
background: inherit;
.button {
height: 100%;
border: none;
border-radius: 0;
.icon, i {
min-width: 42px;
&.icon:before {
@include display-flex();
@include align-items(center);
position: absolute;
top: 0;
height: 100%;
font-size: 24px;
font-size: 32px;
}
}
}
@@ -598,3 +602,7 @@ button.item-button-right:after {
border-radius: 0;
}
}
.item-options-hide .item-options {
display: none;
}

View File

@@ -14,14 +14,21 @@
/**
* List editing styles. These trigger when the entire list goes into
* "edit mode"
* "edit mode" or reordering list items
*/
.list-editing {
.item-content {
margin-right: 50px;
margin-left: 50px;
}
}
.list-reordering {
.item-content {
margin-right: 50px;
}
.item-drag {
z-index: 1;
}
}
/**