UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

120 lines (108 loc) 2.73 kB
<div id="demo"> <div id='out'></div> <script id="app" type="text/stache"> <accordion> <panel title="Contacts"> <button>Change title attribute to "Users"</button> <ul> <li>Justin</li> <li>Brian</li> </ul> </panel> <panel title="Libraries"> <ul> <li>CanJS</li> <li>JavaScriptMVC</li> </ul> </panel> </accordion> </script> </div> <script src="../../node_modules/steal/steal.js" main="@empty"> var Component = require("can-component"); var stache = require("can-stache"); var DefineMap = require("can-define/map/map"); var DefineList = require("can-define/list/list"); var canViewModel = require("can-view-model"); var Panel = DefineMap.extend({ active: "boolean" }); var AccordionViewModel = DefineMap.extend({ active: Panel, // Contains a list of all panel scopes within the // tabs element. panels: { Value: DefineList }, // When a `<panel>` element is inserted into the document, // it calls this method to add the panel's scope to the // panels array. addPanel: function(panel){ // If this is the first panel, activate it. if( this.panels.length === 0 ) { this.makeActive(panel) } this.panels.push(panel); }, // When a `<panel>` element is removed from the document, // it calls this method to remove the panel's scope from // the panels array. removePanel: function(panel){ var panels = this.panels; panels.splice(panels.indexOf(panel),1); // if the panel was active, make the first item active if(panel === this.active){ if(panels.length){ this.makeActive(panels[0]); } else { this.active = undefined; } } }, makeActive: function(panel){ this.active = panel; this.panels.forEach(function(panel){ panel.active = false; }); panel.active = true; } }); Component.extend({ tag: "accordion", ViewModel: AccordionViewModel, leakScope: true }); Component.extend({ view: stache("<h2 ($click)='makeActive(.)'>{{title}}</h2>"+ "{{#if ./active}}<content></content>{{/if}}"), tag:"panel", ViewModel: { active: "boolean" }, events: { inserted: function(){ var vm = this.parentViewModel = canViewModel(this.element.parentNode); vm.addPanel(this.viewModel); }, removed: function(){ this.parentViewModel.removePanel(this.viewModel); } }, leakScope: true }); var out = document.getElementById("out"); var template = stache(document.getElementById("app").innerHTML); out.appendChild(template({})); out.addEventListener("click", function(ev){ var el = ev.target; var parent = el.parentNode; if(el.nodeName === "BUTTON") { parent.setAttribute("title", "Users"); } }); window.canViewModel = canViewModel; </script> <script> DEMO_HTML = document.getElementById("demo").innerHTML </script>