Skip to content
This repository has been archived by the owner on Dec 1, 2023. It is now read-only.

Commit

Permalink
feat(aside): add $aside module
Browse files Browse the repository at this point in the history
  • Loading branch information
mgcrea committed Jan 7, 2014
1 parent 1184a78 commit 0731af2
Show file tree
Hide file tree
Showing 6 changed files with 480 additions and 0 deletions.
109 changes: 109 additions & 0 deletions src/aside/aside.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'use strict';

var forEach = angular.forEach;
var isObject = angular.isObject;
var isDefined = angular.isDefined;

angular.module('mgcrea.ngStrap.aside', [])

.run(function($templateCache) {
var template = '' +
'<div class="aside" tabindex="-1" role="dialog">' +
'<div class="aside-dialog">' +
'<div class="aside-content">' +
'<div class="aside-header" ng-show="title">' +
'<button type="button" class="close" ng-click="$hide()">&times;</button>' +
'<h4 class="aside-title" ng-bind-html="title"></h4>' +
'</div>' +
'<div class="aside-body" ng-show="content" ng-bind-html="content"></div>' +
'<div class="aside-footer">' +
'<button type="button" class="btn btn-default" ng-click="$hide()">Close</button>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
$templateCache.put('$aside', template);
})

.provider('$aside', function() {

var defaults = this.defaults = {
animation: 'animation-fadeAndSlideRight',
prefixClass: 'aside',
placement: 'right',
template: '$aside',
container: false,
element: null,
backdrop: true,
keyboard: true,
show: true
};

this.$get = function($modal) {

function AsideFactory(config) {

var $aside = {};

// Common vars
var options = angular.extend({}, defaults, config);

$aside = $modal(options);

return $aside;

}

return AsideFactory;

};

})

.directive('bsAside', function($window, $location, $sce, $aside) {

var requestAnimationFrame = $window.requestAnimationFrame || $window.setTimeout;

return {
restrict: 'EAC',
scope: true,
link: function postLink(scope, element, attr, transclusion) {
// Directive options
var options = {scope: scope, element: element, show: false};
forEach(['template', 'placement', 'backdrop', 'keyboard', 'show', 'container', 'animation'], function(key) {
if(isDefined(attr[key])) options[key] = attr[key];
});

// Support scope as data-attrs
forEach(['title', 'content'], function(key) {
attr[key] && attr.$observe(key, function(newValue, oldValue) {
scope[key] = newValue;
});
});

// Support scope as an object
attr.bsAside && scope.$watch(attr.bsAside, function(newValue, oldValue) {
if(angular.isObject(newValue)) {
angular.extend(scope, newValue);
} else {
scope.content = newValue;
}
}, true);

// Initialize aside
var aside = $aside(options);

// Trigger
element.on(attr.trigger || 'click', aside.toggle);

// Garbage collection
scope.$on('$destroy', function() {
aside.destroy();
options = null;
aside = null;
});

}
};

});
174 changes: 174 additions & 0 deletions src/aside/docs/aside.demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
<div class="bs-docs-section" ng-controller="AsideDemoCtrl">

<div class="page-header">
<h1 id="asides">Asides <a class="small" href="//github.com/mgcrea/angular-strap/blob/master/src/aside/aside.js" target="_blank">aside.js</a>
</h1>
<code>mgcrea.ngStrap.aside</code>
</div>


<h2 id="asides-examples">Examples</h2>
<p>Asides are custom panels, drawers that inherit the behavior of modals.</p>

<div class="callout callout-danger">
<h4>Plugin dependency</h4>
<p>Asides require the <a href="#modals">modal plugin</a> to be included.</p>
</div>

<h3>Live demo <a class="small" href="#" target="_blank"><i class="fa fa-edit" data-title="edit in plunker" data-placement="right" bs-tooltip></i></a></h3>
<pre class="bs-example-scope">$scope.aside = {{aside | json}};</pre>
<div class="bs-example" style="padding-bottom: 24px;" append-source>

<!-- Button to trigger a default aside with a scope as an object {title:'', content:'', etc.} -->
<button type="button" class="btn btn-lg btn-primary" bs-aside="aside">Click to toggle aside
<br />
<small>(using an object)</small>
</button>

<!-- You can use a custom html template with the `data-template` attr -->
<button type="button" class="btn btn-lg btn-danger" data-template="aside/docs/aside.tpl.demo.html" data-placement="left" data-animation="animation-fadeAndSlideLeft" bs-aside="aside">Custom aside
<br />
<small>(using data-template)</small>
</button>

</div>


<h2 id="asides-usage">Usage</h2>
<p>Append a <code>bs-aside</code>attribute to any element to enable the plugin.</p>
<div class="callout callout-info">
<h4>The module also exposes an <code>$aside</code>service</h4>
<p>Available for programmatic use.</p>
<div class="highlight">
<pre>
<code class="javascript" highlight-block>
angular.module('myApp')
.controller('DemoCtrl', function($scope, $aside) {
// Show a basic aside from a controller
var myAside = $aside({title: 'My Title', content: 'My Content', show: true});

// Pre-fetch an external template populated with a custom scope
var myOtherAside = $aside({scope: $scope, template: 'aside/docs/aside.tpl.demo.html'});
// Show when some event occurs (uses promises to ensure the template has been loaded)
myOtherModal.deferred.then(function() {
myOtherModal.show();
})
})
</code>
</pre>
</div>
</div>

<h3>Options</h3>
<p>Options can be passed via data-attributes on the directive or as an object hash to configure the service. For data attributes, append the option name to <code>data-</code>, as in <code>data-animation=""</code>.</p>
<p>For directives, you can naturally inherit the contextual <code>$scope</code> or leverage a custom one with an <a href="http://docs.angularjs.org/guide/expression">AngularJS expression</a> to evaluate as an object directly on the <code>bs-aside</code> attribute</p>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th style="width: 100px;">Name</th>
<th style="width: 50px;">type</th>
<th style="width: 50px;">default</th>
<th>description</th>
</tr>
</thead>
<tbody>
<tr>
<td>animation</td>
<td>string</td>
<td>animation-fadeAndSlideRight</td>
<td>apply a CSS animation powered by ngAnimate</td>
</tr>
<tr>
<td>placement</td>
<td>string</td>
<td>'top'</td>
<td>how to position the modal - top | bottom | center <small>(requires custom CSS)</small>.</td>
</tr>
<tr>
<td>title</td>
<td>string</td>
<td>''</td>
<td>default title value if
<code>title</code>attribute isn't present</td>
</tr>
<tr>
<td>content</td>
<td>string</td>
<td>''</td>
<td>default content value if
<code>data-content</code>attribute isn't present</td>
</tr>
<tr>
<td>backdrop</td>
<td>boolean or the string
<code>'static'</code>
</td>
<td>true</td>
<td>Includes a modal-backdrop element. Alternatively, specify
<code>static</code>for a backdrop which doesn't close the modal on click.</td>
</tr>
<tr>
<td>keyboard</td>
<td>boolean</td>
<td>true</td>
<td>Closes the modal when escape key is pressed</td>
</tr>
<tr>
<td>show</td>
<td>boolean</td>
<td>true</td>
<td>Shows the modal when initialized.</td>
</tr>
<tr>
<td>container</td>
<td>string | false</td>
<td>false</td>
<td>
<p>Appends the popover to a specific element. Example:
<code>container: 'body'</code>. This option is particularly useful in that it allows you to position the popover in the flow of the document near the triggering element -&nbsp;which will prevent the popover from floating away from the triggering element during a window resize.</p>
</td>
</tr>
<tr>
<td>template</td>
<td>path</td>
<td>false</td>
<td>
<p>If provided, overrides the default template, can be either a remote URL or a cached template id.</p>
</td>
</tr>
</tbody>
</table>
</div>
<div class="callout callout-info">
<h4>Default options</h4>
<p>You can override global defaults for the plugin with <code>$asideProvider.defaults</code></p>
<div class="highlight">
<pre class="bs-exemple-code">
<code class="javascript" highlight-block>
angular.module('myApp')
.config(function($asideProvider) {
angular.extend($asideProvider.defaults, {
animation: 'animation-fadeAndSlideLeft',
placement: 'left'
});
})
</code>
</pre>
</div>
</div>


<h3>Scope methods</h3>
<p>Methods available inside the directive scope to toggle visibility.</p>

<h4>$show()</h4>
<p>Reveals the aside.</p>

<h4>$hide()</h4>
<p>Hides the aside.</p>

<h4>$toggle()</h4>
<p>Toggles the aside.</p>

</div>
7 changes: 7 additions & 0 deletions src/aside/docs/aside.demo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
'use strict';

angular.module('mgcrea.ngStrapDocs')

.controller('AsideDemoCtrl', function($scope) {
$scope.aside = {title: 'Title', content: 'Hello Aside<br />This is a multiline message!'};
});
27 changes: 27 additions & 0 deletions src/aside/docs/aside.tpl.demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<div class="aside" tabindex="-1" role="dialog">
<div class="aside-dialog">
<div class="aside-content">
<div class="aside-header" ng-show="title">
<button type="button" class="close" ng-click="$hide()">&times;</button>
<h4 class="aside-title" ng-bind-html="title"></h4>
</div>
<div class="aside-body" ng-show="content">

<h4>Text in aside</h4>
<p ng-bind-html="content"></p>
<pre>2 + 3 = {{ 2 + 3 }}</pre>

<h4>Popover in aside</h4>
<p>This <a href="#" role="button" class="btn btn-default popover-test" data-title="A Title" data-content="And here's some amazing content. It's very engaging. right?" bs-popover>button</a> should trigger a popover on click.</p>

<h4>Tooltips in aside</h4>
<p><a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>This link</a> and <a href="#" class="tooltip-test" data-title="Tooltip" bs-tooltip>that link</a> should have tooltips on hover.</p>

</div>
<div class="aside-footer">
<button type="button" class="btn btn-default" ng-click="$hide()">Close</button>
<button type="button" class="btn btn-primary" ng-click="$hide()">Save changes</button>
</div>
</div>
</div>
</div>
1 change: 1 addition & 0 deletions src/aside/test/.jshintrc

0 comments on commit 0731af2

Please sign in to comment.