Example 5 - Tree with expand/collapse - how does it work?

1,702 views
Skip to first unread message

Salman Haq

unread,
Jan 7, 2013, 2:42:45 PM1/7/13
to slic...@googlegroups.com
How does this example actually show/hide the child rows of an expanded/collapsed parent?

The grid.onClick handler toggles the `_collapsed` attribute and calls updateItem and calls `updateItem()`. I traced through `updateItem()` but it doesn't like any show/hide logic happens there. The `_collapsed` attribute only appears to control the display state of the icon. And I can't figure out what the `parent` attribute is actually used for other than in `myFilter()` for controlling tree descent.

So where is the show/hide logic?

Thanks,
Salman

Steve Fazekas

unread,
Jan 7, 2013, 2:51:36 PM1/7/13
to slic...@googlegroups.com
It uses the inline filter functionality to show or not show based on the index of the parent row. The function used for collapsed actually adds or removes that JSON attribute from the row so it knows whether to filter it or not.

Steve Fazekas

Sent from my iPhone

Salman Haq

unread,
Jan 7, 2013, 4:21:47 PM1/7/13
to slic...@googlegroups.com
Thanks.

The `myFilter()` function uses a closure on the global var `data`. But when I do the same in my code and set inlineFilters:true, I get a reference error because `data` is not defined.

This is happening because my code uses a factory function to create the DataView and Grid. The `data` object is passed as an argument to this function which is called inside a loop. Here is a snippet:

for (...) { // create several grids dynamically
  var data = generateData();
  var elid = '#grid-'+loopCounter;
  var grid = MyFactory(elid, data, defaultColumns, defaultOptions);
  grid.render();
}

I think it's rather limiting that the filter function has to rely on a closure on a global variable to work correctly. Is there any way around this?

Can the signature of the filter function be changed so that it accepts the current DataView instance?

Thanks,
Salman

Michael Leibman

unread,
Jan 7, 2013, 4:26:26 PM1/7/13
to slickgrid
This particular example uses a closure, but you don't have to.  The filter function accepts a second argument that can be set using DataView.setFilterArgs().  See example-optimizing-dataview.html.

Salman Haq

unread,
Jan 7, 2013, 4:37:55 PM1/7/13
to slic...@googlegroups.com
Tin,

Yes, I discovered `setFilterArgs` moments before your email and tested it in my code with desired results.

So what is the implication of a DataView object holding a reference to a filter function which in turn holds a reference back to the DataView object. Have I not created a circular reference? It probably doesn't matter in my use case but I'm just curious.

Also, IIRC, creating a dynamic function with `new Function(...)` does not compile it. Is that no longer true?

Thanks,
Salman

Michael Leibman

unread,
Jan 7, 2013, 4:46:54 PM1/7/13
to slickgrid
I suppose there's potential for leaks there, but unless you create tens of thousands of DataViews in a single page app, I think this can be safely ignored.  It would be nice if the filters were executed in the context of the DataView (i.e. this == DataView instance) - I've created a bug for this (#508).

As for the dynamic function JIT compilation and optimization (I assume that's what you meant), it's actually the other way around, at least in Chrome.

Salman Haq

unread,
Jan 7, 2013, 4:52:06 PM1/7/13
to slic...@googlegroups.com


On Monday, January 7, 2013 4:46:54 PM UTC-5, Tin wrote:
I suppose there's potential for leaks there, but unless you create tens of thousands of DataViews in a single page app, I think this can be safely ignored.  It would be nice if the filters

That's what I thought. :)
 
were executed in the context of the DataView (i.e. this == DataView instance) - I've created a bug for this (#508).


That would be great!



 

As for the dynamic function JIT compilation and optimization (I assume that's what you meant), it's actually the other way around, at least in Chrome.


I see. I'll have to get up to speed with the JITting features of the different browsers.

Pinny

unread,
Jan 10, 2013, 12:23:31 PM1/10/13
to slic...@googlegroups.com
I am currently trying to use Example5 for my multi-level grouping and so far it's going great. I also came across the issue with data object and filter args :)

But that got me to this question: Right now, it seems, you can have just one filter and one sort comparator. What happens if there is already a sorting or/and filtering applied to the grid? 

In order for Example5 to work properly rows must be sorted in a specific way and filtered by collapes/expanded groups. But if sorting is enabled on columns (or other means) then there should be an ability to chain sorting handlers/comparers. Same with filters. Right now you have setFilter that sets a single filter function. And in Example5 it has three different filters, but they all combined into one function. In our case we have a separate module that plugs into grid and provide ability to select grid columns and values to filter by. And there might be more "external" places that are trying to filter a given grid. So I think I will have to implement things like addFilter/removeFilter and provide ability to chain filters... Or is there a better/existing way? Like playing with filter args maybe?

Michael Leibman

unread,
Jan 10, 2013, 1:59:25 PM1/10/13
to slickgrid
Pavel,

This sounds like the kind of thing that's specific to the application and that you'd want to control.  I don't yet see a case for building it into the DataView.  The filter chaining (http://stackoverflow.com/questions/4940564/sorting-slickgrid-by-multiple-columns/4941693#4941693) can be done by your single filter implementation that is aware of the auxiliary filters.

Pinny

unread,
Jan 10, 2013, 2:16:32 PM1/10/13
to slic...@googlegroups.com
Agree, this is something that is most likely my app specific. And both the link you provided and Ex5 dealing with a case where one comparer/filter is aware of another one(s). In my case this is not so.

Yet I still think it might be useful to be able to separate logic for different comparer/filters (with completely independent logic) and be able to pick and choose which ones to apply. Just like you have it in grouping example - different buttons to group by this or that field (or multiple fields) and/or filter by this or that (or all together) logic.
Just a thought... =))

Michael Leibman

unread,
Jan 10, 2013, 2:30:51 PM1/10/13
to slickgrid
What would you propose?

Pinny

unread,
Jan 11, 2013, 2:12:14 PM1/11/13
to slic...@googlegroups.com
If I understand it correctly, you take the set filter, strip it into its args and body, replaces the "return true" with statements that add the row to the list of rows to be shown and "return false" with continue statements, and then basically create a new "compiled" filter version that is suited to work with the dataView object stuff. so for for filter I would:
  1. instead of setFilter that sets a single filter I would create addFilter(filterName, filterHandler), and removeFilter(filterName). Under the hood instead of one single filter variable I would have a map  filterMap :: {filterName:filterHandler}
  1a. if we dont care about each filter then instead of creating new methods we can just update the existing one to accept as many params as you want (Java equivalent of varargs) and just use "arguments" property to iterate through all filters and put them into filterMap
  2. Same for filterArgs
  3. compiling methods (with and without cache) would then be changed as:
    1. create filterInfo for each filter in the filterMap. would put it into an array.
    2. for each of them would create an anonimous function call string and replace all the $item and $args, just like it is done right now for one filter
    3. would create a single string that calls those anonymous functions one by one.
    4. at the place where you create your own filter you have a line of new code that calls the filter:  "$filter$" which is replaces with the body of the set filter - this would be changed with that string that calls those anonymous functions. Just like before anyone of them can call "continue _coreloop" so we will not be calling ALL of the filters all the time. So no worries there
  4 In case of allowing unlimited nubmer fo filters - it would invoke the filtering just like it is rignt now, and in case of add/remove methods - we would need to have a method something like "dataView.filterItems() that would invoke this brilliance! :)))

and that should do it i think. in the end these methods will return just one single function like it does rignt now, but it would call all the filters added, instead just one.


With sorting, i think it is a little bit easier. Though it has a different approach since unlike with filter you dont store it anywhere, just sorting items and done. So
  1. Either go with filter option 1a to allow multiple comparer (the order of params would have to change though. instead of sort(comparaer, asc) now it would be sort(asc, comparer1[ ,comparere2..comparerN]). But it might be a bit painful for current users...
  1a. or I would have as with filters option 1 and create addSortComaprator removeSortComparator and have the map to store it. Though usually the order of sort algorithms is important, so array might be a better solution to preserve the order of comperer
  2. Create a new "compiled" comparer from the chain of eaich of the coparers where each of them is is calling next one it it returns 0 (if -1 or 1 is returned the job is done)
  3. Apply the compiled comparer to the items: items.sort(myNewShinyComparer);
  4. Same with invoking the sorting as with filters.

 
How does that sound? :)


On Thursday, January 10, 2013 11:30:51 AM UTC-8, Tin wrote:
What would you propose?
Message has been deleted

Pinny

unread,
Jan 11, 2013, 2:19:10 PM1/11/13
to slic...@googlegroups.com
I would also put checks that supplied filters and comparers are typeOf === "function" :)

Ziber Bee

unread,
Apr 11, 2013, 12:31:06 AM4/11/13
to slic...@googlegroups.com
Hi Salman Haq, do u have your example using collapsing with SlickGrid and the data comes from database. i don't know the basic concept how tree grid works. 
Reply all
Reply to author
Forward
0 new messages