-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Add autodividers functionality to listview #3302
Conversation
* this happens if list items are added to the listview, | ||
* which causes the autodividers to be regenerated. | ||
*/ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this plugin and I have a few ideas for how to make this a bit more flexible:
- We should refactor it a bit so that a developer can specify a method, rather than a selector, for finding/calculating the divider text. The default implementation that uses a selector can just be the default method for the plugin.
- We should provide a hook that would allow a developer to merge/sort list items into and under the dividers created.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the idea of being able to specify a method for selecting text, though this would only be possible programmatically and not in HTML attributes.
As for the merge/sort idea, I would see these as separate issues: they could be further plugins for listview. Perhaps a simple autosort plugin, and separately additional API on listview itself to be able to insert/delete/move elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added the "use a function as a selector" feature (see https://github.com/townxelliot/jquery-mobile/commit/27da421d2cbdd5a1a2b81ac716e2844859404c67)
@jblas @toddparker and I are keen to get this merged in which is why we have so many comments/ideas. Hopefully it's not off-putting, and thanks for doing the hard work here! |
I'm more than happy to get the comments: it's great how responsive the jqm team is. There are a couple of aspects I can work on for now, but longer term my suggestion is that listview provides some events when a listview changes (e.g. item(s) added, item(s) removed, item(s) changed). I'm not sure whether you also need API to manage inserting/deleting list items, as there are libraries to do that for you (knockout, for example). But it's worth a discussion. |
I've incorporated several of the comments into my branch. I have left the autosort out as I feel that belongs in a separate extension; similarly, I've left out insert/delete functionality, as that feels like it should be in listview core (e.g. "add this li element after this divider"). I haven't attempted to add any events to listview, pending your feelings about that. In a previous version of this code, I think I added a listchange event to two places in the listview code (it was fairly straightforward). But I decided to go back to using the DOM events (which aren't uniformly supported, granted) rather than add hacks to listview itself. One more thing I'm thinking of doing is testing whether or not the approach here (with prevAll, prevUntil, :contains selectors) is faster than simply rebuilding all the dividers, especially for large lists. |
https://github.com/townxelliot/jquery-mobile/commit/35c5feb8ea025268a9bb9d34a942afe37fee9147 replaces all dividers on the list when autodividers are first applied (around 20x faster than the previous approach). I have retained the individual liAdded/liRemoved functions for now, as I was unable to just replace all the dividers when list elements are added or removed without breaking tests. I think it may also be more efficient when a single list item is added/removed than rebuilding all the dividers (though I haven't tested that yet). |
I think we should leave the list management up to the user (hopefully a kvo library) and just rest on In this case I think we'd trigger this._trigger("afterrefresh"); Hopefully that will help with the |
On 20 December 2011 16:57, John Bender
Agreed, that would resolve this for me.
Also agreed. |
Regarding your 20x speed-up ... you can get it even faster if you do 2 things:
|
On 21 December 2011 17:33, Kin Blas wrote:
Thanks for these pointers. I've rewritten the code slightly to use Please see https://github.com/townxelliot/jquery-mobile/commit/5c8ba5d3133d7e773edfa7dfc82e7b7af9c1184b |
How would you chaps like to close off this work? Would you like me to make the changes to listview to provide the event discussed above (listviewafterrefresh) so I can get rid of the DOM event watching? Are we agreed that the autosort functionality suggested by jblas should go into a separate extension and can be left out of autodividers? Are you happy with the implementation of the "selector as function"? Is it OK that it's not possible to reset options on this extension after it has been applied (because it's not a fully-fledged widget)? If that's not OK, what is the correct pattern to fix that? Thanks. |
@townxelliot - I know Kin and John Bender are now out, but I think @johnbender said he's be checking in so hopefully you'll get and answer so we can button this up. Thanks for being so responsive. |
Yah, go ahead and drop that trigger at the bottom of the refresh.
Yes, or we can add it here later. Either way I want to get this merged in, we've dithered enough on all this hard work you've done.
I'm still of the opinion we should avoid supporting "words-as-functionality" in the same way we avoided it with the listview filter. I'd rather just provide a callback that's defined on the options where the default is the alpha check. Also, that way we can remove the "type" information because it will always just be a callback. The fact that it requires code change to alter the behavior is entirely acceptable.
I was going to do a quick refactor and move this off the global [UPDATE] I didn't take a huge amount of time to understand the selector functionality so feel free to correct any assumptions I've made with the above. |
Any progress? I'll probably close this one out or move it to the feature requests page if there's no movement. |
Apologies John, I've been on another project and this work got sidelined. I will spend some time on it today and see if I can put something together from the comments etc. |
This is used as the hook for autodividers to redraw the dividers on a listview.
Can be used to autogenerate dividers for a listview by setting data-autodividers="alpha" (dividers are unique, uppercased single characters from list items) or data-autodividers="full" (unique full text strings selected from list items) on the ul element of the listview. It's also possible to apply a custom selector to find the elements to be used for divider text, with data-autodividers-selector="...". This relates to #2466, but is a different implementation which will automatically update the list dividers if the list elements change. It also has a fairly thorough test suite and documentation.
I've rewritten this branch and rebased it etc. (though I had to force push onto this branch), so it should be good to go. As there are no reliable mechanisms for detecting when list items are added/removed, I added a listviewafterrefresh event. The autodividers extension is bound to that event; however, when it is detected, the autodividers are unbound from the event, they do their work (creating autodividers), refresh the listview, then rebind to the event. This is to avoid having to duplicate the code in listview which adds classes, styling and behaviour to list items: listview can still do it, but autodividers has to unbind from the refresh event to avoid an infinite loop. The other change is that the autodividers are redrawn every time the list refreshes. Again, this is because there's no reliable way to detect individual items being added to the list. A better solution longer term might be to provide API on listview to add items and dividers programmatically (triggering appropriate events), but I didn't think that was in the scope of this patch. |
@johnbender Any progress on reviewing this? Sorry it took me so long to rework it, but it would be great to get it closed off. |
I've been busy with a presentation and blog post for the last two weeks. I'm going to start back in on PR's next week so I'll review it then. |
And! Thank you for staying on top of this. We value your effort and contributions and I'm sorry it's taken this long. |
Bam! Thanks for all your hard work! @toddparker Two things for discussion on Thursday:
@townxelliot your are welcome to join us for the discussion if you would like, but let us know when/if you do so we don't keep you online for too long. |
Excellent. Let's look at these API questions on Thursday. I'll add it to the agenda. Thanks again @townxelliot - cool feature. |
On 1 May 2012 22:45, Todd Parker
Thanks for reviewing and merging, I'm really pleased. I'm sorry, I can't make discussions this Thursday, as I'm already On the HTMLElement being passed in: that provides the most flexibility The advantage of a selector is it can be declarative (you could even I leave it to your judgement as to what the best way to go is. Thanks again. |
I just checked the demo page on test and it doesn't seem to be working: I'll need to update the header and CSS/JS refs in that page too. On May 1, 2012, at 6:24 PM, "Elliot Smith" [email protected] wrote:
|
@johnbender - I deleted that comment. |
Autodividers can be used to autogenerate dividers for a listview by setting data-autodividers="alpha" (dividers are unique, uppercased single characters from list items) or data-autodividers="full" (unique full text strings selected from list items) on the ul element of the listview.
It's also possible to apply a custom selector to find the elements to be used for divider text, with data-autodividers-selector="...".
This relates to #2466, but is a different implementation which will automatically update the list dividers if the list elements change. It also has a fairly thorough test suite and documentation.