Erste lauffähige Version
This commit is contained in:
54
www/lib/ionic-filter-bar/.bower.json
Normal file
54
www/lib/ionic-filter-bar/.bower.json
Normal file
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"name": "ionic-filter-bar",
|
||||
"version": "1.1.1",
|
||||
"description": "A filter directive UI for Ionic apps that animates over the header bar",
|
||||
"author": "Devin Jett <djett41@gmail.com> (https://github.com/djett41)",
|
||||
"main": [
|
||||
"dist/ionic.filter.bar.css",
|
||||
"dist/ionic.filter.bar.js"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/djett41/ionic-filter-bar.git"
|
||||
},
|
||||
"ignore": [
|
||||
"demo",
|
||||
"js",
|
||||
"test",
|
||||
".gitignore",
|
||||
"gulpfile.js",
|
||||
"karma.conf.js",
|
||||
"LICENSE",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"ionic": "^1.0.0-rc.0",
|
||||
"angular-mocks": "1.4.3"
|
||||
},
|
||||
"keywords": [
|
||||
"mobile",
|
||||
"html5",
|
||||
"ionic",
|
||||
"cordova",
|
||||
"phonegap",
|
||||
"search",
|
||||
"filter",
|
||||
"angularjs",
|
||||
"angular"
|
||||
],
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"homepage": "https://github.com/djett41/ionic-filter-bar",
|
||||
"_release": "1.1.1",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v1.1.1",
|
||||
"commit": "0a0a9f310a911815b45161800b276a9404142825"
|
||||
},
|
||||
"_source": "https://github.com/djett41/ionic-filter-bar.git",
|
||||
"_target": "^1.1.1",
|
||||
"_originalSource": "ionic-filter-bar",
|
||||
"_direct": true
|
||||
}
|
||||
43
www/lib/ionic-filter-bar/bower.json
Normal file
43
www/lib/ionic-filter-bar/bower.json
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "ionic-filter-bar",
|
||||
"version": "1.1.1",
|
||||
"description": "A filter directive UI for Ionic apps that animates over the header bar",
|
||||
"author": "Devin Jett <djett41@gmail.com> (https://github.com/djett41)",
|
||||
"main": [
|
||||
"dist/ionic.filter.bar.css",
|
||||
"dist/ionic.filter.bar.js"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/djett41/ionic-filter-bar.git"
|
||||
},
|
||||
"ignore": [
|
||||
"demo",
|
||||
"js",
|
||||
"test",
|
||||
".gitignore",
|
||||
"gulpfile.js",
|
||||
"karma.conf.js",
|
||||
"LICENSE",
|
||||
"package.json",
|
||||
"README.md"
|
||||
],
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"ionic": "^1.0.0-rc.0",
|
||||
"angular-mocks": "1.4.3"
|
||||
},
|
||||
"keywords": [
|
||||
"mobile",
|
||||
"html5",
|
||||
"ionic",
|
||||
"cordova",
|
||||
"phonegap",
|
||||
"search",
|
||||
"filter",
|
||||
"angularjs",
|
||||
"angular"
|
||||
],
|
||||
"license": "MIT",
|
||||
"private": false
|
||||
}
|
||||
224
www/lib/ionic-filter-bar/dist/ionic.filter.bar.css
vendored
Normal file
224
www/lib/ionic-filter-bar/dist/ionic.filter.bar.css
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
.filter-bar-backdrop {
|
||||
-webkit-transition: opacity 150ms ease-in-out;
|
||||
transition: opacity 150ms ease-in-out;
|
||||
opacity: 0;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%; }
|
||||
.filter-bar-backdrop.active {
|
||||
z-index: 10;
|
||||
opacity: 1; }
|
||||
|
||||
.filter-bar {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 44px;
|
||||
z-index: 10; }
|
||||
.filter-bar .filter-bar-wrapper {
|
||||
z-index: 11;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%; }
|
||||
.filter-bar .filter-bar-wrapper .item-input-inset .icon.placeholder-icon:before {
|
||||
padding-top: 3px;
|
||||
font-size: 16px; }
|
||||
.filter-bar .filter-bar-wrapper .item-input-inset .item-input-wrapper {
|
||||
background: #fff;
|
||||
height: 28px; }
|
||||
.filter-bar .filter-bar-wrapper .item-input-inset .item-input-wrapper .filter-bar-clear {
|
||||
padding: 0 2px 0 0; }
|
||||
.filter-bar .filter-bar-wrapper .item-input-inset .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #aaa;
|
||||
font-size: 18px;
|
||||
padding-top: 1px; }
|
||||
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper {
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: white; }
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper input[type="search"] {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-light .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper {
|
||||
border-bottom: 1px solid #a2a2a2;
|
||||
background: #f8f8f8; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper input[type="search"] {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-stable .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper {
|
||||
border-bottom: 1px solid #0c60ee;
|
||||
background: #387ef5; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-positive .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper {
|
||||
border-bottom: 1px solid #0a9dc7;
|
||||
background: #11c1f3; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-calm .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper {
|
||||
border-bottom: 1px solid #e42112;
|
||||
background: #ef473a; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-assertive .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper {
|
||||
border-bottom: 1px solid #28a54c;
|
||||
background: #33cd5f; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-balanced .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper {
|
||||
border-bottom: 1px solid #e6b500;
|
||||
background: #ffc900; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-energized .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper {
|
||||
border-bottom: 1px solid #6b46e5;
|
||||
background: #886aea; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-royal .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper {
|
||||
border-bottom: 1px solid #000;
|
||||
background: #444444; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper input[type="search"] {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: white; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: white;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-dark .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #fff; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper {
|
||||
border-bottom: 1px solid #ccc;
|
||||
background: white; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper input[type="search"] {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper input[type="search"]::-moz-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper input[type="search"]:-ms-input-placeholder {
|
||||
color: #aaaaaa; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper input[type="search"]::-webkit-input-placeholder {
|
||||
color: #aaaaaa;
|
||||
text-indent: 0; }
|
||||
.platform-android .filter-bar .filter-bar-default .item-input-wrapper .filter-bar-clear:before {
|
||||
color: #444; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset {
|
||||
padding-right: 24px; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset .filter-bar-cancel {
|
||||
padding-left: 0; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset .filter-bar-cancel:before {
|
||||
font-size: 24px; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset .item-input-wrapper {
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
margin-left: 10px; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset .item-input-wrapper input[type="search"] {
|
||||
font-weight: 500; }
|
||||
.platform-android .filter-bar-wrapper .item-input-inset .item-input-wrapper .filter-bar-clear:before {
|
||||
font-size: 20px; }
|
||||
|
||||
.filter-bar-transition-horizontal {
|
||||
-webkit-transition: -webkit-transform cubic-bezier(.25, .45, .05, 1) 300ms;
|
||||
transition: transform cubic-bezier(.25, .45, .05, 1) 300ms;
|
||||
-webkit-transform: translate3d(100%, 0, 0);
|
||||
transform: translate3d(100%, 0, 0); }
|
||||
|
||||
.filter-bar-transition-vertical {
|
||||
-webkit-transition: -webkit-transform cubic-bezier(.25, .45, .05, 1) 350ms;
|
||||
transition: transform cubic-bezier(.25, .45, .05, 1) 350ms;
|
||||
-webkit-transform: translate3d(0, -100%, 0);
|
||||
transform: translate3d(0, -100%, 0); }
|
||||
|
||||
.filter-bar-transition-fade {
|
||||
-webkit-transition: opacity 250ms ease-in-out;
|
||||
transition: opacity 250ms ease-in-out;
|
||||
opacity: 0; }
|
||||
|
||||
.filter-bar-in {
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
opacity: 1; }
|
||||
|
||||
.filter-bar-modal .item.item-input {
|
||||
padding-right: 16px; }
|
||||
.filter-bar-modal .list-right-editing .item.item-input {
|
||||
opacity: .5; }
|
||||
.filter-bar-modal .button.button-icon.ion-ios-checkmark-empty:before {
|
||||
font-size: 42px; }
|
||||
|
||||
.filter-bar-element-hide {
|
||||
display: none; }
|
||||
721
www/lib/ionic-filter-bar/dist/ionic.filter.bar.js
vendored
Normal file
721
www/lib/ionic-filter-bar/dist/ionic.filter.bar.js
vendored
Normal file
@@ -0,0 +1,721 @@
|
||||
angular.module('jett.ionic.filter.bar', ['ionic']);
|
||||
(function (angular, document) {
|
||||
'use strict';
|
||||
|
||||
angular.module('jett.ionic.filter.bar')
|
||||
.directive('ionFilterBar', [
|
||||
'$timeout',
|
||||
'$ionicGesture',
|
||||
'$ionicPlatform',
|
||||
function ($timeout, $ionicGesture, $ionicPlatform) {
|
||||
var filterBarTemplate;
|
||||
|
||||
//create platform specific filterBar template using filterConfig items
|
||||
if ($ionicPlatform.is('android')) {
|
||||
filterBarTemplate =
|
||||
'<div class="filter-bar-wrapper filter-bar-{{::config.theme}} filter-bar-transition-{{::config.transition}}">' +
|
||||
'<div class="bar bar-header bar-{{::config.theme}} item-input-inset">' +
|
||||
'<button class="filter-bar-cancel button button-icon icon {{::config.back}}"></button>' +
|
||||
'<label class="item-input-wrapper">' +
|
||||
'<input type="search" class="filter-bar-search" ng-model="data.filterText" placeholder="{{::config.placeholder}}" />' +
|
||||
'<button class="filter-bar-clear button button-icon icon" ng-class="getClearButtonClass()"></button>' +
|
||||
'</label>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
} else {
|
||||
filterBarTemplate =
|
||||
'<div class="filter-bar-wrapper filter-bar-{{::config.theme}} filter-bar-transition-{{::config.transition}}">' +
|
||||
'<div class="bar bar-header bar-{{::config.theme}} item-input-inset">' +
|
||||
'<label class="item-input-wrapper">' +
|
||||
'<i class="icon {{::config.search}} placeholder-icon"></i>' +
|
||||
'<input type="search" class="filter-bar-search" ng-model="data.filterText" placeholder="{{::config.placeholder}}"/>' +
|
||||
'<button class="filter-bar-clear button button-icon icon" ng-class="getClearButtonClass()"></button>' +
|
||||
'</label>' +
|
||||
'<button class="filter-bar-cancel button button-clear" ng-bind-html="::cancelText"></button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: true,
|
||||
link: function ($scope, $element) {
|
||||
var el = $element[0];
|
||||
var clearEl = el.querySelector('.filter-bar-clear');
|
||||
var cancelEl = el.querySelector('.filter-bar-cancel');
|
||||
var inputEl = el.querySelector('.filter-bar-search');
|
||||
var filterTextTimeout;
|
||||
var swipeGesture;
|
||||
var backdrop;
|
||||
var backdropClick;
|
||||
var filterWatch;
|
||||
|
||||
// Action when filter bar is cancelled via backdrop click/swipe or cancel/back buton click.
|
||||
// Invokes cancel function defined in filterBar service
|
||||
var cancelFilterBar = function () {
|
||||
$scope.cancelFilterBar();
|
||||
};
|
||||
|
||||
// If backdrop is enabled, create and append it to filter, then add click/swipe listeners to cancel filter
|
||||
if ($scope.config.backdrop) {
|
||||
backdrop = angular.element('<div class="filter-bar-backdrop"></div>');
|
||||
$element.append(backdrop);
|
||||
|
||||
backdropClick = function(e) {
|
||||
if (e.target == backdrop[0]) {
|
||||
cancelFilterBar();
|
||||
}
|
||||
};
|
||||
|
||||
backdrop.bind('click', backdropClick);
|
||||
swipeGesture = $ionicGesture.on('swipe', backdropClick, backdrop);
|
||||
}
|
||||
|
||||
//Sure we could have had 1 function that also checked for favoritesEnabled.. but no need to keep checking a var that wont change
|
||||
if ($scope.favoritesEnabled) {
|
||||
$scope.getClearButtonClass = function () {
|
||||
return $scope.data.filterText.length ? $scope.config.clear : $scope.config.favorite;
|
||||
}
|
||||
} else {
|
||||
$scope.getClearButtonClass = function () {
|
||||
return $scope.data.filterText.length ? $scope.config.clear : 'filter-bar-element-hide';
|
||||
}
|
||||
}
|
||||
|
||||
// When clear button is clicked, clear filterText, hide clear button, show backdrop, and focus the input
|
||||
var clearClick = function () {
|
||||
if (clearEl.classList.contains($scope.config.favorite)) {
|
||||
$scope.showModal();
|
||||
} else {
|
||||
$timeout(function () {
|
||||
$scope.data.filterText = '';
|
||||
ionic.requestAnimationFrame(function () {
|
||||
$scope.showBackdrop();
|
||||
$scope.scrollItemsTop();
|
||||
$scope.focusInput();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Bind touchstart so we can regain focus of input even while scrolling
|
||||
var inputClick = function () {
|
||||
$scope.scrollItemsTop();
|
||||
$scope.focusInput();
|
||||
};
|
||||
|
||||
// When a non escape key is pressed, show/hide backdrop/clear button based on filterText length
|
||||
var keyUp = function(e) {
|
||||
if (e.which == 27) {
|
||||
cancelFilterBar();
|
||||
} else if ($scope.data.filterText && $scope.data.filterText.length) {
|
||||
$scope.hideBackdrop();
|
||||
} else {
|
||||
$scope.showBackdrop();
|
||||
}
|
||||
};
|
||||
|
||||
//Event Listeners
|
||||
cancelEl.addEventListener('click', cancelFilterBar);
|
||||
// Since we are wrapping with label, need to bind touchstart rather than click.
|
||||
// Even if we use div instead of label need to bind touchstart. Click isn't allowing input to regain focus quickly
|
||||
clearEl.addEventListener('touchstart', clearClick);
|
||||
clearEl.addEventListener('mousedown', clearClick);
|
||||
|
||||
inputEl.addEventListener('touchstart', inputClick);
|
||||
inputEl.addEventListener('mousedown', inputClick);
|
||||
|
||||
document.addEventListener('keyup', keyUp);
|
||||
|
||||
// Calls the services filterItems function with the filterText to filter items
|
||||
var filterItems = function () {
|
||||
$scope.filterItems($scope.data.filterText);
|
||||
};
|
||||
|
||||
// Clean up when scope is destroyed
|
||||
$scope.$on('$destroy', function() {
|
||||
$element.remove();
|
||||
document.removeEventListener('keyup', keyUp);
|
||||
if (backdrop) {
|
||||
$ionicGesture.off(swipeGesture, 'swipe', backdropClick);
|
||||
}
|
||||
filterWatch();
|
||||
});
|
||||
|
||||
// Watch for changes on filterText and call filterItems when filterText has changed.
|
||||
// If debounce is enabled, filter items by the specified or default delay.
|
||||
// Prefer timeout debounce over ng-model-options so if filterText is cleared, initial items show up right away with no delay
|
||||
filterWatch = $scope.$watch('data.filterText', function (newFilterText, oldFilterText) {
|
||||
var delay;
|
||||
|
||||
if (filterTextTimeout) {
|
||||
$timeout.cancel(filterTextTimeout);
|
||||
}
|
||||
|
||||
if (newFilterText !== oldFilterText) {
|
||||
delay = (newFilterText.length && $scope.debounce) ? $scope.delay : 0;
|
||||
filterTextTimeout = $timeout(filterItems, delay, false);
|
||||
}
|
||||
});
|
||||
},
|
||||
template: filterBarTemplate
|
||||
};
|
||||
}]);
|
||||
|
||||
})(angular, document);
|
||||
|
||||
/* global angular */
|
||||
/**
|
||||
* This copies the functionality of the ionicConfig provider to allow for platform specific configuration
|
||||
*/
|
||||
(function (angular) {
|
||||
'use strict';
|
||||
|
||||
angular.module('jett.ionic.filter.bar')
|
||||
.provider('$ionicFilterBarConfig', function () {
|
||||
|
||||
var provider = this;
|
||||
provider.platform = {};
|
||||
var PLATFORM = 'platform';
|
||||
|
||||
var configProperties = {
|
||||
theme: PLATFORM,
|
||||
clear: PLATFORM,
|
||||
add: PLATFORM,
|
||||
close: PLATFORM,
|
||||
done: PLATFORM,
|
||||
remove: PLATFORM,
|
||||
reorder: PLATFORM,
|
||||
favorite: PLATFORM,
|
||||
search: PLATFORM,
|
||||
backdrop: PLATFORM,
|
||||
transition: PLATFORM,
|
||||
platform: {},
|
||||
placeholder: PLATFORM
|
||||
};
|
||||
|
||||
createConfig(configProperties, provider, '');
|
||||
|
||||
// Default
|
||||
// -------------------------
|
||||
setPlatformConfig('default', {
|
||||
clear: 'ion-ios-close',
|
||||
add: 'ion-ios-plus-outline',
|
||||
close: 'ion-ios-close-empty',
|
||||
done: 'ion-ios-checkmark-empty',
|
||||
remove: 'ion-ios-trash-outline',
|
||||
reorder: 'ion-drag',
|
||||
favorite: 'ion-ios-star',
|
||||
search: 'ion-ios-search-strong',
|
||||
backdrop: true,
|
||||
transition: 'vertical',
|
||||
placeholder: 'Search'
|
||||
});
|
||||
|
||||
// iOS (it is the default already)
|
||||
// -------------------------
|
||||
setPlatformConfig('ios', {});
|
||||
|
||||
// Android
|
||||
// -------------------------
|
||||
setPlatformConfig('android', {
|
||||
clear: 'ion-android-close',
|
||||
close: 'ion-android-close',
|
||||
done: 'ion-android-done',
|
||||
remove: 'ion-android-delete',
|
||||
favorite: 'ion-android-star',
|
||||
search: false,
|
||||
backdrop: false,
|
||||
transition: 'horizontal'
|
||||
});
|
||||
|
||||
provider.setPlatformConfig = setPlatformConfig;
|
||||
|
||||
// private: used to set platform configs
|
||||
function setPlatformConfig(platformName, platformConfigs) {
|
||||
configProperties.platform[platformName] = platformConfigs;
|
||||
provider.platform[platformName] = {};
|
||||
|
||||
addConfig(configProperties, configProperties.platform[platformName]);
|
||||
|
||||
createConfig(configProperties.platform[platformName], provider.platform[platformName], '');
|
||||
}
|
||||
|
||||
// private: used to recursively add new platform configs
|
||||
function addConfig(configObj, platformObj) {
|
||||
for (var n in configObj) {
|
||||
if (n != PLATFORM && configObj.hasOwnProperty(n)) {
|
||||
if (angular.isObject(configObj[n])) {
|
||||
if (!angular.isDefined(platformObj[n])) {
|
||||
platformObj[n] = {};
|
||||
}
|
||||
addConfig(configObj[n], platformObj[n]);
|
||||
|
||||
} else if (!angular.isDefined(platformObj[n])) {
|
||||
platformObj[n] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// private: create methods for each config to get/set
|
||||
function createConfig(configObj, providerObj, platformPath) {
|
||||
angular.forEach(configObj, function(value, namespace) {
|
||||
|
||||
if (angular.isObject(configObj[namespace])) {
|
||||
// recursively drill down the config object so we can create a method for each one
|
||||
providerObj[namespace] = {};
|
||||
createConfig(configObj[namespace], providerObj[namespace], platformPath + '.' + namespace);
|
||||
|
||||
} else {
|
||||
// create a method for the provider/config methods that will be exposed
|
||||
providerObj[namespace] = function(newValue) {
|
||||
if (arguments.length) {
|
||||
configObj[namespace] = newValue;
|
||||
return providerObj;
|
||||
}
|
||||
if (configObj[namespace] == PLATFORM) {
|
||||
// if the config is set to 'platform', then get this config's platform value
|
||||
var platformConfig = stringObj(configProperties.platform, ionic.Platform.platform() + platformPath + '.' + namespace);
|
||||
if (platformConfig || platformConfig === false) {
|
||||
return platformConfig;
|
||||
}
|
||||
// didnt find a specific platform config, now try the default
|
||||
return stringObj(configProperties.platform, 'default' + platformPath + '.' + namespace);
|
||||
}
|
||||
return configObj[namespace];
|
||||
};
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
//splits a string by dot operator and accesses the end var. For example in a.b.c,
|
||||
function stringObj(obj, str) {
|
||||
str = str.split(".");
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
if (obj && angular.isDefined(obj[str[i]])) {
|
||||
obj = obj[str[i]];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
provider.$get = function() {
|
||||
return provider;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
})(angular);
|
||||
|
||||
/* global angular,ionic */
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name $ionicFilterBar
|
||||
* @module ionic
|
||||
* @description The Filter Bar is an animated bar that allows a user to search or filter an array of items.
|
||||
*/
|
||||
(function (angular, ionic) {
|
||||
'use strict';
|
||||
|
||||
var filterBarModalTemplate =
|
||||
'<ion-modal-view ng-controller="$ionicFilterBarModalCtrl" class="filter-bar-modal">' +
|
||||
'<ion-header-bar class="bar bar-{{::config.theme}} disable-user-behavior">' +
|
||||
'<button class="button button-icon {{::config.close}}" ng-click="closeModal()"></button>' +
|
||||
'<h1 class="title" ng-bind-html="::favoritesTitle"></h1>' +
|
||||
'<button ng-if="searches.length > 1" class="button button-icon" ng-class="displayData.showReorder ? config.done : config.reorder" ng-click="displayData.showReorder = !displayData.showReorder"></button>' +
|
||||
'</ion-header-bar>' +
|
||||
'<ion-content>' +
|
||||
'<ion-list show-reorder="displayData.showReorder" delegate-handle="searches-list">' +
|
||||
'<ion-item ng-repeat="item in searches" class="item-remove-animate" ng-class="{reordered: item.reordered}" ng-click="itemClicked(item.text, $event)">' +
|
||||
'<span ng-bind-html="item.text"></span>' +
|
||||
'<ion-option-button class="button-assertive icon {{::config.remove}}" ng-click="deleteItem(item)"></ion-option-button>' +
|
||||
'<ion-reorder-button class="{{::config.reorder}}" on-reorder="moveItem(item, $fromIndex, $toIndex)"></ion-reorder-button>' +
|
||||
'</ion-item>' +
|
||||
'<div class="item item-input">' +
|
||||
'<input type="text" ng-model="newItem.text" placeholder="{{::favoritesAddPlaceholder}}"/>' +
|
||||
'<button class="button button-icon icon {{::config.add}}" ng-click="addItem(newItem)"></button>' +
|
||||
'</div>' +
|
||||
'</ion-list>' +
|
||||
'</ion-content> ' +
|
||||
'</ion-modal-view>';
|
||||
|
||||
var getNavBarTheme = function ($navBar) {
|
||||
var themes = ['light', 'stable', 'positive', 'calm', 'balanced', 'energized', 'assertive', 'royal', 'dark'];
|
||||
var classList = $navBar && $navBar.classList;
|
||||
|
||||
if (!classList) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < themes.length; i++) {
|
||||
if (classList.contains('bar-' + themes[i])) {
|
||||
return themes[i];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
angular.module('jett.ionic.filter.bar')
|
||||
.factory('$ionicFilterBar', [
|
||||
'$document',
|
||||
'$rootScope',
|
||||
'$compile',
|
||||
'$timeout',
|
||||
'$filter',
|
||||
'$ionicPlatform',
|
||||
'$ionicFilterBarConfig',
|
||||
'$ionicConfig',
|
||||
'$ionicModal',
|
||||
'$ionicScrollDelegate',
|
||||
function ($document, $rootScope, $compile, $timeout, $filter, $ionicPlatform, $ionicFilterBarConfig, $ionicConfig, $ionicModal, $ionicScrollDelegate) {
|
||||
var isShown = false;
|
||||
var $body = $document[0].body;
|
||||
var templateConfig = {
|
||||
theme: $ionicFilterBarConfig.theme(),
|
||||
transition: $ionicFilterBarConfig.transition(),
|
||||
back: $ionicConfig.backButton.icon(),
|
||||
clear: $ionicFilterBarConfig.clear(),
|
||||
favorite: $ionicFilterBarConfig.favorite(),
|
||||
search: $ionicFilterBarConfig.search(),
|
||||
backdrop: $ionicFilterBarConfig.backdrop(),
|
||||
placeholder: $ionicFilterBarConfig.placeholder(),
|
||||
close: $ionicFilterBarConfig.close(),
|
||||
done: $ionicFilterBarConfig.done(),
|
||||
reorder: $ionicFilterBarConfig.reorder(),
|
||||
remove: $ionicFilterBarConfig.remove(),
|
||||
add: $ionicFilterBarConfig.add()
|
||||
};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name $ionicFilterBar#show
|
||||
* @description
|
||||
* Load and return a new filter bar.
|
||||
*
|
||||
* A new isolated scope will be created for the filter bar and the new filter bar will be appended to the
|
||||
* body, covering the header bar.
|
||||
*
|
||||
* @returns {function} `hideFilterBar` A function which, when called, hides & cancels the filter bar.
|
||||
*/
|
||||
function filterBar (opts) {
|
||||
//if filterBar is already shown return
|
||||
if (isShown) {
|
||||
return;
|
||||
}
|
||||
|
||||
isShown = true;
|
||||
opts = opts || {};
|
||||
|
||||
var scope = $rootScope.$new(true);
|
||||
var backdropShown = false;
|
||||
var isKeyboardShown = false;
|
||||
|
||||
//if container option is set, determine the container element by querying for the container class
|
||||
if (opts.container) {
|
||||
opts.container = $body.querySelector(opts.container);
|
||||
}
|
||||
|
||||
//extend scope defaults with supplied options
|
||||
angular.extend(scope, {
|
||||
config: templateConfig,
|
||||
$deregisterBackButton: angular.noop,
|
||||
update: angular.noop,
|
||||
cancel: angular.noop,
|
||||
done: angular.noop,
|
||||
scrollDelegate: $ionicScrollDelegate,
|
||||
filter: $filter('filter'),
|
||||
filterProperties: null,
|
||||
expression: null,
|
||||
comparator: null,
|
||||
debounce: true,
|
||||
delay: 300,
|
||||
cancelText: 'Cancel',
|
||||
cancelOnStateChange: true,
|
||||
container: $body,
|
||||
favoritesTitle: 'Favorite Searches',
|
||||
favoritesAddPlaceholder: 'Add a search term',
|
||||
favoritesEnabled: false,
|
||||
favoritesKey: 'ionic_filter_bar_favorites'
|
||||
}, opts);
|
||||
|
||||
scope.data = {filterText: ''};
|
||||
|
||||
//if no custom theme was configured, get theme of containers bar-header
|
||||
if (!scope.config.theme) {
|
||||
scope.config.theme = getNavBarTheme(scope.container.querySelector('.bar.bar-header'));
|
||||
}
|
||||
|
||||
// Compile the template
|
||||
var element = scope.element = $compile('<ion-filter-bar class="filter-bar"></ion-filter-bar>')(scope);
|
||||
|
||||
// Grab required jQLite elements
|
||||
var filterWrapperEl = element.children().eq(0);
|
||||
var input = filterWrapperEl.find('input')[0];
|
||||
var backdropEl = element.children().eq(1);
|
||||
|
||||
//get scrollView
|
||||
var scrollView = scope.scrollDelegate.getScrollView();
|
||||
var canScroll = !!scrollView;
|
||||
|
||||
//get the scroll container if scrolling is available
|
||||
var $scrollContainer = canScroll ? scrollView.__container : null;
|
||||
|
||||
var stateChangeListenDone = scope.cancelOnStateChange ?
|
||||
$rootScope.$on('$stateChangeSuccess', function () { scope.cancelFilterBar(); }) :
|
||||
angular.noop;
|
||||
|
||||
// Focus the input which will show the keyboard.
|
||||
var showKeyboard = function () {
|
||||
if (!isKeyboardShown) {
|
||||
isKeyboardShown = true;
|
||||
input && input.focus();
|
||||
}
|
||||
};
|
||||
|
||||
// Blur the input which will hide the keyboard.
|
||||
// Even if we need to bring in ionic.keyboard in the future, blur is preferred so keyboard animates out.
|
||||
var hideKeyboard = function () {
|
||||
if (isKeyboardShown) {
|
||||
isKeyboardShown = false;
|
||||
input && input.blur();
|
||||
}
|
||||
};
|
||||
|
||||
// When the filtered list is scrolled, we want to hide the keyboard as long as it's not already hidden
|
||||
var handleScroll = function () {
|
||||
if (scrollView.__scrollTop > 0) {
|
||||
hideKeyboard();
|
||||
}
|
||||
};
|
||||
|
||||
// Scrolls the list of items to the top via the scroll delegate
|
||||
scope.scrollItemsTop = function () {
|
||||
if (canScroll && scrollView.__scrollTop > 0 && scope.scrollDelegate.scrollTop) {
|
||||
scope.scrollDelegate.scrollTop();
|
||||
}
|
||||
};
|
||||
|
||||
// Set isKeyboardShown to force showing keyboard on search focus.
|
||||
scope.focusInput = function () {
|
||||
isKeyboardShown = false;
|
||||
showKeyboard();
|
||||
};
|
||||
|
||||
// Hide the filterBar backdrop if in the DOM and not already hidden.
|
||||
scope.hideBackdrop = function () {
|
||||
if (backdropEl.length && backdropShown) {
|
||||
backdropShown = false;
|
||||
backdropEl.removeClass('active').css('display', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
// Show the filterBar backdrop if in the DOM and not already shown.
|
||||
scope.showBackdrop = function () {
|
||||
if (backdropEl.length && !backdropShown) {
|
||||
backdropShown = true;
|
||||
backdropEl.css('display', 'block').addClass('active');
|
||||
}
|
||||
};
|
||||
|
||||
scope.showModal = function () {
|
||||
scope.modal = $ionicModal.fromTemplate(filterBarModalTemplate, {
|
||||
scope: scope
|
||||
});
|
||||
scope.modal.show();
|
||||
};
|
||||
|
||||
// Filters the supplied list of items via the supplied filterText.
|
||||
// How items are filtered depends on the supplied filter object, and expression
|
||||
// Filtered items will be sent to update
|
||||
scope.filterItems = function(filterText) {
|
||||
var filterExp, filteredItems;
|
||||
|
||||
// pass back original list if filterText is empty.
|
||||
// Otherwise filter by expression, supplied properties, or filterText.
|
||||
if (!filterText.length) {
|
||||
filteredItems = scope.items;
|
||||
} else {
|
||||
if (scope.expression) {
|
||||
filterExp = angular.bind(this, scope.expression, filterText);
|
||||
} else if (angular.isArray(scope.filterProperties)) {
|
||||
filterExp = {};
|
||||
angular.forEach(scope.filterProperties, function (property) {
|
||||
filterExp[property] = filterText;
|
||||
});
|
||||
} else if (scope.filterProperties) {
|
||||
filterExp = {};
|
||||
filterExp[scope.filterProperties] = filterText;
|
||||
} else {
|
||||
filterExp = filterText;
|
||||
}
|
||||
|
||||
filteredItems = scope.filter(scope.items, filterExp, scope.comparator);
|
||||
}
|
||||
|
||||
$timeout(function() {
|
||||
scope.update(filteredItems, filterText);
|
||||
scope.scrollItemsTop();
|
||||
});
|
||||
};
|
||||
|
||||
// registerBackButtonAction returns a callback to deregister the action
|
||||
scope.$deregisterBackButton = $ionicPlatform.registerBackButtonAction(
|
||||
function() {
|
||||
$timeout(scope.cancelFilterBar);
|
||||
}, 300
|
||||
);
|
||||
|
||||
// Removes the filterBar from the body and cleans up vars/events. Once the backdrop is hidden we can invoke done
|
||||
scope.removeFilterBar = function(done) {
|
||||
if (scope.removed) return;
|
||||
|
||||
scope.removed = true;
|
||||
|
||||
//animate the filterBar out, hide keyboard and backdrop
|
||||
ionic.requestAnimationFrame(function () {
|
||||
filterWrapperEl.removeClass('filter-bar-in');
|
||||
hideKeyboard();
|
||||
scope.hideBackdrop();
|
||||
|
||||
//Wait before cleaning up so element isn't removed before filter bar animates out
|
||||
$timeout(function () {
|
||||
scope.scrollItemsTop();
|
||||
scope.update(scope.items);
|
||||
|
||||
scope.$destroy();
|
||||
element.remove();
|
||||
scope.cancelFilterBar.$scope = scope.modal = $scrollContainer = scrollView = filterWrapperEl = backdropEl = input = null;
|
||||
isShown = false;
|
||||
(done || angular.noop)();
|
||||
}, 350);
|
||||
});
|
||||
|
||||
$timeout(function () {
|
||||
// wait to remove this due to a 300ms delay native
|
||||
// click which would trigging whatever was underneath this
|
||||
scope.container.classList.remove('filter-bar-open');
|
||||
}, 400);
|
||||
|
||||
scope.$deregisterBackButton();
|
||||
stateChangeListenDone();
|
||||
|
||||
//unbind scroll event
|
||||
if ($scrollContainer) {
|
||||
$scrollContainer.removeEventListener('scroll', handleScroll);
|
||||
}
|
||||
};
|
||||
|
||||
// Appends the filterBar to the body. Once the backdrop is hidden we can invoke done
|
||||
scope.showFilterBar = function(done) {
|
||||
if (scope.removed) return;
|
||||
|
||||
scope.container.appendChild(element[0]);
|
||||
scope.container.classList.add('filter-bar-open');
|
||||
|
||||
//scroll items to the top before starting the animation
|
||||
scope.scrollItemsTop();
|
||||
|
||||
//start filterBar animation, show backrop and focus the input
|
||||
ionic.requestAnimationFrame(function () {
|
||||
if (scope.removed) return;
|
||||
|
||||
$timeout(function () {
|
||||
filterWrapperEl.addClass('filter-bar-in');
|
||||
scope.focusInput();
|
||||
scope.showBackdrop();
|
||||
(done || angular.noop)();
|
||||
}, 20, false);
|
||||
});
|
||||
|
||||
if ($scrollContainer) {
|
||||
$scrollContainer.addEventListener('scroll', handleScroll);
|
||||
}
|
||||
};
|
||||
|
||||
// called when the user presses the backdrop, cancel/back button, changes state
|
||||
scope.cancelFilterBar = function() {
|
||||
// after the animation is out, call the cancel callback
|
||||
scope.removeFilterBar(scope.cancel);
|
||||
};
|
||||
|
||||
scope.showFilterBar(scope.done);
|
||||
|
||||
// Expose the scope on $ionFilterBar's return value for the sake of testing it.
|
||||
scope.cancelFilterBar.$scope = scope;
|
||||
|
||||
return scope.cancelFilterBar;
|
||||
}
|
||||
|
||||
return {
|
||||
show: filterBar
|
||||
};
|
||||
}]);
|
||||
|
||||
|
||||
})(angular, ionic);
|
||||
|
||||
/* global angular */
|
||||
(function (angular) {
|
||||
'use strict';
|
||||
|
||||
angular.module('jett.ionic.filter.bar')
|
||||
.controller('$ionicFilterBarModalCtrl', [
|
||||
'$window',
|
||||
'$scope',
|
||||
'$timeout',
|
||||
'$ionicListDelegate',
|
||||
function ($window, $scope, $timeout, $ionicListDelegate) {
|
||||
var searchesKey = $scope.$parent.favoritesKey;
|
||||
|
||||
$scope.displayData = {showReorder: false};
|
||||
$scope.searches = angular.fromJson($window.localStorage.getItem(searchesKey)) || [];
|
||||
$scope.newItem = {text: ''};
|
||||
|
||||
$scope.moveItem = function(item, fromIndex, toIndex) {
|
||||
item.reordered = true;
|
||||
$scope.searches.splice(fromIndex, 1);
|
||||
$scope.searches.splice(toIndex, 0, item);
|
||||
|
||||
$timeout(function () {
|
||||
delete item.reordered;
|
||||
}, 500);
|
||||
};
|
||||
|
||||
$scope.deleteItem = function(item) {
|
||||
var index = $scope.searches.indexOf(item);
|
||||
$scope.searches.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.addItem = function () {
|
||||
if ($scope.newItem.text) {
|
||||
$scope.searches.push({
|
||||
text: $scope.newItem.text
|
||||
});
|
||||
$scope.newItem.text = '';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.closeModal = function () {
|
||||
$window.localStorage.setItem(searchesKey, angular.toJson($scope.searches));
|
||||
$scope.$parent.modal.remove();
|
||||
};
|
||||
|
||||
$scope.itemClicked = function (filterText, $event) {
|
||||
var isOptionButtonsClosed = !!$event.currentTarget.querySelector('.item-options.invisible');
|
||||
|
||||
if (isOptionButtonsClosed) {
|
||||
$scope.closeModal();
|
||||
$scope.$parent.hideBackdrop();
|
||||
$scope.$parent.data.filterText = filterText;
|
||||
$scope.$parent.filterItems(filterText);
|
||||
} else {
|
||||
$ionicListDelegate.$getByHandle('searches-list').closeOptionButtons();
|
||||
}
|
||||
};
|
||||
|
||||
}]);
|
||||
|
||||
})(angular);
|
||||
1
www/lib/ionic-filter-bar/dist/ionic.filter.bar.min.css
vendored
Normal file
1
www/lib/ionic-filter-bar/dist/ionic.filter.bar.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
www/lib/ionic-filter-bar/dist/ionic.filter.bar.min.js
vendored
Normal file
1
www/lib/ionic-filter-bar/dist/ionic.filter.bar.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
179
www/lib/ionic-filter-bar/scss/ionic.filter.bar.scss
Normal file
179
www/lib/ionic-filter-bar/scss/ionic.filter.bar.scss
Normal file
@@ -0,0 +1,179 @@
|
||||
// Filter Bar
|
||||
|
||||
// Variables
|
||||
//-----------------------------------
|
||||
|
||||
$z-index-filter-bar: 11;
|
||||
|
||||
// Mixins
|
||||
//-----------------------------------
|
||||
|
||||
@mixin filter-bar-style($filter-bar-bg-color, $filter-bar-active-border-color, $filter-bar-text) {
|
||||
.item-input-wrapper {
|
||||
border-bottom: 1px solid $filter-bar-active-border-color;
|
||||
background: $filter-bar-bg-color;
|
||||
input[type="search"] {
|
||||
@include placeholder(lighten($filter-bar-text, 40%));
|
||||
color: $filter-bar-text;
|
||||
}
|
||||
.filter-bar-clear {
|
||||
&:before {
|
||||
color: $filter-bar-text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Styles
|
||||
//-----------------------------------
|
||||
|
||||
.filter-bar-backdrop {
|
||||
@include transition(opacity 150ms ease-in-out);
|
||||
opacity: 0;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&.active {
|
||||
z-index: $z-index-bar-above;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: $bar-height;
|
||||
z-index: $z-index-bar-above;
|
||||
|
||||
.filter-bar-wrapper {
|
||||
z-index: $z-index-filter-bar;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right:0;
|
||||
width: 100%;
|
||||
|
||||
.item-input-inset {
|
||||
.icon.placeholder-icon:before {
|
||||
padding-top: 3px;
|
||||
font-size: 16px;
|
||||
}
|
||||
.item-input-wrapper {
|
||||
background: $light;
|
||||
height: 28px;
|
||||
.filter-bar-clear {
|
||||
padding: 0 2px 0 0;
|
||||
&:before {
|
||||
color: #aaa;
|
||||
font-size: 18px;
|
||||
padding-top: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//android
|
||||
.platform-android {
|
||||
.filter-bar {
|
||||
.filter-bar-light {
|
||||
@include filter-bar-style($bar-light-bg, $bar-light-active-border, $bar-light-text);
|
||||
}
|
||||
.filter-bar-stable {
|
||||
@include filter-bar-style($bar-stable-bg, $bar-stable-active-border, $bar-stable-text);
|
||||
}
|
||||
.filter-bar-positive {
|
||||
@include filter-bar-style($bar-positive-bg, $bar-positive-active-border, $bar-positive-text);
|
||||
}
|
||||
.filter-bar-calm {
|
||||
@include filter-bar-style($bar-calm-bg, $bar-calm-active-border, $bar-positive-text);
|
||||
}
|
||||
.filter-bar-assertive {
|
||||
@include filter-bar-style($bar-assertive-bg, $bar-assertive-active-border, $bar-assertive-text);
|
||||
}
|
||||
.filter-bar-balanced {
|
||||
@include filter-bar-style($bar-balanced-bg, $bar-balanced-active-border, $bar-balanced-text);
|
||||
}
|
||||
.filter-bar-energized {
|
||||
@include filter-bar-style($bar-energized-bg, $bar-energized-active-border, $bar-energized-text);
|
||||
}
|
||||
.filter-bar-royal {
|
||||
@include filter-bar-style($bar-royal-bg, $bar-royal-active-border, $bar-royal-text);
|
||||
}
|
||||
.filter-bar-dark {
|
||||
@include filter-bar-style($bar-dark-bg, $bar-dark-active-border, $bar-dark-text);
|
||||
}
|
||||
.filter-bar-default {
|
||||
@include filter-bar-style($bar-default-bg, $bar-default-active-border, $bar-default-text)
|
||||
};
|
||||
}
|
||||
|
||||
.filter-bar-wrapper {
|
||||
.item-input-inset {
|
||||
padding-right: $button-padding * 2;
|
||||
.filter-bar-cancel {
|
||||
padding-left: 0;
|
||||
&:before {
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
.item-input-wrapper {
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
margin-left: 10px;
|
||||
input[type="search"] {
|
||||
font-weight: 500;
|
||||
}
|
||||
.filter-bar-clear:before {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter-bar-transition-horizontal {
|
||||
@include transition-transform(cubic-bezier(.25, .45, .05, 1) 300ms);
|
||||
@include translate3d(100%, 0, 0);
|
||||
}
|
||||
|
||||
.filter-bar-transition-vertical {
|
||||
@include transition-transform(cubic-bezier(.25, .45, .05, 1) 350ms);
|
||||
@include translate3d(0, -100%, 0);
|
||||
}
|
||||
|
||||
.filter-bar-transition-fade {
|
||||
@include transition(opacity 250ms ease-in-out) ;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.filter-bar-in {
|
||||
@include translate3d(0, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.filter-bar-modal {
|
||||
.item {
|
||||
&.item-input {
|
||||
padding-right: $item-padding;
|
||||
}
|
||||
}
|
||||
.list-right-editing {
|
||||
.item.item-input {
|
||||
opacity: .5;
|
||||
}
|
||||
}
|
||||
|
||||
//in my opinion the ios checkmark is a little skimp.. make it bigger
|
||||
.button.button-icon.ion-ios-checkmark-empty:before {
|
||||
font-size: 42px;
|
||||
}
|
||||
}
|
||||
|
||||
.filter-bar-hide {
|
||||
display: none;
|
||||
}
|
||||
Reference in New Issue
Block a user