| Page 1 of 1 | [ 6 posts ] |
|
Hi,
How does one nest tabviews correctly? I know I've done this in the past ... but at the moment can't get it to work. I'm sure that I'm missing something simple and obvious, and maybe have a bug in my layout or code somewhere, but I've tried to reduce it to a bare-bones test case. the rendering works fine, but the nested tabview tabs do not respond to clicks. This is from markup -- each tabview works fine by itself, the sub-tabview is simply contained within the one of the tab panels. Do I need to express a relationship between the sub-tabview and the panel that contains it, other than markup placement? I have noted that it is required to render the sub-tabview first (otherwise all heck breaks loose). This fact points me towards the need to have the parent tabview panel informed about the presence of a the sub-tabview. Erik. |
Juan Ignacio DopazoYUI Contributor
|
You don't need to connect one tabview and the other in any way. In fact if you did it probably wouldn't work right.
I am using nested tabviews created from JavaScript for now without any problems. I made a test case using progressive enhancement and I didn't find any errors either http://jsfiddle.net/juandopazo/PzeR4/. Could you post an example? |
|
Hi Juan,
Thanks for the tip and code. Our code was just about identical, however it I was creating the tabs first, and then rendering them, and order matters in ways I hadn't account for. I've tried every combination of tab creation and rendering, and the only method that works was the one you used (and the one I must have inadvertently used before): In some cases the inner tabview markup will be left intact (i.e. un-rendered, in all of its original glory) AND also rendered into the document (creating an extra tabset at the top of the page.) This happens when the tabviews are first created, and then rendered, and the outer tabview is rendered first. In other cases, the inner tabview is rendered correctly but the inner tabs don't respond to clicks. This happens if you create the tabview objects first, and then render the inner tabview first, or if you create the inner tabview object, then render it, and then create and render the outer tabview object. Finally, the one case which works is to create and then render the outer tabview, and then create and render the inner tabview. BTW, Juan, would you mind sharing your programmatic method of creating nested tabviews? A single tabview is easy, but I can't figure out how to insert a tab with non-html content. I can do this with other things like charts, through markup-based tabviews, using a placholder div with id, and rendering into that node, but at a certain point in my app it would be really great to just create this whole thing programatically. There will be little or no benefit from progressive enhancement for a more complex app which needs to build up charts, help pages, etc.based on interactions with the user. Erik. |
Juan Ignacio DopazoYUI Contributor
|
Oh! I see what's going on. Let's consider this code:
Code: var tabview1 = new Y.TabView({ srcNode: '#tabs' }) var tabview2 = new Y.TabView({ srcNode: '#subtabs' }); tabview1.render(); tabview2.render(); At first, both instances look for a reference of their srcNode. Then TabView seems to be doing something that when rendering the first TabView the second one loses the reference to the #subtabs node so it ends up rendered in the body. That's possibly a bug. I'll investigate a little more and file a ticket if it looks like it can be fixed. Creating nested TabViews from JS is just a matter of rendering the second TabView into the "panelNode" of a tab in the first one. Check it out: http://jsfiddle.net/juandopazo/ez4Tz/. However, I'm doing it programmatically because I'm writing a bookmarklet (something like Firebug Lite). If you can do it, progressive enhancement of most elements in your page is usually great for user experience. |
|
Thanks, Juan. I'm a fan of YUI3, and always end up back at it after getting frustrated and toying with jquery or mootools. However, YUI3 can take a lot more time to work with because of the complexity, holes in the documentation, and overly-simply example cases. Or rather, the concepts are explained very well in some places, but the Widget-specific documentation quite often falls short of providing full explanations or cross linking to the appropriate references.
Anyway, I had attempted to add a new tab, using the panelNode as part of the object, as in var newTab = new Tab({label: "New Tab", panelNode: anotherTabView}); tabView.add(newTab); I was mistakenly hoping that the tab would see the panelNode object and set it up and render it by itself. A bit of a chicken and egg thing -- how can the tab exist without content -- how can the tabview exist without a place to call home? Anyway, my attempt didn 't work -- it creates a blank tab, with no label. Replacing the panelNode with a content: property in the new tab constructor works. This is a bit confusing, but I guess part of the learning curve. Render is a pretty essential part of the Widget lifecycle. So the secret sauce is to create the new tab first, which creates a panelNode even if you don't give it anything go to there: var newTab = new Y.Tab({label: "New Tab"}); and then you can add the tab to the tabview it will live in: tabview.add(newTab); and finally you can render the inner tab view in its new tab home by using the panelNode of the new tab: tvInner.render(newTab.get('panelNode')); This is another case where order matters. You can't render the inner tabview before you have added the new tab to the outer tab view. If you try that, the inner tab view tabs are not clickable. It would be cool if you could just compose the widgets together then then call render() on the topmost parent widget and have all sub-widgets get rendered. The Widget and render() documentation is rather oriented to working with the DOM and existing markup. Still we have invaluable resources like you, Juan. Thanks! Erik. |
Juan Ignacio DopazoYUI Contributor
|
I guess I don't suffer from that very much because whenever I have a problem I just jump right to the source code and figure out what everything does. I should definitely find a way to translate that into patches for the docs.
Here's two little convensions that will probably help you avoid this kind of problem: - Always render() into nodes that are already in the DOM - If a widget looks like it uses something like dimensions/positioning, wait until the container is visible to render it (don't render it into a hidden container) |
| Page 1 of 1 | [ 6 posts ] |
| You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum |
© 2006-2013 Yahoo! Inc. All rights reserved.
All code on this site is licensed under the BSD License unless stated otherwise.
About This Site · Security Contact Info
Powered by phpBB® Forum Software © phpBB Group