List Pull Refresh Plugin for Sencha Touch
One thing that you find out quickly when developing for mobile, is that mobile devices require us to be much more creative with our usage of UI features. It's not all about adding another button here, or a form field there - that takes up too much space - it's about harnessing simple and natural gestures to perform the functionality we need.
Be Gone Refresh Button!
A simple thing we can do to get rid of extra button clutter is get rid of that "Refresh" button that is eating up space and ugifying the top right corner of our toolbar. Luckily someone has already come up with a UX to deal with this problem, the "Pull to Refresh" interaction pioneered by Loren Brichter of Tweetie fame. I just needed to implement it into Sencha Touch.
Pull to Refresh
The solution to this UX problem is quite simple, make a plugin that monitors scroll and adds the appropriate visual indicators, but I wanted to see how others implemented it first and follow that same pattern. This way whatever I developed would follow the exact same interaction as other established implementations and not confuse users.
What I found was the EGOTableViewPullRefresh , a JAVA implementation developed by enormego and used by Facebook for their Android mobile app, this provided me with the appropriate logic, styling and interaction to match the current widely accepted user interaction.
After careful examination (the code is actually quite small) I found that there are three stages to the "Pull to Refresh" concept:
- Normal
- Pulling
- Loading
The "Normal" state is when the user is pulling down on the list, but has not yet reached the required distance pulling the list to cause a refresh if released.
The "Pulling" state is when the user has pulled down on the list past the required distance, and releasing it would cause a refresh. If the user were to pull the list back up past the required distance and release it would return to the Normal state and a refresh would not be triggered - this is the "escape" for users that do not want to refresh.
The "Loading" state is quite self explanatory, it's when the user has released the list from the "Pulling" state and a refresh has been triggered, but data has not yet been re-populated. Also, a last updated date is updated when this happens.
With all of this laid out now, I can write the code needed to make it happen, and create the styles to mimic what currently exists.
The plugin
The first thing I had to do was add the HTML element to the top of the scrolling list that would provide feedback to the user when they pulled the list. After that, monitoring the 'offsetchange' event of the scroller element of the list is where the logic of when to show the feedback HTML elements is handled.
this.cmp.scroller.on('offsetchange', this.handlePull, this);
The handlePull method is where the logic went for determining which of the three states we were in. Take a look at my code on Github for all the details - all said and done it's only 125 lines.
I hope this code proves useful to you in your mobile development projects. This code is available to the public at my Github repository.
https://github.com/VinylFox/Ext.ux.touch.ListPullRefresh
Using the plugin is quite simple, just listen for the 'released' event on the plugin and reload your data.
{ xtype: 'list', ..., plugins: [new Ext.ux.touch.ListPullRefresh({ listeners: { 'released': function(plugin,list){ // call the plugins processComplete method to hide the 'loading' indicator your_store.on('load', plugin.processComplete, plugin, {single:true}); // do whatever needs to happen for reload your_store.load(); } } })], ... }
DEMO (Must be viewed on phone):http://www.codetick.com/demos/refresh/index.html
Enjoy!
Hey Looks very promising but the link to the demo seems to be broken
Works fine for me – can you provide any more details than “broken”.
The actual URL shown works (http://www.codetick.com/demos/refresh/index.html), but the link points to http://www.codetick.com/demos/refresh/, which first gave me a 500, now a 404.
Oh yeah, good spot. I never noticed because I was just typing it into my phone to test.
Fixed the link now.
demo is broken surely, for me..
Broken Details: I am clicking the link claiming that it is the demo link.
Although every page I want to open is open, this little link persistently is not opened.
Well, for somebody it works, for others it doesn’t,I think there is a server issue..
Thank you Shea…
Hi Shea,
Preety cool. The plugin did work however its breaking the itemtap listener which I have put on the list.
Not sure if I am doing something wrong or if you have already noticed it.
thanks
I have not experienced this problem, the itemtap event still works for me. Can you provide a sample and version.
Is this plugin works only with List? I am trying to add this feature to the Component class.
Hey, brilliant code, exactly what I was looking for.
I do not like the built in List in sencha so I tend to use a panel and render my own HTML. I have successfully added this plugin to a panel and it works on the first drag but after that the refresh message element disappears permanently. Any ideas?
Dean Wild!
I made a fork that works with panels.
Check it out at https://github.com/diegoeche/Ext.ux.touch.ListPullRefresh
Hello,
it works with my list, but it hides default list loading mask.
How can i fix it? i want list loading mask!
I want loading mask too….
i met the same question. how to fix it ?
Thank you. It works like a charm.
I don’t use load() function like you in the release event but loadData() (of the store) and I can call one time only the pull refresh. Is that normal?
I should view the plugin code before post.
I solve my problem with a manual call of the processComplete() function of the plugin.
Code:
{
xtype: ‘list’,
…,
plugins: [new Ext.ux.touch.ListPullRefresh({
listeners: {
'released': function(plugin,list){
myRefreshListFunc();
plugin.processComplete();
}
}
})],
…
}