Skip to content

Instantly share code, notes, and snippets.

@nightire
Last active July 30, 2016 23:01
Show Gist options
  • Save nightire/207cf8567aa6b3fdd62212249863034f to your computer and use it in GitHub Desktop.
Save nightire/207cf8567aa6b3fdd62212249863034f to your computer and use it in GitHub Desktop.
Ember Simple Accordion
import Ember from 'ember';
const AccordionItemState = Ember.Object.extend({
id: null,
active: false,
inactive: Ember.computed.not('active')
});
const AccordionItemComponent = Ember.Component.extend({
init() {
this._super(...arguments);
this.set('state', AccordionItemState.create({
id: this.getWithDefault('index', this.elementId),
active: this.getWithDefault('active', false)
}));
this.get('registry').pushObject(this.get('state'));
}
});
AccordionItemComponent.reopenClass({
positionalParams: ['registry', 'item', 'index']
});
export default AccordionItemComponent;
import Ember from 'ember';
const AccordionListComponent = Ember.Component.extend({
registry: Ember.A([]),
/**
* allow to open multiple items at the same time
*/
coexist: true,
/**
* opposite to `coexist`
* @private
*/
monopoly: Ember.computed.not('coexist'),
/**
* ensure to keep at least one item being openned
*/
preserve: true,
actions: {
open(id, event) {
event.stopImmediatePropagation();
const item = this.get('registry').findBy('id', id);
if (this.get('monopoly')) {
this.get('registry').setEach('active', false);
if (this.get('preserve')) {
return item.setProperties({'active': true, 'inactive': true});
}
}
item.set('active', true);
},
close(id, event) {
event.stopImmediatePropagation();
this.get('registry').findBy('id', id).set('active', false);
},
toggle(id, event) {
event.stopImmediatePropagation();
const item = this.get('registry').findBy('id', id);
if (this.get('monopoly')) {
this.get('registry').rejectBy('id', id).setEach('active', false);
if (this.get('preserve')) {
return item.setProperties({'active': true, 'inactive': true});
}
}
item.toggleProperty('active');
}
}
});
AccordionListComponent.reopenClass({
positionalParams: ['list']
});
export default AccordionListComponent;
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Ember Simple Accordion'
});
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return Ember.RSVP.resolve([{
title: 'c79fdbdbf1959664d1e0f1b99f0fb2af74762b2d',
content: 'Nam id tempus dolor, ut malesuada velit. In ex velit, suscipit a interdum vel, interdum et sapien. Suspendisse ac diam rutrum, euismod purus vitae, iaculis justo. Ut vel ornare urna. Donec accumsan ornare dolor, et feugiat ipsum. Donec consequat sodales pretium. Fusce eleifend orci imperdiet vehicula mattis. Vestibulum magna quam, dapibus nec congue a, semper in orci. Ut eget ante quis lacus volutpat consectetur eu nec est. Integer at ante nec neque pulvinar vulputate. Pellentesque tempor ex at ante dictum, quis scelerisque orci lacinia.'
}, {
title: '42ad3872683671267dfbd7f63d2b18015b6060be',
content: 'Phasellus at arcu a ipsum aliquet posuere non sit amet nibh. Duis volutpat, urna a tincidunt consectetur, ante magna efficitur sapien, nec sollicitudin felis lacus vitae mi. Morbi eleifend elit eget consectetur luctus. Proin a purus a urna varius accumsan. Curabitur fermentum, massa ac porta condimentum, tortor quam semper magna, sed laoreet velit tellus eget quam. Donec et dui ut nulla viverra congue tempus vitae nunc. Suspendisse sed sem consectetur, pharetra dolor ac, iaculis libero. Nunc ut est felis.'
}, {
title: '3de275b9861b662b0c3577dd0f2d9126d66e5ca3',
content: 'In urna lacus, consectetur eu suscipit id, sodales in sapien. Nulla ultrices malesuada ipsum hendrerit blandit. Vestibulum a pulvinar ligula, quis blandit lacus. Donec commodo, ligula ac aliquam consectetur, velit est congue odio, at tristique tellus nulla sed ligula. Sed viverra facilisis nisi sit amet congue. Praesent commodo odio sed fringilla hendrerit. Quisque sed massa et ligula dignissim volutpat.'
}]);
}
});
body {
margin: 12px 16px;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12pt;
}
.accordion-list {
width: 80vw;
margin: 0 auto;
}
<h1>{{appName}}</h1>
<hr />
{{#accordion-list coexist=true preserve=true class="accordion-list" as |accordion|}}
{{#accordion.item as |item state|}}
<h3 onclick={{action accordion.toggle}}>
{{item.title}}
<button disabled={{state.active}}
onclick={{action accordion.open state.id}}>Open</button>
</h3>
{{#if state.active}}
<p>
{{item.content}}
<button disabled={{state.inactive}}
onclick={{action accordion.close state.id}}>Close</button>
</p>
{{/if}}
{{/accordion.item}}
{{/accordion-list}}
{{outlet}}
{{#if list}}
{{#each list as |item index|}}
{{yield (hash
item=(component "accordion-item" registry item index)
open=(action "open" index)
close=(action "close" index)
toggle=(action "toggle" index)
)}}
{{/each}}
{{else}}
{{yield (hash
item=(component "accordion-item" registry item)
open=(action "open")
close=(action "close")
toggle=(action "toggle")
)}}
{{/if}}
{
"version": "0.10.2",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.7.0",
"ember-template-compiler": "2.7.0"
},
"addons": {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment