PDA

View Full Version : Modified Ext.ux.touch.ListPullRefresh for Paging



SimonFlack
17 Dec 2010, 5:16 AM
I needed to modify VinylFox's Ext.ux.touch.ListPullRefresh plugin in order to use the same idea for list paging support.

If anybody is interested in doing something similar here is my modified code.

http://lh6.ggpht.com/_yBxLihSnjhA/TQtawagFSsI/AAAAAAAABAo/kP-BWkbb9bM/s640/paging.jpg

Usage:


plugins: [new mobile.plugins.ListPullPager({
previousFn: function(cb,scope){
mobile.commissions.store.previousPage();
cb.call(this);
},
nextFn: function(cb,scope){
mobile.commissions.store.nextPage();
cb.call(this);
}
})]

Plugin:


Ext.apply(Ext.anims, {
rotate: new Ext.Anim({
autoClear: false,
out: false,
before: function(el) {
var d = '';
if (this.dir == 'ccw'){
d = '-';
}

this.from = {
'-webkit-transform': 'rotate('+d+''+this.fromAngle+'deg)'
};

this.to = {
'-webkit-transform': 'rotate('+d+''+this.toAngle+'deg)'
};

}
})
});

Ext.ns('mobile.plugins');

mobile.plugins.ListPullPager = Ext.extend(Ext.util.Observable, {
langPullPrevious: 'Pull down to load previous...',
langReleasePrevious: 'Release to load previous...',
langPullNext: 'Pull up to load next...',
langReleaseNext: 'Release to load next...',
langLoading: 'Loading...',

loading: false,
//define the functions to call for loading.
previousFn: undefined,
nextFn: undefined,
// private
init: function(cmp){
this.cmp = cmp;
this.lastUpdate = new Date();
cmp.loadingText = undefined;
cmp.on('render', this.initPullHandler, this);
if (!this.previousFn || !this.nextFn){
cmp.getStore().on('load', this.reloadComplete, this);
}
},
// private
initPullHandler: function(){
//Previous
this.previousTpl = new Ext.XTemplate(
'<div class="pullprevious" style="height: {h}; text-align: bottom;">'+
'<div class="msgwrap" style="height: 75px; bottom: 0px; position: relative;">'+
'<span class="arrow {s}"></span>'+
'<span class="msg">{m}</span>'+
'</div>'+
'</div>');
this.previousEl = this.previousTpl.insertBefore(this.cmp.scroller.el, {h:0,m:this.langPullPrevious,l:this.lastUpdate}, true);
this.previousEl.hide();
Ext.Element.cssTranslate(this.previousEl, {x:0, y:+75});
//this.cmp.scroller.on('offsetchange', this.handlePrevious, this);

//Next
this.nextTpl = new Ext.XTemplate(
'<div class="pullnext" style="height: {h}; text-align: bottom;">'+
'<div class="msgwrap" style="height: 75px; bottom: 0px; position: relative;">'+
'<span class="arrow {s}"></span>'+
'<span class="msg">{m}</span>'+
'</div>'+
'</div>');
this.nextEl = this.nextTpl.insertAfter(this.cmp.scroller.el, {h:0,m:this.langPullNext,l:this.lastUpdate}, true);
this.nextEl.hide();
Ext.Element.cssTranslate(this.nextEl, {x:0, y:-75});


this.cmp.scroller.on('offsetchange', this.handleOffsettChange, this);
},

handleOffsettChange: function(scroller, offset) {
if (scroller.direction === 'vertical' && !this.loading){

var heightOfList = scroller.size.height - scroller.containerBox.height;

if (offset.y > 0){
//console.log('up');
this.handlePrevious(scroller, offset, heightOfList);
}

if (offset.y < (heightOfList * -1)) {
//console.log('down');
this.handleNext(scroller, offset, heightOfList);
}
}
},

//private
handlePrevious: function(scroller, offset, heightOfList){
if (scroller.direction === 'vertical' && !this.loading){
if (offset){
Ext.Element.cssTranslate(this.previousEl, {x:0, y:offset.y-75});
if (offset.y > 75){
// state 1
if (this.state !== 1){
this.prevState = this.state;
this.state = 1;
this.previousTpl.overwrite(this.previousEl, {h:offset.y,m:this.langReleasePrevious,l:this.lastUpdate});
Ext.Anim.run(this.previousEl.select('.arrow').first(),'rotate',{dir:'ccw',fromAngle:0,toAngle:180});
}
}else if (!scroller.isDragging()){
// state 3
if (this.state !== 3){
this.prevState = this.state;
this.state = 3;
if (this.prevState == 1){
this.loading = true;
this.lastUpdate = new Date();
this.previousEl.hide();
if (this.previousFn){
this.previousFn.call(this,this.previousComplete,this);
}else{
this.cmp.getStore().load();
}
}
}
}else{
// state 2
if (this.state !== 2){
this.prevState = this.state;
this.state = 2;
this.previousTpl.overwrite(this.previousEl, {h:offset.y,m:this.langPullPrevious,l:this.lastUpdate});
this.previousEl.show();
if (this.prevState == 1){
Ext.Anim.run(this.previousEl.select('.arrow').first(),'rotate',{dir:'cw',fromAngle:180,toAngle:0});
}
}
}
}
}
},
handleNext: function(scroller, offset, heightOfList){
if (scroller.direction === 'vertical' && !this.loading){
if (offset){
Ext.Element.cssTranslate(this.nextEl, {x:0, y:offset.y});
if (offset.y < ((heightOfList + 75)*-1)){
// state 1
if (this.state !== 1){
this.prevState = this.state;
this.state = 1;
this.nextTpl.overwrite(this.nextEl, {h:offset.y,m:this.langReleaseNext,l:this.lastUpdate});
Ext.Anim.run(this.nextEl.select('.arrow').first(),'rotate',{dir:'ccw',fromAngle:180,toAngle:0});
}
}else if (!scroller.isDragging()){
// state 3
if (this.state !== 3){
this.prevState = this.state;
this.state = 3;
if (this.prevState == 1){
this.loading = true;
this.lastUpdate = new Date();
this.nextEl.hide();
if (this.nextFn){
this.nextFn.call(this,this.nextComplete,this);
}else{
this.cmp.getStore().load();
}
}
}
}else{
// state 2
if (this.state !== 2){
this.prevState = this.state;
this.state = 2;
this.nextTpl.overwrite(this.nextEl, {h:offset.y,m:this.langPullNext,l:this.lastUpdate});
this.nextEl.show();
if (this.prevState == 1){
Ext.Anim.run(this.nextEl.select('.arrow').first(),'rotate',{dir:'cw',fromAngle:180,toAngle:0});
}
}
}
}
}
},
//private
previousComplete: function(){
this.loading = false;
this.lastUpdate = new Date();
this.previousTpl.overwrite(this.previousEl, {h:0,m:this.langPullPrevious,l:this.lastUpdate});
},
nextComplete: function(){
this.loading = false;
this.lastUpdate = new Date();
this.nextTpl.overwrite(this.nextEl, {h:0,m:this.langPullNext,l:this.lastUpdate});
}
});

Ext.preg('listpullpager', mobile.plugins.ListPullPager);

CSS


div.pullprevious, div.pullprevious div.msgwrap {
background-color: #e1e1e1 !important;
}

div.pullprevious span.arrow {
width: 32px;
height: 60px;
position: absolute;
top: 0;
left: 10px;
background-image: url('../images/blackArrow.png');
background-repeat: no-repeat;
margin: 10px 0 0 25px;
}

div.loadingspacer span.loading {
width: 32px;
height: 60px;
position: absolute;
top: 0;
left: 10px;
background-image: url('../images/loader.gif');
background-repeat: no-repeat;
background-position: 0 7px;
}

div.pullprevious span.msg, div.loadingspacer span.msg {
width: 80%;
text-align: center;
font-size: 0.9em;
position: absolute;
top: 12px;
left: 40px;
margin: 5px 0 5px 40px;
font-weight: bold;
}

div.pullprevious span.lastupdate {
width: 80%;
text-align: center;
font-size: 0.7em;
position: absolute;
top: 25px;
left: 40px;
margin: 15px 0 5px 40px;
}

div.pullnext, div.pullnext div.msgwrap {
background-color: #e1e1e1 !important;
}

div.pullnext span.arrow {
width: 32px;
height: 60px;
position: absolute;
top: 0;
left: 10px;
background-image: url('../images/blackArrow.png');
background-repeat: no-repeat;
margin: 10px 0 0 25px;
-webkit-transform: rotate(180deg);
}

div.pullnext span.msg, div.loadingspacer span.msg {
width: 80%;
text-align: center;
font-size: 0.9em;
position: absolute;
top: 12px;
left: 40px;
margin: 5px 0 5px 40px;
font-weight: bold;
}

div.pullnext span.lastupdate {
width: 80%;
text-align: center;
font-size: 0.7em;
position: absolute;
top: 25px;
left: 40px;
margin: 15px 0 5px 40px;
}

mitchellsimoens
18 Dec 2010, 7:16 AM
Have you thought about forking his Git repos?

https://github.com/VinylFox/Ext.ux.touch.ListPullRefresh

VinylFox
18 Dec 2010, 6:39 PM
Wow, what a cool idea. Thanks for sharing.

As Mitch said, it would be really cool if you put this code up on Github, or if you like I could throw it in with my ListPull repo on Github.

SimonFlack
19 Dec 2010, 10:54 PM
Glad you liked it.

https://github.com/SimFla/ListPullPager

This is my first time using Github. No readme.rdoc yet.

Hopefully I will have some more stuff up there soon.

VinylFox
20 Dec 2010, 10:46 AM
Cool.

To get the most bang for the buck out of Github, you should really 'fork' my code and work from that, then it lets me merge your changes with mine and mine with yours, so we can both make changes and both take advantage of those changes with very little effort.

SimonFlack
20 Dec 2010, 11:07 AM
Ok. Cool. As soon as I figure Github out (I'm a svn guy) I'll give it a try. I dont want to break anything. Feel free to throw it in your repo and I can fork from that version if I need to make changes.

I just created a Fork of Ext.ux.touch.ListPullRefresh....hehe this is like learning to "crawl" again.

Are you planning on merging the "paging" support into the same plugin as "refresh" or creating a seperate plugin altogether.

Send me a mail at [SNIP] if you want me to do anything.... Or have any more Github tips... I need them ;-)

VinylFox
21 Dec 2010, 3:12 AM
I understand your pain, it took me forever to figure out Git. Luckily I had friends using it that were able to help.

I was thinking that one base plugin could do both things, since they are very similar. They could be much more configurable than what I coded. Ill shoot ya an email (removed your email from post so you don't get spammed).

gkatz
29 Dec 2010, 8:04 AM
Hi;
I want to implement a 'more' button @ the end of a list (ala mobile facebook lists). it is simply a button in the end of the list (but is a 'first class citizen' of the list) that you can push to get more data.
I am having some problems with how to implent the UI side (no problems understanding how paging works). my button always disapears probably because the list refreshes it self from the store.
could you guys give me some pointers on which events to listen to etc...? (as you have had lots of experience with your list extentions.)
thanks in advance.

mitchellsimoens
29 Dec 2010, 8:06 AM
This isn't a button. It just basically detects when it has been scrolled down and then loads more records.

gkatz
29 Dec 2010, 8:09 AM
http://www.sencha.com/forum/showthread.php?119818-More-List&p=555583#post555583
posted in the help forum.
sorry for the thread highjacking.

mitchellsimoens
29 Dec 2010, 8:11 AM
All you want is to add a button to the end of the list?

Just a hint, we should really keep this thread only to this plugin. Yeah your request is similar but not to this plugin so you should really have posted in the Help forum.

aeiz
2 Mar 2011, 1:08 PM
Thanks for this! I might add a scrollto when new data is load in, because it doesn't automatically show what's at the top of each page. It maintains the previous scroll position even after the new page of data is loaded in.

Old McStopher
29 Jul 2011, 2:06 PM
@SimonFlack, bravo! Works perfectly. I'm setting it up to make ajax calls as necessary.

Premier
19 Aug 2011, 1:59 AM
Please can you give me a complete example with paging on local store?

I'm unable to use pageSize, currentPage, and nextPage, prevPage in Sencha Touch