Reusable modals with Ember JS
This Fiddle demonstrates how to build reusable modals with Ember. With CSS transition in and out.
by jkneb
HTML
<script src="http://builds.emberjs.com/handlebars-1.0.0-rc.4.js"></script>
<script src="http://builds.emberjs.com/ember-1.0.0-rc.6.1.js"></script>
<script type="text/x-handlebars" id="index">
<button {{action showModal 'modal01'}}>show modal 01</button>
<button {{action showModal 'modal02'}}>show modal 02</button>
{{render modal01}}
{{render modal02}}
</script>
<script type="text/x-handlebars" id="modal_layout">
<button {{action "hideModal" target="view"}} class="modal-close">×</button>
<div class="modal-body">
{{yield}}
</div>
</script>
<script type="text/x-handlebars" id="modal01">
{{#view App.ModalView}}
<p>modal01 content ooh yeah</p>
{{/view}}
</script>
<script type="text/x-handlebars" id="modal02">
{{#view App.ModalView}}
<p>modal02 content omg</p>
{{/view}}
</script>
SCSS
@mixin transition($params){
-webkit-transition:#{$params};
-moz-transition:#{$params};
-ms-transition:#{$params};
transition:#{$params};
}
/* reveal logic for the modal
*/
.modal {
/* v + h centering */
position:absolute; margin:auto;
top:0; bottom:0; left:0; right:0;
&.shown {
opacity:1;
@include transition( top 0ms linear 0ms,
opacity 300ms ease 10ms );
}
&.hidden {
opacity:0; top:-200%;
@include transition( opacity 300ms ease 0ms,
top 0ms linear 900ms );
}
}
/* ----------------------------------- */
/* styles for the purpose of this demo */
.modal {
width:250px; height:180px;
padding:25px;
background:white;
border:1px solid #ddd; border-radius:4px;
box-shadow:5px 5px 12px rgba(0,0,0,.1);
}
button {
border:1px solid #ccc;
border-radius:3px; padding:4px 10px;
font-size:12px; cursor:pointer;
background:#f1f1f1;
&:hover {
background:#3ab6da;
color:white; border-color:#3ab6da;
}
}
.modal-close {
position:absolute; top:5px; right:5px;
}
body { padding:25px;
background:#f9f9f9;
font-family:'Helvetica Neue', Arial;
font-size:12px;
}
* {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
-ms-box-sizing:border-box;
box-sizing:border-box;
}
JavaScript
window.App = Em.Application.create();
App.ApplicationRoute = Em.Route.extend({
events: {
showModal: function(name){
this.controllerFor(name).set('modalVisible', true);
}
}
});
App.ModalView = Em.View.extend({
layoutName: 'modal_layout',
tagName: 'div',
classNames: ['modal', 'whatever'],
classNameBindings: ['controller.modalVisible:shown:hidden'],
hideModal: function(){
this.get('controller').set('modalVisible', false);
}
});