Skip to content

Instantly share code, notes, and snippets.

@copremesis
Created June 18, 2018 06:15
Show Gist options
  • Save copremesis/0315432214a261a1f59de0595f093675 to your computer and use it in GitHub Desktop.
Save copremesis/0315432214a261a1f59de0595f093675 to your computer and use it in GitHub Desktop.
Ember Starter Template

Ember Starter Template

Starter template which includes libraries for bootstrap (Yeti theme), ember.js + ember-data

A Pen by Curt Husting on CodePen.

License.

<script type="text/x-handlebars" data-template-name="application">
{{render 'navigation'}}
<div class="container">
<h1>ember.js + bootstrap starter template</h1>
<h4>Includes bootstrap (Yeti theme), fontAwesome, ember.js + ember-data</h4>
{{outlet}}
</div>
{{outlet 'modal'}}
</script>
<script type="text/x-handlebars" data-template-name="about">
<div class="container">
<h1>About route</h1>
</div>
</script>
<script type="text/x-handlebars" data-template-name="navigation">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
{{#linkTo 'index' class="navbar-brand"}}Home{{/linkTo}}
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li>{{#linkTo 'about'}}About{{/linkTo}}</li>
<li>{{#linkTo 'inview'}}In View{{/linkTo}}</li>
<li>{{#linkTo 'calendar'}}Calendar{{/linkTo}}</li>
<li>{{#linkTo 'infinite'}}Infinite Scroll{{/linkTo}}</li>
<li>{{#linkTo 'scroll'}}Scroll{{/linkTo}}</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">Modals <span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li>
<a href="#" class="navbar-link" {{action 'showModal' 'settings-modal' model}}>Settings</a>
</li>
<!--<li class="divider"></li>-->
<li>
<a href="#" class="navbar-link" {{action 'showModal' 'logout-modal'}}>Logout</a>
</li>
</ul>
</li>
</ul>
</div>
</nav>
</script>
<script type="text/x-handlebars" data-template-name="settings-modal">
{{#my-modal title='Settings' ok='save' close='removeModal'}}
<form {{action 'ok' on='submit' target=view}}>
<div class="form-group">
<label>Name</label>
{{input class="form-control" value=name}}
</div>
</form>
{{/my-modal}}
</script>
<script type="text/x-handlebars" data-template-name="logout-modal">
{{#my-modal title='Logout' ok='logout' close='removeModal'}}
Are you sure you want to logout?
{{/my-modal}}
</script>
<script type="text/x-handlebars" data-template-name="components/my-modal">
<div class="modal fade">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title">{{title}}</h4>
</div>
<div class="modal-body">
{{yield}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" {{action 'ok'}}>OK</button>
</div>
</div>
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="inview">
<div class="container">
<div class="row">
{{#each item in model}}
<div class="col-sm-12">
{{this-is-dog item=item}}
</div>
{{/each}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="components/this-is-dog">
<header><h2>{{item}} ~ {{enteredViewport}}</h2></header>
{{#if enteredViewport}}
<article>
<blockquote class="dog-card-description">Shinier than yours, meatbag. Tell them I hate them. Meh. My fellow Earthicans, as I have explained in my book 'Earth in the Balance, and the much more popular 'Harry Potter and the Balance of Earth', we need to defend our planet against pollution. Also dark wizards. Stop! Don't shoot fire stick in space canoe! Cause explosive decompression!
</blockquote>
</article>
{{/if}}
</script>
<script type="text/x-handlebars" data-template-name="calendar">
{{ui-calendar
selectedDates=emberConfDates
showNextMonth=false
showPrevMonth=false
select="dateSelected"}}
<ol>
{{#each day in emberConfDates}}
<li>{{format-date date=day format="dddd, MMMM Do, YYYY"}}</li>
{{/each}}
</ol>
</script>
<script data-template-name="infinite" type="text/x-handlebars">
<h2>Widgets (Page {{page}}: {{content.length}} total widgets)</h2>
<ul class=infinite>
{{#each widget in controller}}
<li>Widget: {{widget.name}}</li>
{{/each}}
</ul>
{{#if loadingMore}}
Loading more...
{{else}}
<a href='#' {{action 'getMore'}}>Get More...</a>
{{/if}}
</script>
<script type="text/x-handlebars" data-template-name="scroll">
{{cloaked-collection itemViewClass="item" content=model}}
</script>
<script type="text/x-handlebars" data-template-name="item">
<div {{action "greeting"}}>
#{{id}} ({{height}}px)
</div>
</script>
/* App
=============================*/
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Store = DS.Store.extend({
adapter: DS.FixtureAdapter.create()
});
/* Router
=============================*/
App.Router.map(function() {
this.route("about", { path: "/about" });
this.route("inview", { path: "/inview" });
this.route("calendar", { path: "/calendar" });
this.route("infinite", { path: "/infinite" });
this.route("scroll", { path: "/scroll" });
});
/* Routes
=============================*/
App.IndexRoute = Ember.Route.extend({
model: function() {
return Ember.Object.create({ name: 'My name' });
}
});
App.ApplicationRoute = Ember.Route.extend({
actions: {
showModal: function(name, model) {
this.render(name, {
into: 'application',
outlet: 'modal',
model: model
});
},
removeModal: function() {
this.disconnectOutlet({
outlet: 'modal',
parentView: 'application'
});
}
}
});
App.InviewRoute = Ember.Route.extend({
model: function() {
return ['Shiba Inu', 'Siberian Husky', 'Labrador', 'Golden Retriever', 'Malamute', 'Pomeranian', 'Doberman'];
}
});
App.CalendarRoute = Em.Route.extend({
setupController: function(controller) {
controller.set('emberConfDates', [
/*moment('2014-03-25'),
moment('2014-03-26')*/
]);
},
actions: {
dateSelected: function(date) {
/* console.log(this.get('dates'), 'dateSelected');
$('input[name="dateSelected]').val('date')*/
}
}
});
App.InfiniteRoute = Ember.Route.extend({
model: function(){
var items = Em.A([]);
for (var i = 0; i < 10; i++) {
items.pushObject({name: ''+i});
}
return items;
},
actions: {
getMore: function() {
var controller = this.get('controller'),
nextPage = controller.get('page') + 1,
perPage = controller.get('perPage'),
items;
items = this.send('fetchPage', nextPage, perPage);
console.log(items, 'items')
// add delay to simulate API latency
Ember.run.later(function(){
// alert the controller to the new data
controller.gotMore(items, nextPage);
}, 1000);
},
// load another page's worth of fake widgets
fetchPage: function(page, perPage) {
var items = Em.A([]);
console.log(items, 'fetchPage')
var firstIndex = (page-1) * perPage;
var lastIndex = page * perPage;
for (var i = firstIndex; i < lastIndex; i++) {
items.pushObject({name:''+i});
}
return items;
}
}
});
/* Models
=============================*/
/* Views
=============================*/
App.InfiniteView = Ember.View.extend({
didInsertElement: function(){
// we want to make sure 'this' inside `didScroll` refers
// to the IndexView, so we use jquery's `proxy` method to bind it
$(window).on('scroll', $.proxy(this.didScroll, this));
},
willDestroyElement: function(){
// have to use the same argument to `off` that we did to `on`
$(window).off('scroll', $.proxy(this.didScroll, this));
},
// this is called every time we scroll
didScroll: function(){
if (this.isScrolledToBottom()) {
this.get('controller').send('getMore');
}
},
// we check if we are at the bottom of the page
isScrolledToBottom: function(){
var distanceToViewportTop = (
$(document).height() - $(window).height());
var viewPortTop = $(document).scrollTop();
if (viewPortTop === 0) {
// if we are at the top of the page, don't do
// the infinite scroll thing
return false;
}
return (viewPortTop - distanceToViewportTop === 0);
}
});
/*rerenderObserver:function(){
this.rerender();
}.observes('controller.content')*/
/* Controllers =============================*/
App.SettingsModalController = Ember.ObjectController.extend({
actions: {
save: function() {
// save to server
console.log('settings saved');
}
}
});
App.LogoutModalController = Ember.Controller.extend({
actions: {
logout: function() {
// logout
console.log('logout triggered');
}
}
});
App.InfiniteController = Ember.ArrayController.extend({
// add properties
page: 1,
perPage: 10,
getMore: function() {
// don't load new data if we already are
if (this.get('loadingMore')) return;
this.set('loadingMore', true);
// pass this action up the chain to the events hash on the route
this.get('target').send('getMore');
},
// Also add a method `gotMore` that the route can call back to
// notify the controller that the new data is in and it can stop
// showing its loading indicator
gotMore: function(items, page) {
this.set('loadingMore', false);
this.set('page', page);
this.pushObjects(items);
}
});
/* Components =============================*/
App.MyModalComponent = Ember.Component.extend({
actions: {
ok: function() {
this.$('.modal').modal('hide');
this.sendAction('ok');
}
},
show: function() {
this.$('.modal').modal().on('hidden.bs.modal', function() {
this.sendAction('close');
}.bind(this));
}.on('didInsertElement')
});
App.ThisIsDogComponent = Ember.Component.extend(App.InViewportMixin, {
classNames: ['dog-card'],
classNameBindings: ['enteredViewport:entered-viewport']
});
App.FormatDateComponent = Em.Component.extend({
layout: Em.Handlebars.compile('{{formatted}}'),
date: null,
format: null,
formatted: function() {
var date = this.get('date');
var format = this.get('format');
return date ? date.format(format) : null;
}.property('date', 'format')
});
/* Mixins =============================*/
App.InViewportMixin = Ember.Mixin.create({
scrollTimeout: 100,
boundingClientRect: 0,
windowHeight: 0,
windowWidth: 0,
enteredViewport: Em.computed('boundingClientRect', 'windowHeight', 'windowWidth', function() {
var rect, windowHeight, windowWidth;
rect = this.get('boundingClientRect');
windowHeight = this.get('windowHeight');
windowWidth = this.get('windowWidth');
console.log(rect, 'rect')
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= windowHeight &&
rect.right <= windowWidth
);
}),
exitedViewport: Em.computed.not('enteredViewport'),
_updateBoundingClientRect: function() {
var el;
el = this.$()[0];
this.set('boundingClientRect', el.getBoundingClientRect());
},
_setup: (function() {
console.log('setup')
return Em.run.scheduleOnce('afterRender', this, function() {
this._updateBoundingClientRect();
this.set('windowHeight', window.innerHeight || document.documentElement.clientHeight);
this.set('windowWidth', window.innerWidth || document.documentElement.clientWidth);
});
}).on('didInsertElement'),
_scrollHandler: function() {
return Em.run.debounce(this, '_updateBoundingClientRect', this.get('scrollTimeout'));
},
_bindScroll: (function() {
console.log('scroll')
var scrollHandler;
scrollHandler = this._scrollHandler.bind(this);
Ember.$(document).on('touchmove.scrollable', scrollHandler);
Ember.$(window).on('scroll.scrollable', scrollHandler);
}).on('didInsertElement'),
_unbindScroll: (function() {
Ember.$(window).off('.scrollable');
Ember.$(document).off('.scrollable');
}).on('willDestroyElement')
});
$(function() {
// Check to see if the window is running in app mode.
if (("standalone" in window.navigator) && window.navigator.standalone) {
$('.navbar-fixed-top').css({
paddingTop:'12px'
});
}
})
// Cloaked Collection
random_height = function() {
return Math.round(Math.random() * 100 + 20);
};
model = (function() {
var _i, _results;
_results = [];
for (i = _i = 0; _i <= 500; i = ++_i) {
_results.push({
id: i,
height: random_height()
});
}
return _results;
})();
App.ScrollRoute = Ember.Route.extend({
model: function() {
return model;
},
actions: {
greeting: function() {
return alert('greeting from route');
}
}
});
App.ScrollView = Em.View.extend({
templateName: 'scroll'
});
App.ItemView = Em.View.extend({
templateName: 'item',
didInsertElement: function() {
return this.$().css('height', this.get('context.height'));
}
});
/**
Display a list of cloaked items
@class CloakedCollectionView
@extends Ember.CollectionView
@namespace Ember
**/
Ember.CloakedCollectionView = Ember.CollectionView.extend({
cloakView: Ember.computed.alias('itemViewClass'),
topVisible: null,
bottomVisible: null,
offsetFixedTopElement: null,
offsetFixedBottomElement: null,
loadingHTML: 'Loading...',
scrollDebounce: 10,
init: function() {
var cloakView = this.get('cloakView'),
idProperty = this.get('idProperty'),
uncloakDefault = !!this.get('uncloakDefault');
// Set the slack ratio differently to allow for more or less slack in preloading
var slackRatio = parseFloat(this.get('slackRatio'));
if (!slackRatio) { this.set('slackRatio', 1.0); }
this.set('itemViewClass', Ember.CloakedView.extend({
classNames: [cloakView + '-cloak'],
cloaks: cloakView,
preservesContext: this.get('preservesContext') === 'true',
cloaksController: this.get('itemController'),
defaultHeight: this.get('defaultHeight'),
init: function() {
this._super();
if (idProperty) {
this.set('elementId', cloakView + '-cloak-' + this.get('content.' + idProperty));
}
if (uncloakDefault) {
this.uncloak();
} else {
this.cloak();
}
}
}));
this._super();
Ember.run.next(this, 'scrolled');
},
/**
If the topmost visible view changed, we will notify the controller if it has an appropriate hook.
@method _topVisibleChanged
@observes topVisible
**/
_topVisibleChanged: function() {
var controller = this.get('controller');
if (controller.topVisibleChanged) { controller.topVisibleChanged(this.get('topVisible')); }
}.observes('topVisible'),
/**
If the bottommost visible view changed, we will notify the controller if it has an appropriate hook.
@method _bottomVisible
@observes bottomVisible
**/
_bottomVisible: function() {
var controller = this.get('controller');
if (controller.bottomVisibleChanged) { controller.bottomVisibleChanged(this.get('bottomVisible')); }
}.observes('bottomVisible'),
/**
Binary search for finding the topmost view on screen.
@method findTopView
@param {Array} childViews the childViews to search through
@param {Number} windowTop The top of the viewport to search against
@param {Number} min The minimum index to search through of the child views
@param {Number} max The max index to search through of the child views
@returns {Number} the index into childViews of the topmost view
**/
findTopView: function(childViews, viewportTop, min, max) {
if (max < min) { return min; }
var wrapperTop = this.get('wrapperTop')>>0;
while(max>min){
var mid = Math.floor((min + max) / 2),
// in case of not full-window scrolling
$view = childViews[mid].$(),
viewBottom = $view.position().top + wrapperTop + $view.height();
if (viewBottom > viewportTop) {
max = mid-1;
} else {
min = mid+1;
}
}
return min;
},
/**
Determine what views are onscreen and cloak/uncloak them as necessary.
@method scrolled
**/
scrolled: function() {
if (!this.get('scrollingEnabled')) { return; }
var childViews = this.get('childViews');
if ((!childViews) || (childViews.length === 0)) { return; }
var self = this,
toUncloak = [],
onscreen = [],
onscreenCloaks = [],
// calculating viewport edges
$w = Ember.$(window),
windowHeight = this.get('wrapperHeight') || ( window.innerHeight ? window.innerHeight : $w.height() ),
windowTop = this.get('wrapperTop') || $w.scrollTop(),
slack = Math.round(windowHeight * this.get('slackRatio')),
viewportTop = windowTop - slack,
windowBottom = windowTop + windowHeight,
viewportBottom = windowBottom + slack,
topView = this.findTopView(childViews, viewportTop, 0, childViews.length-1),
bodyHeight = this.get('wrapperHeight') ? this.$().height() : $('body').height(),
bottomView = topView,
offsetFixedTopElement = this.get('offsetFixedTopElement'),
offsetFixedBottomElement = this.get('offsetFixedBottomElement');
if (windowBottom > bodyHeight) { windowBottom = bodyHeight; }
if (viewportBottom > bodyHeight) { viewportBottom = bodyHeight; }
if (offsetFixedTopElement) {
windowTop += (offsetFixedTopElement.outerHeight(true) || 0);
}
if (offsetFixedBottomElement) {
windowBottom -= (offsetFixedBottomElement.outerHeight(true) || 0);
}
// Find the bottom view and what's onscreen
while (bottomView < childViews.length) {
var view = childViews[bottomView],
$view = view.$(),
// in case of not full-window scrolling
scrollOffset = this.get('wrapperTop') || 0,
viewTop = $view.offset().top + scrollOffset,
viewBottom = viewTop + $view.height();
if (viewTop > viewportBottom) { break; }
toUncloak.push(view);
if (viewBottom > windowTop && viewTop <= windowBottom) {
onscreen.push(view.get('content'));
onscreenCloaks.push(view);
}
bottomView++;
}
if (bottomView >= childViews.length) { bottomView = childViews.length - 1; }
// If our controller has a `sawObjects` method, pass the on screen objects to it.
var controller = this.get('controller');
if (onscreen.length) {
this.setProperties({topVisible: onscreen[0], bottomVisible: onscreen[onscreen.length-1]});
if (controller && controller.sawObjects) {
Em.run.schedule('afterRender', function() {
controller.sawObjects(onscreen);
});
}
} else {
this.setProperties({topVisible: null, bottomVisible: null});
}
var toCloak = childViews.slice(0, topView).concat(childViews.slice(bottomView+1));
this._uncloak = toUncloak;
if(this._nextUncloak){
Em.run.cancel(this._nextUncloak);
this._nextUncloak = null;
}
Em.run.schedule('afterRender', this, function() {
onscreenCloaks.forEach(function (v) {
if(v && v.uncloak) {
v.uncloak();
}
});
toCloak.forEach(function (v) { v.cloak(); });
if (self._nextUncloak) { Em.run.cancel(self._nextUncloak); }
self._nextUncloak = Em.run.later(self, self.uncloakQueue,50);
});
for (var j=bottomView; j<childViews.length; j++) {
var checkView = childViews[j];
if (!checkView._containedView) {
if (!checkView.get('loading')) {
checkView.$().html(this.get('loadingHTML'));
}
return;
}
}
},
uncloakQueue: function(){
var maxPerRun = 3, delay = 50, processed = 0, self = this;
if(this._uncloak){
while(processed < maxPerRun && this._uncloak.length>0){
var view = this._uncloak.shift();
if(view && view.uncloak && !view._containedView){
Em.run.schedule('afterRender', view, view.uncloak);
processed++;
}
}
if(this._uncloak.length === 0){
this._uncloak = null;
} else {
Em.run.schedule('afterRender', self, function(){
if(self._nextUncloak){
Em.run.cancel(self._nextUncloak);
}
self._nextUncloak = Em.run.next(self, function(){
if(self._nextUncloak){
Em.run.cancel(self._nextUncloak);
}
self._nextUncloak = Em.run.later(self,self.uncloakQueue,delay);
});
});
}
}
},
scrollTriggered: function() {
Em.run.scheduleOnce('afterRender', this, 'scrolled');
},
_startEvents: function() {
if (this.get('offsetFixed')) {
Em.warn("Cloaked-collection's `offsetFixed` is deprecated. Use `offsetFixedTop` instead.");
}
var self = this,
offsetFixedTop = this.get('offsetFixedTop') || this.get('offsetFixed'),
offsetFixedBottom = this.get('offsetFixedBottom'),
scrollDebounce = this.get('scrollDebounce'),
onScrollMethod = function() {
Ember.run.debounce(self, 'scrollTriggered', scrollDebounce);
};
if (offsetFixedTop) {
this.set('offsetFixedTopElement', Ember.$(offsetFixedTop));
}
if (offsetFixedBottom) {
this.set('offsetFixedBottomElement', Ember.$(offsetFixedBottom));
}
Ember.$(document).bind('touchmove.ember-cloak', onScrollMethod);
Ember.$(window).bind('scroll.ember-cloak', onScrollMethod);
this.addObserver('wrapperTop', self, onScrollMethod);
this.addObserver('wrapperHeight', self, onScrollMethod);
this.addObserver('content.@each', self, onScrollMethod);
this.scrollTriggered();
this.set('scrollingEnabled', true);
}.on('didInsertElement'),
cleanUp: function() {
Ember.$(document).unbind('touchmove.ember-cloak');
Ember.$(window).unbind('scroll.ember-cloak');
this.set('scrollingEnabled', false);
},
_endEvents: function() {
this.cleanUp();
}.on('willDestroyElement')
});
/**
A cloaked view is one that removes its content when scrolled off the screen
@class CloakedView
@extends Ember.View
@namespace Ember
**/
Ember.CloakedView = Ember.View.extend({
attributeBindings: ['style'],
_containedView: null,
_scheduled: null,
init: function() {
this._super();
this._scheduled = false;
this._childViews = [];
},
setContainedView: function(cv) {
if (this._childViews[0]) {
this._childViews[0].destroy();
this._childViews[0] = cv;
}
if (cv) {
cv.set('_parentView', this);
cv.set('templateData', this.get('templateData'));
this._childViews[0] = cv;
} else {
this._childViews.clear();
}
if (this._scheduled) return;
this._scheduled = true;
this.set('_containedView', cv);
Ember.run.schedule('render', this, this.updateChildView);
},
render: function (buffer) {
var el = buffer.element();
this._childViewsMorph = buffer.dom.createMorph(el, null, null, el);
},
updateChildView: function () {
this._scheduled = false;
if (!this._elementCreated || this.isDestroying || this.isDestroyed) { return; }
var childView = this._containedView;
if (childView && !childView._elementCreated) {
this._renderer.renderTree(childView, this, 0);
}
},
/**
Triggers the set up for rendering a view that is cloaked.
@method uncloak
*/
uncloak: function() {
var state = this._state || this.state;
if (state !== 'inDOM' && state !== 'preRender') { return; }
if (!this._containedView) {
var model = this.get('content'),
controller = null,
container = this.get('container');
// Wire up the itemController if necessary
var controllerName = this.get('cloaksController');
if (controllerName) {
var controllerFullName = 'controller:' + controllerName,
factory = container.lookupFactory(controllerFullName),
parentController = this.get('controller');
// let ember generate controller if needed
if (factory === undefined) {
factory = Ember.generateControllerFactory(container, controllerName, model);
// inform developer about typo
Ember.Logger.warn('ember-cloaking: can\'t lookup controller by name "' + controllerFullName + '".');
Ember.Logger.warn('ember-cloaking: using ' + factory.toString() + '.');
}
controller = factory.create({
model: model,
parentController: parentController,
target: parentController
});
}
var createArgs = {},
target = controller || model;
if (this.get('preservesContext')) {
createArgs.content = target;
} else {
createArgs.context = target;
}
if (controller) { createArgs.controller = controller; }
this.setProperties({
style: null,
loading: false
});
this.setContainedView(this.createChildView(this.get('cloaks'), createArgs));
}
},
/**
Removes the view from the DOM and tears down all observers.
@method cloak
*/
cloak: function() {
var self = this;
if (this._containedView && (this._state || this.state) === 'inDOM') {
var style = 'height: ' + this.$().height() + 'px;';
this.set('style', style);
this.$().prop('style', style);
// We need to remove the container after the height of the element has taken
// effect.
Ember.run.schedule('afterRender', function() {
self.setContainedView(null);
});
}
},
_setHeights: function(){
if (!this._containedView) {
// setting default height
// but do not touch if height already defined
if(!this.$().height()){
var defaultHeight = 100;
if(this.get('defaultHeight')) {
defaultHeight = this.get('defaultHeight');
}
this.$().css('height', defaultHeight);
}
}
}.on('didInsertElement')
});
Ember.Handlebars.registerHelper('cloaked-collection', function(options) {
var hash = options.hash,
types = options.hashTypes;
for (var prop in hash) {
if (types[prop] === 'ID') {
hash[prop + 'Binding'] = hash[prop];
delete hash[prop];
}
}
return Ember.Handlebars.helpers.view.call(this, Ember.CloakedCollectionView, options);
});
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.9.1/ember.prod.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.0.0-beta.14.1/ember-data.prod.js"></script>
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script>
<script src="https://s3.amazonaws.com/heycarsten/ember-ui-calendar-0.1.1.js"></script>
@import "compass/css3";
body { padding-top: 70px; }
.modal-dialog { margin: 90px auto; }
@import "compass";
// Cool
$aqua: #7FDBFF;
$blue: #0074D9;
$navy: #001F3F;
$teal: #39CCCC;
$green: #2ECC40;
$olive: #3D9970;
$lime: #01FF70;
// Warm
$yellow: #FFDC00;
$orange: #FF851B;
$red: #FF4136;
$fuchsia: #F012BE;
$purple: #B10DC9;
$maroon: #85144B;
// Gray Scale
$white: #fff;
$silver: #ddd;
$gray: #aaa;
$black: #111;
h1.title {
font-size: 2.5em;
}
.dog-card {
@include transition(all 0.25s ease-out);
@include border-radius(5px);
border: 3px solid $silver;
min-height: 400px;
background: darken($white, 3%);
margin-bottom: 2em;
padding: 5px 20px;
header {
color: $gray;
}
}
.dog-card-description {
color: $gray;
font-size: 1.25em;
}
.entered-viewport {
background: $white;
border-color: lighten($green, 20%);
header {
@include transition(all 0.1s ease-out);
color: $black;
}
&:hover {
border-color: $green;
}
}
.ui-calendar {
width: 200px;
font-size: 14px;
background: #fff; }
.ui-calendar-months:after {
content: "";
display: table;
clear: both; }
.ui-calendar-month-container {
width: 100%;
float: left;
margin: 0;
padding: 0;
margin-top: 30px;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none; }
.ui-calendar-month {
margin: 0;
padding: 3px; }
.ui-calendar-month:last-child {
padding-right: 0;
}
.ui-calendar-header {
position: relative;
line-height: 22px; }
.ui-calendar-header h1 {
font-size: 14px;
text-align: center; }
.ui-calendar-header button {
position: absolute;
top: 0; }
.ui-calendar-prev {
left: 0; }
.ui-calendar-next {
right: 0; }
.ui-calendar-today {
left: 50%;
margin-left: -28px; }
.ui-calendar-slot {
float: left;
list-style: none;
text-align: center;
line-height: 30px;
padding: 0;
margin: 0;
width: 14.28%;
height: 30px;
border: 1px solid #eee;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box; }
.ui-calendar-slot.is-today {
background: #edc; }
.ui-calendar-slot.is-selected {
background: #cde; }
.ui-calendar-slot.is-disabled {
background: #eee;
color: #999;
cursor: default; }
.ui-calendar-day {
background: #fff;
cursor: pointer; }
.ui-calendar-empty {
cursor: default;
background: #eee; }
p { width: 50%; }
ul.infinite { list-style-type: none; padding:0; margin:0; }
.infinite li {
background-color: #CCC;
height: 100px;
line-height: 100px;
width: 300px;
text-align: center;
margin-bottom: 10px;
}
.ember-view {
-webkit-animation: debug .5s;
}
@-webkit-keyframes debug {
0% {
background-color: yellow;
}
100% {
background-color: inherit;
}
}
<link href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.2/yeti/bootstrap.min.css" rel="stylesheet" />
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment