Giter Club home page Giter Club logo

ion-drawer-vertical's Introduction

ion-drawer-vertical

A vertical slide-out panel (toggle panel) for Ionic. Built by Bram(us) Van Damme - https://www.bram.us

Demo ion-drawer-vertical

Danger, here be dragons

Do note that this is an early release of ion-drawer-vertical. Whilst the basics work, a few things still need tweaking (the animation speed for example) or might change in the future.

Installation

You may clone this repo or get ion-drawer-vertical via Bower:

bower install ion-drawer-vertical

Usage

Usage is simple: include the source files, inject the project as a dependency and add some markup [PEN]

  1. Refer to the ionic.contrib.drawer.vertical.js and ionic.contrib.drawer.vertical.css files from within your HTML file:

    <link href="src/ionic.contrib.drawer.vertical.css" rel="stylesheet">
    <script src="src/ionic.contrib.drawer.vertical.js"></script>
  2. Inject ionic.contrib.drawer.vertical as a dependency into your Angular app:

    angular.module('app', [
    	'ionic',
    	'ionic.contrib.drawer.vertical'
    ])
  3. Add a <ion-drawer-vertical-wrapper> element to your document. Inside it, put a <ion-drawer-vertical-content> and an optional <ion-drawer-vertical-handle> element.

    <ion-drawer-vertical-wrapper>
    	<ion-drawer-vertical-content>
    		<img src="http://lorempixel.com/g/400/200/animals/4/horizontal-giraffe/" alt="Horizontal Giraffe" title="Horizontal Giraffe" />
    	</ion-drawer-vertical-content>
    	<ion-drawer-vertical-handle />
    </ion-drawer-vertical-wrapper>

Configuration

Adjust the direction (possible values: down [default] and up) and state (possible values: opened [default] and closed) attributes of the <ion-drawer-vertical-wrapper> element if needed. [PEN]

If any headers and/or footers are present, also set the proper has-* classes (such as has-header or has-footer) on the <ion-drawer-vertical-wrapper> element. [PEN]

When having a scrollable element (viz. ion-scroll or ion-content[scroll="true"]) it's possible to make the drawer automagically close when scrolling the content in the direction of the drawer itself. Enable it by setting autoclose-on-scroll on the <ion-drawer-vertical-wrapper> element. [PEN]

Adjust <ion-drawer-vertical-wrapper> atributemargin(default is 0, it's capped at <ion-drawer-vertical-wrapper> height), to show some part of the drawer content when closed.

(@note: the autoclose feature required some monkey patching of Ionic's scrollView behavior. Above that has not been tested (and won't work) with Ionic's scrollViewNative)

Events and Functions

ion-drawer-vertical automatically binds drag events to the <ion-drawer-vertical-handle> element if it's present. Dragging said element up/down will make the drawer follow its moves. Upon releasing the handle, the drawer will either revert to its original state, or to the opposite one (e.g. open will become closed) when having dragged far enough (over 33% of the height of the panel).

ion-drawer-vertical also ships with a delegate $ionDrawerVerticalDelegate. The methods openDrawer(), closeDrawer(), toggleDrawer(), and getState() are exposed via this delegate. [PEN]

angular
.module('app', ['ionic.contrib.drawer.vertical', 'ionic'])
.controller('demo', function($scope, $ionDrawerVerticalDelegate) {

	$scope.toggleDrawer = function() {
		$ionDrawerVerticalDelegate.toggleDrawer();
	}

});
<body ng-app="app" ng-controller="demo">
	<ion-header-bar class="bar-positive">
		<h1 class="title">ion-drawer-vertical</h1>
		<button class="button" ng-click="toggleDrawer()">Toggle Drawer</button>
	</ion-header-bar>
	<ion-drawer-vertical-wrapper class="has-header" direction="down" state="closed">
		<ion-drawer-vertical-content>[...]</ion-drawer-vertical-content>
		<ion-drawer-vertical-handle />
	</ion-drawer-vertical-wrapper>
	<ion-content>
		[...]
	</ion-content>
</body>

When cleverly combining getState() with ngIf one make the button change text/icon. [PEN]

angular
.module('app', ['ionic.contrib.drawer.vertical', 'ionic'])
.controller('demo', function($scope, $ionDrawerVerticalDelegate) {

	$scope.toggleDrawer = function() {
		$ionDrawerVerticalDelegate.toggleDrawer();
	}

	$scope.drawerIs = function(state) {
		return $ionDrawerVerticalDelegate.getState() == state;
	}

});
<body ng-app="app" ng-controller="demo">
	<ion-header-bar class="bar-positive">
		<h1 class="title">ion-drawer-vertical</h1>
		<button class="button" ng-click="toggleDrawer()">
			<i class="icon ion-ios-arrow-down" ng-show="drawerIs('opened')"></i>
			<i class="icon ion-ios-loop" ng-show="!drawerIs('opened') && !drawerIs('closed')"></i>
			<i class="icon ion-ios-arrow-up" ng-show="drawerIs('closed')"></i>
		</button>
	</ion-header-bar>
	...
</body>

Note that when calling methods on the delegate it will control all ion-drawer-vertical instances. To target one single / a specific instance use the $getByHandle method along with the delegate-handle attribute. [PEN]

angular
.module('app', ['ionic.contrib.drawer.vertical', 'ionic'])
.controller('demo', function($scope, $ionDrawerVerticalDelegate) {

	$scope.toggleDrawer = function(handle) {
		$ionDrawerVerticalDelegate.$getByHandle(handle).toggleDrawer();
	}

});
<body ng-app="app" ng-controller="demo">
	<ion-header-bar class="bar-positive">
		<button class="button" ng-click="toggleDrawer('first')">Toggle First</button>
		<h1 class="title">ion-drawer-vertical</h1>
		<button class="button" ng-click="toggleDrawer('second')">Toggle Second</button>
	</ion-header-bar>
	<ion-drawer-vertical-wrapper class="has-header" direction="down" state="closed" delegate-handle="first">
		<ion-drawer-vertical-content>[...]</ion-drawer-vertical-content>
		<ion-drawer-vertical-handle />
	</ion-drawer-vertical-wrapper>
	<ion-drawer-vertical-wrapper class="has-footer" direction="up" state="closed" delegate-handle="second">
		<ion-drawer-vertical-content>[...]</ion-drawer-vertical-content>
		<ion-drawer-vertical-handle />
	</ion-drawer-vertical-wrapper>
	<ion-content>
		[...]
	</ion-content>
	<ion-footer-bar class="bar-positive">
	</ion-footer-bar>
</body>

Callbacks / Promises

The methods closeDrawer(), openDrawer(), and toggleDrawer() all return a promise (provided by Angular's $q) allowing you to have callbacks

$scope.toggleDrawer = function() {
	$ionDrawerVerticalDelegate.toggleDrawer().then(function() {
		$ionDrawerVerticalDelegate.toggleDrawer().then(function() {
			$ionicPopup.alert({
				title: 'Done',
				template: 'Done sliding up and down'
			});
		});
	});
}

Acknowledgements

ionic-contrib-drawer has been a source of inspiration / a starting point for ion-drawer-vertical.

License

ion-drawer-vertical is released under the MIT public license. See the enclosed LICENSE for details.

ion-drawer-vertical's People

Contributors

alex-zane avatar bramus avatar cagica avatar mghayour avatar sebthieti avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ion-drawer-vertical's Issues

Showing drawer content partly when closed

Fantastic plugin! I implemented it to my app and it works great. However, I wanted to modify the way it works so that the wrapper is actually showing (let's say 20%) from the bottom of the screen. I managed to do this by editing one single CSS style:

ion-drawer-vertical-wrapper.up.closed { bottom: 20%; }

It works, but it breaks the animation and position calculations. When toggling / dragging, it jumps that 20% off and also goes over the screen boundaries. Any help would be appreciated on how to modify it so that it would be as smooth moving as by default? I am not sure how to go about altering the plugin js calculations. Cheers!

Encoding issue

Hi,

I am facing an issue concerning the encoding of the ionic.contrib.drawer.vertical.js file.
When I opened it on an editor, using another encoding than UTF-8/16, a special character appeared onthis line : if ((isClosed() || isDoneDragging()) && !isBusyAnimating()) {, after the pipe (see attached screenshot).

Can you commit a revised version of the file without the special character please ? I opened a fork.

Best regards

ion_vertical_drawer_error

Inject dependencies by string to be able to minify the code

As of now, dependencies needed by ionDrawerVertical are not injected as string, but only by parameter name. Because of that, once minified, the library won't work, as new minified parameters names won't mean anything to angular.

You should change this:
.controller('$ionDrawerVertical', function($scope, $element, $attrs ...

To this:
.controller('$ionDrawerVertical', ['$scope', '$element', '$attrs', function($scope, $element, $attrs ...

I've made a PR for that #21

Dynamic height causing the drawer to be visible on load

I could be wrong, but having the drawer set as a dynamic height in CSS (e.g. height: auto;) with runtime-loaded content will cause the drawer to be partially visible upon load, possibly due to the height calculation being performed before the content is loaded and the drawer sized appropriately.

autoclose-on-scroll slides back open in MobileSafari

Check http://s.codepen.io/bramus/debug/RWGaPW in MobileSafari: The drawer slides up when sliding up the list, yet upon releasing the drawer always slides back open.

Expected Flow when dragging and successively releasing:

  1. When starting a drag the (monkeypatched) scrollView.doTouchStart (L224) defines the starting positions (scrollView.__scrollTopAtTouchStart and scrollView.__scrollLeftAtTouchStart) and then triggers touchstart on the scrollView container.
  2. Whilst dragging the (monkeypatched) scrollView.doTouchMove (L245) triggers touchmove with the current position and the delta.
  3. $ionDrawerVertical responds to this touchmove event (L282) and passes the delta (e.detail.deltaY) to handleDrag() so that the panel position follows the dragging.
  4. Upon releasing the (monkeypatched) scrollView.doTouchEnd (L264) triggers touchend with the current position and the delta.
  5. $ionDrawerVertical responds to this touchend event (L294) and passes the delta (e.detail.deltaY) along with scrollView.__isDecelerating to handleDragEnd()
  6. handleDragEnd() will calculate if the user has scrolled far enough (or if the user has forcefully swiped over the list) and then close the drawer.

Having added extensive console.log()s to the demo, the console of the demo page will reflect this:

doTouchStart (__scrollTopAtTouchStart = 0)
(20) doTouchMove
doTouchEnd (scrollTop = 100)
touchend (deltaY = -100, force = false)
  drawer not closed, calling handleDragEnd()
handleDragEnd (deltaY = -100, force = false, height = 200)

In MobileSafari something strange is going on: touchend gets triggered twice somehow.

doTouchStart (__scrollTopAtTouchStart = 0)
doTouchMove (RWGaPW, line 311, x42)
touchend (deltaY = undefined, force = false)
  drawer not closed, calling handleDragEnd() (RWGaPW, line 369)
handleDragEnd (deltaY = undefined, force = false, height = 200) (RWGaPW, line 221)
doTouchEnd (scrollTop = 72) (RWGaPW, line 332)
touchend (deltaY = -72, force = false) (RWGaPW, line 365)
  drawer not closed, calling handleDragEnd() (RWGaPW, line 369)

As the first handleDragEnd() will set the state to STATE_DRAGGED, the second one (which has the correct parameters) won't do jack and thus the panel won't go to the closed state ...

Getting TypeError: Length undefined Error

Hi,

I am getting a TypeError : Cannot read property 'length' of undefined(ionic.bundle.js: 26794(if that helps :))). Can't seem to know why. I am rendering a page on button click which has the drawer. But the page doesn't get rendered. Instead I get this TypeError in the browser console. Please help.

Handle background

how can the background of the handle be changed according to the state? and this should be possible without the use of a button and adding ngclick.

iOS 8.4 bug (drawer hidden)

First, thanks for this project! It's really great.

There seems to be an issue on iOS 8 where the drawer content is hidden. Hovering over the element in the Safari inspector shows the blue content "shadow" in the right place, but the item isn't visible at all. Upon further inspection it looks like position: fixed might be causing an issue?

Any ideas on how to fix this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.