-
4 Dec 2006 11:18 AM #1
How to make and navigation menu like Jack's Blog
How to make and navigation menu like Jack's Blog
Hi guys, I'm quite new to this wonderfull user interface, and I got a question.
How can I make a navigation menu with stacked collapsible panels like the ones found in Jack's Blog at: Downloads ----> Build your own yui-ext.js (Tab).
I'm using the borderlayout, and when I try to add another panel it is created on a new tab.
Thx
-
4 Dec 2006 2:40 PM #2
He's using nested layouts, in a layoutDialog... A layoutDialog is nothing more than a BasicDialog who's body element has had a BorderLayout inserted into it. So you can take this and modify it to fit your BorderLayout.
Jacks Download Dialog
Code:showDialog : function(){ if(!dialog){ dialog = new YAHOO.ext.LayoutDialog("download-dlg", { modal: true, shim:true, width:600, height:450, shadow:true, minWidth:500, minHeight:350, autoTabs:true, autoScroll:false, center:{ tabPosition: 'top', alwaysShowTabs: true } }); dialog.addKeyListener(27, dialog.hide, dialog); dialog.setDefaultButton(dialog.addButton('Close', dialog.hide, dialog)); dlBtn = dialog.addButton('Build It!', this.getDownload, this); var innerLayout = new YAHOO.ext.BorderLayout('dl-inner', { east: { initialSize: 200, autoScroll:true, split:true }, center: { autoScroll:true } }); innerLayout.beginUpdate(); innerLayout.add('east', new YAHOO.ext.ContentPanel('dl-details')); innerLayout.add('center', new YAHOO.ext.ContentPanel('selection-panel')); innerLayout.endUpdate(true); var layout = dialog.getLayout(); dialog.beginUpdate(); var sp = layout.add('center', new YAHOO.ext.ContentPanel('standard-panel', {title: 'Download the Source', fitToFrame:true})); sp.on('activate', function(){ dlBtn.getEl().setStyle('display', 'none'); dlInfo.hide(); }); var p = layout.add('center', new YAHOO.ext.NestedLayoutPanel(innerLayout, {title: 'Build your own yui-ext.js'})); p.on('activate', function(){ dlBtn.getEl().setStyle('display', ''); dlInfo.show(); if(!detailTpl){ this.render(); } }, this, true); layout.getRegion('center').showPanel(sp); dialog.endUpdate(); } if(typeof Commentable != 'undefined' && Commentable.isOpen()){ Commentable.closeComment(); this.showDialog.defer(200, this); return; } dialog.show(showBtn.dom); },
-
4 Dec 2006 3:39 PM #3
If you are specifically asking about how to make the panels that expand and collapse, at the moment there is not a nice, packaged widget for this. However, the code to create it is pretty straight-forward. Here's a version I pulled out of Jack's source and have been playing with (note: it's not necessarily complete or working correctly at the moment, but it should point you in the right direction -- YMMV):
And then to use it you just do something like:Code:var Collapser = function(clickEl, collapseEl){ this.clickEl = getEl(clickEl); this.collapseEl = getEl(collapseEl); this.clickEl.addClass('accordion-expanded'); this.enabled = true; this.clickEl.mon('click', function(){ if (this.enabled) this.collapsed === true ? this.expand() : this.collapse(); }, this, true); }; Collapser.prototype = { collapse : function(){ this.collapseEl.clip(); this.collapseEl.setHeight(1, true, .35, this.afterCollapse.createDelegate(this), YAHOO.util.Easing.easeOut); }, afterCollapse : function(){ this.collapsed = true; this.collapseEl.setDisplayed(false); this.clickEl.replaceClass('accordion-expanded','accordion-collapsed'); }, expand : function(){ this.collapseEl.setDisplayed(true); this.collapseEl.autoHeight(true, .35, this.afterExpand.createDelegate(this), YAHOO.util.Easing.easeOut); }, afterExpand : function(){ this.collapsed = false; this.collapseEl.unclip(); this.collapseEl.setStyle('height', ''); this.clickEl.replaceClass('accordion-collapsed','accordion-expanded'); }, enable : function(){ this.enabled = true; this.clickEl.removeClass('disabled'); }, disable : function(){ this.enabled = false; this.collapse(); this.clickEl.addClass('disabled'); } };
Ultimately, it needs some more functionality and polish, and maybe I (or someone else) will eventually turn it into more of a component like the rest of Jack's stuffCode:<div id="head">My Box</div> <div id="body">Content goes here.</div> <script> var collapser = new Collapser('head', 'body'); collapser.expand(); </script>
Brian
-
6 Dec 2006 4:06 AM #4
Thanks guys, your tips were very useful to the project I'm working at.
And thanks for the quick answer too
-
8 Dec 2006 12:06 PM #5
Hi! I'm really a new newbie to this, but I've done some improvements to the Collapser posted above by Brian (bmoeskau). In particular, I added a state manager to it. I'm sure I could have done it in a better way, but my knowledged of YUI and YUI-ext is still limited. So, please, feel free to point out parts that could be improved.
Thanks!
Luis
Code:// Collapser var Collapser = function(collapsableContainer){ this.id = collapsableContainer.id; this.clickEl = getEl(YAHOO.util.Dom.getElementsByClassName('ycollapsable-menuhead', null, collapsableContainer)[0]); this.collapseEl = getEl(YAHOO.util.Dom.getElementsByClassName('ycollapsable-menucontent', null, collapsableContainer)[0]); this.clickEl.addClass('ycollapsable-expanded'); this.enabled = true; this.clickEl.mon('click', function(){ if (this.enabled) this.collapsed === true ? this.expand() : this.collapse(); }, this, true); this.events = { 'expanded' : new YAHOO.util.CustomEvent('expanded'), 'collapsed' : new YAHOO.util.CustomEvent('collapsed'), 'enabled' : new YAHOO.util.CustomEvent('enabled'), 'disabled' : new YAHOO.util.CustomEvent('disabled') }; }; YAHOO.extendX(Collapser, YAHOO.ext.util.Observable, { collapse : function(animate){ if (!this.collapsed) { this.collapseEl.clip(); if (animate == null || animate == true) { this.collapseEl.setHeight(1, true, .35, this.afterCollapse.createDelegate(this), YAHOO.util.Easing.easeOut); } else { this.collapseEl.setHeight(1); this.afterCollapse(); } } }, afterCollapse : function(){ this.collapsed = true; this.collapseEl.setDisplayed(false); this.clickEl.replaceClass('ycollapsable-expanded','ycollapsable-collapsed'); this.fireEvent('collapsed', this); }, expand : function(animate){ if (this.collapsed) { this.collapseEl.setDisplayed(true); if (animate == null || animate == true) { this.collapseEl.autoHeight(animate, .35, this.afterExpand.createDelegate(this), YAHOO.util.Easing.easeOut); } else { this.collapseEl.autoHeight(); this.afterExapand(); } } }, afterExpand : function(){ this.collapsed = false; this.collapseEl.unclip(); this.collapseEl.setStyle('height', ''); this.clickEl.replaceClass('ycollapsable-collapsed','ycollapsable-expanded'); this.fireEvent('expanded', this); }, enable : function(){ this.enabled = true; this.clickEl.removeClass('ycollapsable-disabled'); this.fireEvent('enabled', this); }, disable : function(){ this.enabled = false; this.collapse(); this.clickEl.addClass('ycollapsable-disabled'); this.fireEvent('disabled', this); }, restoreState : function(provider){ if(!provider){ provider = YAHOO.ext.state.Manager; } var sm = new CollapserStateManager(); sm.init(this, provider); } }); var CollapserStateManager = function(collapserObject, provider){ this.state = { collapsed: true, enabled: true }; }; CollapserStateManager.prototype = { init : function(collapser, provider){ this.provider = provider; var state = provider.get(collapser.id+'-collapser-state'); if(state){ if(state.collapsed){ collapser.collapse(false); } else { collapser.expand(false); } if(state.enabled == true){ collapser.enable(); }else{ collapser.disable(); } this.state = state; } this.collapser = collapser; collapser.on('collapsed', this.onCollapsed, this, true); collapser.on('expanded', this.onExpanded, this, true); collapser.on('enabled', this.onEnabled, this, true); collapser.on('disabled', this.onDisabled, this, true); }, storeState : function(){ this.provider.set(this.collapser.id+'-collapser-state', this.state); }, onCollapsed : function(){ this.state.collapsed = true; this.storeState(); }, onExpanded : function(){ this.state.collapsed = false; this.storeState(); }, onEnabled : function(){ this.state.enabled = true; this.storeState(); }, onDisabled : function(){ this.state.enabled = false; this.storeState(); } }; // //Usage example: // // // <div id="config-collapser" class="ycollapsable"> // <div class="ycollapsable-menuhead"> // <asp:Label ID="MenuHeader0" runat="server" Text="Configuração"></asp:Label> // </div> // <div class="ycollapsable-menucontent"> // <div> // <asp:LinkButton ID="UserAdmLinkPage" runat="server" Text="Gerenciamento de Usuário"></asp:LinkButton> // </div> // <div> // <asp:LinkButton ID="LinkButton1" runat="server" Text="Parâmetros"></asp:LinkButton> // </div> // </div> // </div> // // <div id="monitoring-collapser" class="ycollapsable"> // <div class="ycollapsable-menuhead"> // <asp:Label ID="Label1" runat="server" Text="Monitoring"></asp:Label> // </div> // <div class="ycollapsable-menucontent"> // <div> // <asp:LinkButton ID="LinkButton6" runat="server" Text="Diagnosticos"></asp:LinkButton> // </div> // <div> // <asp:LinkButton ID="LinkButton7" runat="server" Text="Modelos"></asp:LinkButton> // </div> // </div> // </div> // // <script> // // var collapsables = YAHOO.util.Dom.getElementsByClassName('ycollapsable') // // for (i in collapsables) { // var collapser = new Collapser(collapsables[i]); // collapser.restoreState(); // collapser.enable(); // } // // </script>
-
8 Dec 2006 3:38 PM #6
Hey Luis,
Nice job! I took your improvements one step further:
- Added a default cookie provider if none is specified since the StateManager doesn't do anything without a valid provider.
- Changed restoreState() to accept an optional defaultState parameter that gets used the first time through when there is no valid saved state.
- Added: containerEl = getEl(collapsableContainer); as the first line of the constructor so that you can simply pass in an id from the page (although passing an element will still work).
- Added functionality in the sample to demonstrate disabling/enabling a panel. Also made the sample html a little more generic, included the style defs, etc.
Let me know if you improve it even further
- Brian
New script (collapser.js):
New html:Code:// Collapser var Collapser = function(collapsableContainer){ containerEl = getEl(collapsableContainer); this.clickEl = getEl(YAHOO.util.Dom.getElementsByClassName('ycollapsable-menuhead', null, collapsableContainer)[0]); this.collapseEl = getEl(YAHOO.util.Dom.getElementsByClassName('ycollapsable-menucontent', null, collapsableContainer)[0]); this.clickEl.addClass('ycollapsable-expanded'); this.id = containerEl.id; this.enabled = true; this.collapsed = false; this.clickEl.mon('click', function(){ if (this.enabled) this.collapsed == true ? this.expand() : this.collapse(); }, this, true); this.events = { 'expanded' : new YAHOO.util.CustomEvent('expanded'), 'collapsed' : new YAHOO.util.CustomEvent('collapsed'), 'enabled' : new YAHOO.util.CustomEvent('enabled'), 'disabled' : new YAHOO.util.CustomEvent('disabled') }; }; YAHOO.extendX(Collapser, YAHOO.ext.util.Observable, { collapse : function(animate){ if (!this.collapsed) { this.collapseEl.clip(); if (animate == null || animate == true) { this.collapseEl.setHeight(1, true, .15, this.afterCollapse.createDelegate(this), YAHOO.util.Easing.easeIn); } else { this.collapseEl.setHeight(1); this.afterCollapse(); } } }, afterCollapse : function(){ this.collapsed = true; this.collapseEl.setDisplayed(false); this.clickEl.replaceClass('ycollapsable-expanded','ycollapsable-collapsed'); this.fireEvent('collapsed', this); }, expand : function(animate){ if (this.collapsed) { this.collapseEl.setDisplayed(true); if (animate == null || animate == true) { this.collapseEl.autoHeight(animate, .25, this.afterExpand.createDelegate(this), YAHOO.util.Easing.easeOut); } else { this.collapseEl.autoHeight(); this.afterExapand(); } } }, afterExpand : function(){ this.collapsed = false; this.collapseEl.unclip(); this.collapseEl.setStyle('height', ''); this.clickEl.replaceClass('ycollapsable-collapsed','ycollapsable-expanded'); this.fireEvent('expanded', this); }, enable : function(){ this.enabled = true; this.clickEl.removeClass('ycollapsable-disabled'); this.fireEvent('enabled', this); }, disable : function(animate){ this.enabled = false; this.collapse(animate); this.clickEl.addClass('ycollapsable-disabled'); this.fireEvent('disabled', this); }, restoreState : function(defaultState, provider){ if(!provider){ YAHOO.ext.state.Manager.setProvider(new YAHOO.ext.state.CookieProvider()); provider = YAHOO.ext.state.Manager; } var sm = new CollapserStateManager(); sm.init(this, provider, defaultState); } }); var CollapserStateManager = function(collapserObject, provider){ this.state = { collapsed: true, enabled: true }; }; CollapserStateManager.prototype = { init : function(collapser, provider, defaultState){ this.provider = provider; if (!defaultState) { defaultState = { enabled: true, collapsed: false }; } var savedState = provider.get(collapser.id+'-collapser-state'); this.state = savedState || defaultState; if(this.state.collapsed){ collapser.collapse(false); } else { collapser.expand(false); } if(this.state.enabled == true){ collapser.enable(); }else{ collapser.disable(); } this.collapser = collapser; collapser.on('collapsed', this.onCollapsed, this, true); collapser.on('expanded', this.onExpanded, this, true); collapser.on('enabled', this.onEnabled, this, true); collapser.on('disabled', this.onDisabled, this, true); }, storeState : function(){ this.provider.set(this.collapser.id+'-collapser-state', this.state); }, onCollapsed : function(){ this.state.collapsed = true; this.storeState(); }, onExpanded : function(){ this.state.collapsed = false; this.storeState(); }, onEnabled : function(){ this.state.enabled = true; this.storeState(); }, onDisabled : function(){ this.state.enabled = false; this.storeState(); } };
Code:<html> <head> <script type="text/javascript" src="scripts/yahoo-debug.js"></script> <script type="text/javascript" src="scripts/dom-debug.js"></script> <script type="text/javascript" src="scripts/event-debug.js"></script> <script type="text/javascript" src="scripts/animation-debug.js"></script> <script type="text/javascript" src="scripts/yui-ext-debug.js"></script> <script type="text/javascript" src="scripts/collapser.js"></script> <style> .ycollapsable-menuhead {border:1px solid #555;background:#369;color:#fff;cursor:pointer;padding-left:10px;} .ycollapsable-menucontent {border:1px solid #555;padding:20px;} .ycollapsable-disabled {background:#999;color:#ddd;cursor:default;} </style> </head> <body> <div id="collapser1" class="ycollapsable"> <div class="ycollapsable-menuhead"> Header </div> <div class="ycollapsable-menucontent"> <div> Content Content Content Content </div> </div> </div> <div id="collapser2" class="ycollapsable"> <div class="ycollapsable-menuhead"> Header 2 </div> <div class="ycollapsable-menucontent"> <div> Content 2 Content 2 </div> </div> </div> <input id="toggleButton" type="button" value="Enable" /></p> <script> var coll1 = new Collapser('collapser1'); var coll2 = new Collapser('collapser2'); coll1.restoreState({enabled: true, collapsed: true}); coll2.restoreState({enabled: false}); setButtonState(); YAHOO.util.Event.on('toggleButton', 'click', toggleCollapser, coll2, true); function toggleCollapser(){ if (coll2.enabled) { coll2.disable(false); } else { coll2.enable(false); } setButtonState(); } function setButtonState() { YAHOO.util.Dom.get('toggleButton').value = (coll2.enabled ? "Disable" : "Enable"); } </script> </body> </html>
Similar Threads
-
popup like jack's blog system :D
By luke83 in forum Ext 1.x: Help & DiscussionReplies: 21Last Post: 24 Jan 2008, 11:08 PM -
Jack's Screenshots
By Webnet in forum Community DiscussionReplies: 2Last Post: 28 Feb 2007, 9:55 AM -
How to make money and make everybody happy...
By dolittle in forum Community DiscussionReplies: 0Last Post: 21 Feb 2007, 12:28 PM -
Jack's Blog inaccessible?
By techno_adi in forum Ext 1.x: BugsReplies: 10Last Post: 29 Nov 2006, 5:24 AM -
Jack's new blog
By christocracy in forum Ext 1.x: Help & DiscussionReplies: 4Last Post: 18 Oct 2006, 9:36 AM


Reply With Quote