[ 25 posts ] Go to page 1, 2, 3 Next

Brett Bukowski

  • Username: brettb
  • Joined: Wed Aug 26, 2009 9:58 am
  • Posts: 1
  • Offline
  • Profile
Tags:

3.6PR3 TreeView Feedback

Post Posted: Fri Jul 06, 2012 10:56 am
+0-
At the latest Open Hours the YUI dev team called for feedback on the 3.6PR3 TreeView. There doesn't appear to be an existing thread and the Github pull request isn't the place for this type of feedback.

The YUI3 TreeView is a lot simpler than YUI2 TreeView. That's fine, as long as the minimal API still supports some more complex use-cases. However...

# Dynamic loading?

No support for fetching sub-trees via ajax or datasource? That's a curious omission, even in an early release.
A big emphasis was placed on rendering performance, which is good. But a big performance gain can be won by dynamically fetching new nodes on demand rather than requiring them all up front.

# Needs to expose a lot more events

As long as there's enough events to tie into it's straightforward enough to implement dynamic loading yourself. But there's no expand or collapse events being fired. From the source, there's a 'toggleTreeState' event, but it doesn't bubble out to a subscriber on a TreeView instance.
There's 'treeview:click' and 'treeleaf:click', but there's no way to know if a treeview:click is in response to a click on the "expand" portion or on the label itself (select action).

# List item nesting

Children are inserted as sibling list-items of the TreeView's label list-item rather than as a nested list.

e.g. http://pastie.org/4211724

The way it's currently implemented results in less deeply-nested structures (rendering performance, or just a reaction to YUI2 TV's overly-nested tables?) but isn't as semantic and is, presumably, more confusing for screen reader users. It's also impossible to style sub-lists properly since children list-items are siblings of the list-item labeling the TreeView, rather than as a sub-list within the list-item.


I'd appreciate if the authors of the TreeView widget would take a look and possibly get tickets in for some of these things. YUI3 TreeView is a nice first step, but the current omissions make it difficult to implement anything more complex than a simple example.

Satyam

YUI Contributor

  • Username: Satyam
  • Joined: Tue Dec 09, 2008 12:34 am
  • Posts: 2016
  • Location: Sitges, Spain
  • GitHub: Satyam
  • Gists: Satyam
  • IRC: DevaSatyam
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Sat Jul 07, 2012 3:21 am
+0-
Good idea, I felt the same, I didn't know where to put it. let me comment on some of your points and add some of my own.

#Dynamic loading

There is a further problem with Dynamic Loading. YUI2 TreeView had one TreeView object as the root and all the rest were subclasses of (YUI2) Node (which is not related to YUI3 Node). When you have dynamic loading, with this class scheme, what are you going to put at the end when it might not still be the end or you are not yet sure? With YUI2, they were all Node instances. The existence of children, whether they were zero or non-zero determined whether there was a plus/minus sign or not. With this scheme, you would have to .... Actually, I don't know what would you do. Make them all TreeView instances just in case they might have children or make then TreeLeaf and then change them into TreeView?

#Markup:

The markup needs to have three containers, not just one. There must be a container for the plus/minus or coupling sign, another for an application-specific icon and the label. The current trivial mechanism is not good. I know, you can place anything in the label, but then, TreeView would not be providing much functionality that is required. First, you can't expect than someone is going to provide all the possible combinations of plus/minus/coupling + application specific icon. There are 9 varieties of plus/minus/coupling icons. With no application-specific icon, that's all, fine. If you have, say, open and close folder plus three document types (and that is not really that much) then if you don't provide separate containers for each, then you would have to create a sprite with 45 combinations.

Second, the markup does not allow for the following:

#Label and toggle icon click:

You need the separate containers to discriminate clicks on the plus/minus/coupling icon from those on the label. One of the questions asked most often in the YUI2 forum was how to make a click on the label do something different from toggling the node. The default in YUI2 TreeView is to toggle, but it can be easily overridden. To be able to do that, you need to have separate containers.

#memory consumption

Widget takes too much memory. This schema is impossible to support for trees of any size beyond the most trivial examples. This was known and, in fact, it was one of the reasons why TreeView was not initially ported from YUI2 to YUI3. The idea was that at some point there would be a WidgetLite, much as there is a BaseCore class, which uses the lightweight version of Attribute and avoids some events and such. Such WidgetLite would have been the basis for TreeNodes as well as MenuItems, another tree-structured widget that might potentially have too many items.


When Gonzalo first published this module in the Gallery, my suggestion was to have a TreeView object representing the whole tree as well as containing the root object, which is not visible. This would be the only full Widget. Then there would be any number of TreeNode objects which would have been derived from WidgetLite.

Since there is no WidgetLite, I would now suggest the TreeNodes to be plugged-in Nodes, the TreeView being the one doing the plugging.

Experience shows that nobody retains references to any of the individual nodes. Programs usually have a single reference to the whole tree. References to the individual nodes are used mostly only while responding to some event on the node.

Thus, it would be possible to do a single TreeView object that would capture by delegation all events in its nodes, would then locate the target node and create a Node instance out of it, plug the TreeNodePlugin to it and then pass it to the event listener. The single TreeView instance would then be able to have HTML_PARSER capabilities and would be the only one having the code to draw the whole tree or any of its nodes.

For dynamic loading, though YUI2 TreeView could flag both the whole tree or individual nodes/branches for dynamic loading, I am not aware that anyone did the later or, at least, if they did, they never asked any question in the forum for me to notice.

YUI2 TreeView also had several getNodeXxxx and getNodesXxxx methods which were the usual way to find individual nodes. In a YUI3 TreeView, those same methods would locate the requested node(s) and create the plugged in Node instance(s) when returning them.

Navigating through the tree would be handled by the plugin to the TreeView which would have a private object representing the state of the tree (basically, the original object from which it was constructed plus references to the Ids assigned and Node references if instanced).

Developers would be encouraged to dispose of the Node instances once they are done to reduce memory consumption (unless they believe they would use them often which they can by holding on to them).

This would allow the fastest rendering and the least memory consumption since plugged-in Node instaces would only be created of those TreeNodes the user might interact with which, usually, are a very small percentage of the total nodes of a tree. There is absolutely no need to create and maintain a full Widget instance (plus extensions) for each and every node in the tree, with all the memory consumption it takes.

Just as Brett would "appreciate if the authors of the TreeView widget would take a look and possibly get tickets in for some of these things", I would also have appreciated if the guy who was in charge of YUI2 TreeView from version 2.6 (when it got a big upgrade, see: http://developer.yahoo.com/yui/treeview/#upgrade) until its end of life would have been consulted. That person happens to be me and I've just learned about this Widget getting official status when the OH was announced. Out of all the TreeViews available in the Gallery (and there are many) this, with its TreeView and TreeLeaf scheme would be the first I would have discarded.

zmre

  • Joined: Thu May 03, 2012 2:16 pm
  • Posts: 1
  • Offline
  • Profile
Tags:

Re: 3.6PR3 TreeView Feedback

Post Posted: Tue Jul 10, 2012 11:44 am
+0-
I'd also like to see some of these issues fixed or some response from the YUI team on this.

@Satyam, do you recommend any of the gallery options?

Satyen Desai

YUI Developer

  • Username: sdesai
  • Joined: Tue Dec 09, 2008 4:17 pm
  • Posts: 302
  • GitHub: sdesai
  • Gists: sdesai
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Tue Jul 10, 2012 6:13 pm
+1-
I'll leave the TreeView specific questions to the TreeView owner (markup, data layer, events etc.), since I can't add much value there.

I can try and speak primarily to @Satyam's (with an "m") point about whether or not what ends up be the equivalent of a TreeNode should be a DOM based API, or something richer. I'll refrain from using the word "Widget", since it comes with pre-conceived notions about what a "Widget" is.

When I refer to something richer, I refer to an object which has observable state (essentially something Base based) with a logical API which makes sense regardless of how this thing is rendered [ treenode.isCollapsed(), treenode.getLabel() etc. ]. Add to that some non trivial rendering associated with that state [ that is, it's more than a single DIV/LI/SPAN whatever, with arbitrary content in it].

a) A Base-based object was chosen, because it could be easily (I'd use the word 'standardly' if it existed) extended, and custom 'child' types can be fed into a Parent. For example, to provide Editable Tree Nodes, or Selectable Tree Nodes, or Paginated TreeNodes etc.

b) When people work with a top level treeview API, they are usually less interested in the state/API on that top level TreeView (or root), and more interested in the state/API on individual TreeNodes - e.g. node.get("label"), node.get("collapsed"). In an object orient world, the TreeNode is the proper holder of this state, not the TreeView. Hence it makes sense for the TreeNode to be a richer object. If you wanted TreeView level APIs for all of these operations, you'd end up passing some kind of TreeNode identifier to all these top level methods, which just acted as sugar for the object actually holding the state.

c) Events too are usually TreeNode centric and not TreeView centric. e.g. You're normally reacting to a specific TreeNode collapsing or expanding, and not a general TreeView:collapsed, or TreeView:expanded event, which you'd then need to filter against to figure out which TreeNode was expanded or collapsed, or which TreeNode had it's label edited, or which TreeNode had children added to it.

So, fundamentally, as least if we agree on the above, the ideal API we're hoping for is something TreeNode centric and not something TreeView centric, because more operations center around TreeNodes, and not the TreeView (or root).

If we agree on the above, then the only reason we'd consider backing away from that conclusion is performance (and we did consider/debate backing away from it) and that too, performance at large scales [ that is, a TreeView with 20 nodes is not likely to be a concern, a TreeView with 500 node may be ].

So looking at the performance angle, the same set of performance optimizations you mention could arguably be applied to Widget, WidgetParent or WidgetChild - lazy instantiation (so we're not creating 1000s of objects up front), flyweight (so we only have one object in memory) or string based rendering (which we started with as the first step).

I'll grant that we're not there yet with these implementations (as you mention), but IMO, that's not a reason to prematurely back way from the ideal TreeNode centric API we'd like to have. I think we should put the API we want to have out there, and work out the large-scale performance overhead.

Finally - I agree with your point Satyam - as the owner of the final 2.x TreeView, you should have been more involved with the design conversation. You mention some initial conversation/design feedback you provided. I'm not sure why that feedback/debate was not continued - but I think it should have been - and that may be our bad if we dropped the conversation midway.

Well maybe not finally - since I'm done with my feedback on richer objects: What I mention above is fundamentally the definition of a Widget in my mind - some stateful object, which has an associated visualization or rendering which it's responsible for keeping in sync. It's not a "Widget" in the "form element" sense of the word - which is the pre-conceived notion I refer to. A TreeNode is a stateful object, which an associated visualization/rendering, which needs to be kept in sync with changes to it's state.

Hope that helps at least articulate the decisions behind making TreeNode's richer objects, at least as I understand them.

Satyen (with an "n")

Satyam

YUI Contributor

  • Username: Satyam
  • Joined: Tue Dec 09, 2008 12:34 am
  • Posts: 2016
  • Location: Sitges, Spain
  • GitHub: Satyam
  • Gists: Satyam
  • IRC: DevaSatyam
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Wed Jul 11, 2012 12:06 am
+1-
@ZMRE:

All the gallery versions of TreeView are somewhat old. All of them would need some revamping, one of them using WidgetHTMLRenderer and many other performance improvements, specially on a NodeJS environment. None of them has this TreeView/TreeLeaf structure so, at least, that's a point in favor of any of them.

Anyway, there has been several discussions on how to improve the Gallery, the latest here: viewtopic.php?f=18&t=10066 part of which involves which components to pick and promote.

@Satyen

My main concern with this TreeView proposal is the TreeView/TreeLeaf architecture. In your reply you mention TreeView and TreeNode objects, which is how I think it should be, not TreeView/TreeLeaf which is what the proposed component has. I really don't have a particular preference as to what the TreeNode should be and I probably got carried away making them Nodes plugged with a TreeNodePlugin. Perhaps I got carried away in that, but what I wanted to really stress is that there should be one basic foundation and that would be the TreeView object, representing the whole tree and its root and then, TreeNode objects which should be much lighter. What is the right trade-off for TreeNodes, whether to make them full Widgets or plugged in Nodes, I don't know. I imagined plugged in Node instances as an extreme of lightness, but anything in between might be better.

Regarding points b) and c) it is true that people are concerned about the state of individual TreeNodes, but they usually reach them via TreeView (the root). I can't imagine anyone subscribing to a particular TreeNode click event. You usually subscribe to TreeView click events and then get the TreeNode instance in the facade of the event. In YUI2 TreeView, individual nodes didn't have events you could subscribe to (well, you have one but I don't think anyone ever cared about that one), you got all your events from the root. All YUI2 TreeView events have a node reference as one of its arguments already resolved for you. I don't recall anyone ever asking in the forums to be able to subscribe to a particular TreeNode click event.

Likewise, you usually reached the TreeNodes via the root using any of the getNodeXxxx methods. If you build your TreeView either from existing markup or a literal object, you don't get references to individual nodes. When you built your tree via JS code, you held a reference to each individual node when it was created so you could use it to provide it to its children when they were created, then you forgot about it. If you look in the examples, such reference was often called tmpNode or some equally volatile name.

So, nobody really cared about individual TreeNodes until something happened to them. Then, the event listener would be provided with a reference to the one involved. Which is good, because it means they don't even need to exist (except as markup on the screen) until needed. Moreover, markup for nodes in collapsed branches was not even rendered. Such markup can be created really fast via templates, by TreeView, with the help of a single TreeNode instance, re-used over and over, much as that tmpNode reference so often used in YUI2 TreeView.

Using WidgetParent/WidgetChild does not lead to the kind of optimizations you mention (lazy object creation or flyweight pattern), as far as I can remember. If you let a Widget extended with WidgetParent/WidgetChild run over a configuration object and it finds a children property containing an array, WidgetChild will start creating child objects of the ROOT_TYPE class for each of the children. No laziness there.

Anyway, once the TreeView/TreeLeaf architecture is dropped, then we can start talking about optimizations and improvements.

So, my main points are:

a) No TreeView/TreeLeaf.
b) Single TreeView representing the whole tree and its root and a lighter TreeNode for every other node
c) TreeNodes created on demand when needed (in response to events or getNodeXxxx methods), reused if possible (flyweight pattern or some such)
d) I don't think WidgetParent/WidgetChild can be used unless they can get 'lazy'.
e) I don't really mind if TreeNode is a full-blown Widget, if it can be created on-demand( lazy) or reused (flyweight).

Juan Ignacio Dopazo

YUI Contributor

  • Username: jdopazo
  • Joined: Fri Oct 02, 2009 5:39 am
  • Posts: 618
  • Location: Buenos Aires, Argentina
  • Twitter: juandopazo
  • GitHub: juandopazo
  • Gists: juandopazo
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Wed Jul 11, 2012 5:51 am
+0-
In the spirit of "simplify, simplify, simplify", I'd change one of those items and add another:

d) TreeViews/TreeNodes should follow the WidgetParent/WidgetChild API even if doesn't use the extensions. That API (treeview.item(0).item(1).get('children').each()) should be consistent across YUI.
f) No hidden root in TreeView as in YUI2. TreeView should just be a container with any number of children

Satyen Desai

YUI Developer

  • Username: sdesai
  • Joined: Tue Dec 09, 2008 4:17 pm
  • Posts: 302
  • GitHub: sdesai
  • Gists: sdesai
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Wed Jul 11, 2012 9:52 am
+0-
Satyam

My basic point in defining what functionality the TreeNode object should have, is that the state for whether a TreeNode is expanded or collapsed, is a function of that TreeNode, or the state of the label for a TreeNode is a function of that TreeNode, not the top-level TreeView (or Root). The TreeNode encapsulates that state, and fires an event when that state changes (that responsibility is thus encapsulated and extendable). Whether people listen for that event only at the TreeView, or whether they ask for an instance and listen directly on it, is a layer above that.

As for the other stuff, I think we're saying the same thing - Lazy instantiation or flyweight doesn't exist for Parent/Child, but should. We should avoid creating full blown instances until the user needs one. Both of these things make sense in general for Parent/Child (or Model/ModelList for that matter - see below), not just TreeView.

The TreeView implementation, to the best of my knowledge already renders it's Nodes completely using strings/templates, and renders lazily (doesn't render collapsed children up front), but I'll let the TreeView owner validate that statement.

The main missing piece is lazy instantiation/flyweight (flyweight being a little more difficult). Ryan submitted a Lazy Model/ModelList impl which I've discussed with EricF as potentially looking at re-using for Parent/Child [ or a Base/BaseList if you will ], if there's nothing Model specific about what it's doing.

So, to sum up, to your points:

a) I'll let the TreeView owner comment on the choice of structure. I don't have that in my head currently, and haven't given it that much thought.

b) I think the TreeNode should be an observable/stateful thing. We just need to avoid creating 1000s of them up front (see c))

c) Agree

d) I think it's missing a 'feature' - lazy instantiation/flyweight. Using it provides a consistent API as Juan mentions (which matter not only for consistency, but also for the application of generic extensions which target the Widget API), and something to extend, to create Selectable/Editable Tree Node objects.

e) Agree

Again, if we can agree (or conclusively disagree) on whether or not these TreeNode objects, when we finally create them, need to be observable and encapsulate their own state, we can go from there. Another option, which EricF mentioned, is that Model/ModelList (with Views) has lazy instantiation, and string based rendering [ both of which we're trying to retrofit Widget and WidgetParent/Child to support - although it's more challenging there due to backcompat ]. It's another option to consider - keep in mind these would still be observable/stateful objects - but just with lazy instantiation already done. What we'd give up in the scenario is the consistent/common Widget API for extension and consistent classname generation.

Satyam

YUI Contributor

  • Username: Satyam
  • Joined: Tue Dec 09, 2008 12:34 am
  • Posts: 2016
  • Location: Sitges, Spain
  • GitHub: Satyam
  • Gists: Satyam
  • IRC: DevaSatyam
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Wed Jul 11, 2012 1:47 pm
+0-
Regarding a), Gonzalo has 16 posts overall in this forum so just assuming he will reply to this, let alone read it is wishful thinking. (You, Satyen, are a quiet person and you are close to 300 posts and you joined just half a year before him). Trusting the component to someone who has no contact with the community is not a good idea.

This issue about the absurd TreeView/TreeLeaf architecture is not new. I objected to it since December 2010 (see: viewtopic.php?f=256&t=5899). Anyway, being a Gallery module, I wasn't going to make so much fuzz about it; there are worst things on the Gallery. Now, having it upgraded to a full YUI Library component, that is quite some other matter. I hoped it was dead. Zombies are fashionable these days, I didn't expect to find them here. Should I provide myself with a stake or a silver bullet? Is Luke going to have to redesign it a year from now as he has already done with that equally dismal design for DataTable?

Anyway, it is close to midnight on this side of the world so tomorrow I'll post something more positive backed with some code if possible.

My apologies for being such a pain in the neck but this TreeView/Treeleaf architecture? This is not ready for the Library. Please do pull it off this release!!! Then, we can do something decent about it.

Satyam

YUI Contributor

  • Username: Satyam
  • Joined: Tue Dec 09, 2008 12:34 am
  • Posts: 2016
  • Location: Sitges, Spain
  • GitHub: Satyam
  • Gists: Satyam
  • IRC: DevaSatyam
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Thu Jul 12, 2012 12:30 am
+0-
Perhaps this could work:

On instantiation TreeView receives either a literal configuration object or a reference (either CSS selector or Node instance) of existing markup to parse. The object will be cloned to an internal copy, the markup parsed into a similar object.

TreeView will have a pool of TreeNode instances to make available to the developer when looking at any node in the tree. The TreeNode instances will be of the type indicated in an defaultType attribute in TreeView. This attribute will be either a string giving the name of the class under Y (Y[this.get('defaultType')]) or a reference to the class.

The configuration object will specify the structure of the tree with the children property containing specs for child nodes. The nodeType property will specify the type of TreeNode to create. If none is specified, the defaultType will be used, otherwise, an instance of the specified type would be created.

TreeView will keep one instance of each of these types (the defaultType and any other nodeTypes specified) in a pool of reusable TreeNodes.

TreeNode will have a private _node property. TreeNode (and all its derived subclasses) will always access all their internal information through this property. For example, when a node is clicked, TreeView will pick that up by delegation and locate which node it corresponds to in its internal copy of the configuration object. It will read the nodeType for that node and pick the corresponding instance from its pool of TreeNode instances. It will then set its _node property to point to the node in the configuration object.

TreeNode should have all its attributes with getters and setters so that they all get their data from the _node like:

label: {
....getter: function () {
........return this._node.label;
....},
....setter: function (value) {
........this._node.label = value;
....}
}

In this way, any TreeNode instance can be slid on top of any node in the configuration tree and work fine. Only the root attribute in TreeNode will not have such getters and setters since it is the same for all nodes.

On TreeView rendering, TreeView will read the tree configuration object and start sliding the nodeTypes (usually Y.TreeNode) on top of each of the nodes by setting their _node property and calling its render() method. TreeView won't bother to visit the children of collapsed nodes.

Whenever TreeView slides a TreeNode instance on a node, it will check it to see if it has ever been visited before (both TreeView and TreeNode will modify this internal copy of the tree configuration to add information on it, such as whether it has ever been visited) If it hasn't been visited, it will call a private method in TreeNode so that it can read all its properties and see if there are any extra properties not already declared as attributes. If any is found, TreeNode will call its own addAttr to add it to its standard attributes such as label, icon, expanded and so on. (alternatively, TreeNode could have its set and get properties overridden so that it accepts any attribute not previously declared). This is in keeping with the tradition of YUI2 TreeView which allowed extra custom properties (it didn't have attributes) on its nodes, which was a very common practice.

Since I'm thinking of BaseCore as the class TreeNode would be derived from, attribute change events should not be an issue since there are none. Anyway, if a particular TreeNode subclass were to be extended to fire attribute change events, since attributes should only be changed when the TreeNode instance is slid upon the node, it should not be a problem. If you tamper with the underlying property in this._node then you would not expect events to be fired. Such custom events should be bubbled to the root TreeView instance by using addTarget.

All events should be listened to via TreeView. TreeView would use event delegation to listen to anything happening in it or would be the target of custom TreeNode events. In all cases, TreeView would find out which node in its internal configuration object would be the originator of that event and slide the corresponding type of TreeNode on top of it and add it to the event facade.

TreeView would also have a forEachNodeBy() method which would take two functions, the first one a selector function which would receive a TreeNode instance and return a boolean to indicate whether it belongs to the set. The second function would be the function that does something about it. From this method, other helper iterators can be produced such as forEachExpanded(), forEachHighlighted(), forEachChild() which would only take a single callback function or forEachNodeByProperty (often used with custom attributes) which would take a property name, a value to match and the callback. The callback would always receive a TreeNode instance (or one of its subclasses according to its nodeType) slid on top of it.

In these callback functions, as well as in the events, the function should not keep a copy of the TreeNode instance since it will be slid on top of some other node on return. Developers can request a non-pooled TreeNode instance by using any of the getNode(s)By methods. This should not be encouraged since those copies will not be reused by TreeView though, of course, the developer can always dismiss those copies when no longer needed. Unfortunately, since JavaScript objects have no destructor the TreeNode would not be aware of it being de-referenced and would not return resources such as Node instances it might have held in the configuration object. Anyway, Node itself keeps a cache of Node instances so it probably doesn't matter.

Tree navigation via getNextSibling, getPreviousSibling, getParent would force TreeView to provide non-pooled instances for each, however, methods moveToNextSibling, moveToPreviousSibling or moveToParent would simply slide the very same node instance on top of it.

The nodeType property (or defaultNode attribute on TreeView) might also be a template. If the attribute is a string (not an object reference) and it has a curly bracket, then it is a template, if it doesn't, it is the name of a class under Y. TreeView would then use a regular TreeNode instance with the given string as its template. This would go well with the dynamic extra attributes so as to allow users to customize TreeNodes without having to create a subclass.

Some extra means of node formatting via code (not just via templates) should be provided, much as it happens with DataTable where there is a string formatter and a DOM node formatter.

Satyam

YUI Contributor

  • Username: Satyam
  • Joined: Tue Dec 09, 2008 12:34 am
  • Posts: 2016
  • Location: Sitges, Spain
  • GitHub: Satyam
  • Gists: Satyam
  • IRC: DevaSatyam
  • YUI Developer
  • Offline
  • Profile

Re: 3.6PR3 TreeView Feedback

Post Posted: Thu Jul 12, 2012 4:24 am
+0-
Regarding reusing TreeNode instances, I imagine two alternatives. One is to have a _busy property which would be set by TreeView when adding the instance to the event callback or one of the forEach methods and removed upon return. If TreeView finds the instance busy when it needs one (for example, when using forEachChildren within a click listener) it would simply create one for the duration and forget about it when done.

The other alternative would be to have a stack for each node type and pop instances from it when one is required and push it back when no longer needed. (or perhaps shift it back in, so as to wear them evenly? ;-) ). If the stack for any nodeType is empty when an instance is needed, a new one would be created and added to the stack when no longer needed. I would assume that such a stack would not grow beyond the maximum depth of the tree so it should not be that bad, and the code to manage such a pool would be simple.

As for reading existing markup, TreeView would read the properties it knows about from the existing markup and it would read the content of each node. If the content is plain text, it would simply assign it to the label attribute, otherwise, it would get a reference to it and once the new markup is generated would use appendChild to move it to the label container of the node. This was a repeated feature request on YUI2 where developers asked for elements in existing markup to be preserved when progressively enhanced. Usually, they were input boxes or links and sometimes they had event listeners already attached so reading the innerHTML from them was not good enough.

As for the markup for each TreeNode, it should have at least 3, possibly four spans. From left to right they would be the plus/minus/coupling container, an icon container, a selected container and the label. The plus/minus container has to be separate from the label container so that different actions can be assigned to clicks on each. Toggling would always happen when the plus/minus container is clicked. Toggling would be the default for clicks on the label, but can be prevented if a listener wants to do something else.

The icon property would fill the icon container with an img tag. It is highly recommended that the className property be used so that a tile from a sprite file can be used instead. Anyway, such a sprite icon should become the background image of that same icon container.

Finally, in YUI2, the selected/highlighted property of a node was tricked via CSS by setting a non-repeating background image on the label container while the label itself was offset via padding-left. This was a kludge used to preserve backwards compatibility, but I believe having a separate, independently clickable container to hold the selected status would be best. If TreeNode selection is not enabled, such container would simply be hidden.

These separate spans for each node would free the developer to use the label container for whatever might be required. In YUI2, there were issues when the developer tried to combine node selection with some fancy markup on the label because it lacked an independent container for the checkbox.

If the icon and selected features are separated into extensions, the template would need to be changed. However,I doubt that the code plus extra spans on the tree required to handle each of them makes it worth the trouble of turning them into separate extensions. Specially since doing so would bring interesting issues regarding how to extend a template string. How would the extensions manipulate the template, specially if each can be loaded independently and listed in any order?

And I would forget about using a template string as the nodeType, sorry about that. It is better to just have an instance template which can override the static template and define that one instead of messing up with the nodeType. Sorry.
  [ 25 posts ] Go to page 1, 2, 3 Next
Display posts from previous:  Sort by  
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