Hi,
thank you for continuing to work on this but this is implemented in Sencha Touch now. Have a look at the documentation:
http://dev.sencha.com/deploy/touch/docs/
search for ListPagingPlugin.
Regards,
Markus
Printable View
Hi,
thank you for continuing to work on this but this is implemented in Sencha Touch now. Have a look at the documentation:
http://dev.sencha.com/deploy/touch/docs/
search for ListPagingPlugin.
Regards,
Markus
Yeah, look at the dates.
https://github.com/j-mcnally/Sencha2-PullToRefresh
Based on your great plugin
Will this plugin be available in Sencha Touch 2.0? I can't see it preview3.
Check src/plugin/PullRefresh.js :) Looking at it right now.
I have ported this:
https://github.com/j-mcnally/Sencha2-PullToRefresh
That great! but had some bugs,i modify and extend it!
Usage:
Code:plugins: ["listpager"]
Code:plugins: ["listpullpager"]
Plugin:Code:plugins: [{ptype:"listpullpager",isAutoButtons:false}]
Code:Ext.plugins.ListPaging = Ext.extend(Ext.util.Observable, {
isAutoButtons:true,
init:function (list) {
this.store = list.store;
list.load = this.load;
if (this.isAutoButtons) {
list.prevBtn = this.prevBtn = new Ext.Button({text:"1", handler:this.onPrevTap, ui:"back", scope:this});
list.nextBtn = this.nextBtn = new Ext.Button({text:"1", handler:this.onNextTap, ui:"forward", scope:this});
list.reloadBtn = this.reloadBtn = new Ext.Button({iconMask:true,ui:'plain',iconCls:'refresh',handler:this.onRefreshAction, scope:this});
}
this.store.on("load", this.handleStoreLoad, this);
},
onPrevTap:function () {
this.loadPage(-1);
},
onNextTap:function () {
this.loadPage(1);
},
onRefreshAction:function() {
this.loadPage(0);
},
handlePrevPage:function () {
this.loadPage(-1);
},
handleNextPage:function () {
this.loadPage(1);
},
reload:function () {
this.loadPage(0);
},
load:function() {
var store = this.store;
store.currentPage = 1;
store.baseParams["start"] = 0;
store.baseParams["limit"] = this.store.pageSize;
store.load({params:this.store.baseParams});
},
loadPage:function (cpage) {
var store = this.store;
var totalNum = this.getTotalRecs();
var numPages = Math.ceil(totalNum / store.pageSize);
var page = this.store.currentPage + cpage;
if (page < 1) {
page = 1;
}
if (page > numPages) {
page = numPages;
}
store.currentPage = page;
store.baseParams["start"] = (page - 1) * this.store.pageSize;
store.baseParams["limit"] = this.store.pageSize;
store.load({params:this.store.baseParams});
},
getTotalPage:function () {
var store = this.store;
var totalNum = this.getTotalRecs();
return Math.ceil(totalNum / store.pageSize);
},
getTotalRecs:function () {
var store = this.store;
var proxy = store.getProxy();
var reader = proxy.getReader();
return reader.getTotal(reader.rawData);
},
handleStoreLoadBtn:function (store, pageMatch) {
var currentPage = store.currentPage;
if (currentPage > 1) {
this.prevBtn.setText((currentPage - 1) + "/" + pageMatch);
this.prevBtn.enable();
} else {
this.prevBtn.setText(pageMatch == 0 ? 0 : 1);
this.prevBtn.disable();
}
if (currentPage < pageMatch - 1) {
this.nextBtn.setText((currentPage + 1) + "/" + pageMatch);
this.nextBtn.enable();
} else {
this.nextBtn.setText(pageMatch);
this.nextBtn.disable();
}
},
handleStoreLoad:function (store, recs, success) {
if (success) {
var totalNum = this.getTotalRecs();
var numPages = Math.ceil(totalNum / store.pageSize);
if (store.currentPage > numPages) store.currentPage = numPages;
if (store.currentPage < 1) store.currentPage = 1;
if (this.isAutoButtons) {
this.handleStoreLoadBtn(store, numPages);
}
}
}
});
Ext.preg('listpager', Ext.plugins.ListPaging);
Code: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)'
};
}
})
});
Code:Ext.plugins.ListPullPager = Ext.extend(Ext.plugins.ListPaging, {
langPullPrevious: 'Pull down to load {0} of {1},total {2}',
pullPreviousText: 'Pull down to load previous...',
langReleasePrevious: 'Release to load previous...',
langPullNext: 'Pull up to load page {0} of {1} ,total {2}',
pullNextText: 'Pull up to load next...',
langReleaseNext: 'Release to load next...',
langLoading: 'Loading...',
loading: false,
// private
init: function(list) {
this.list = list;
this.lastUpdated = new Date();
list.loadingText = undefined;
list.on('render', this.initPullHandler, this);
Ext.plugins.ListPullPager.superclass.init.apply(this, arguments);
},
// private
initPullHandler: function() {
//Previous
this.previousTpl = new Ext.XTemplate(
'<div class="x-list-pullprevpage">',
'<div class="x-list-pullprevpage-arrow"></div>',
'<div class="x-list-pullrefresh-wrap">',
'<h3 class="x-list-pullrefresh-message">{m}</h3>',
'<div class="x-list-pullrefresh-updated">Last Updated: <span>{l:date("m/d/Y h:iA")}</span></div>',
'</div>',
'</div>'
);
this.previousEl = this.previousTpl.insertBefore(this.list.scroller.el,
{m:this.pullPreviousText,l:this.lastUpdated}, true);
this.previousEl.hide();
Ext.Element.cssTranslate(this.previousEl, {x:0, y:-75});
//Next
this.nextTpl = new Ext.XTemplate(
'<div class="x-list-pullnextpage">',
'<div class="x-list-pullnextpage-arrow"></div>',
'<div class="x-list-pullrefresh-wrap">',
'<h3 class="x-list-pullrefresh-message">{m}</h3>',
'<div class="x-list-pullrefresh-updated">Last Updated: <span>{l:date("m/d/Y h:iA")}</span></div>',
'</div>',
'</div>'
);
this.nextEl = this.nextTpl.insertAfter(this.list.scroller.el,
{m:this.pullNextText,l:this.lastUpdated}, true);
this.nextEl.hide();
Ext.Element.cssTranslate(this.nextEl, {x:0, y:-90});
this.list.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:'+offset);
this.handlePrevious(scroller, offset, heightOfList);
}
if (offset.y < (heightOfList * -1)) {
//console.log('down:'+offset);
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 - 76});
if (offset.y > 90) {
// state 1
if (this.state !== 1) {
this.prevState = this.state;
this.state = 1;
this.previousTpl.overwrite(this.previousEl, {m:this.langReleasePrevious,l:this.lastUpdated});
Ext.Anim.run(this.previousEl.select('.x-list-pullprevpage-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;
this.previousEl.hide();
if (this.prevState == 1) {
this.loading = true;
this.lastUpdated = new Date();
this.loadPage(-1);
this.callback = this.previousComplete();
}
}
} else {
// state 2
if (this.state !== 2) {
this.prevState = this.state;
this.state = 2;
this.previousTpl.overwrite(this.previousEl, {m:this.pullPreviousText,l:this.lastUpdated});
this.previousEl.show();
if (this.prevState == 1) {
Ext.Anim.run(this.previousEl.select('.x-list-pullprevpage-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 + 90) * -1)) {
// state 1
if (this.state !== 1) {
this.nextState = this.state;
this.state = 1;
this.nextTpl.overwrite(this.nextEl, {m:this.langReleaseNext,l:this.lastUpdated});
Ext.Anim.run(this.nextEl.select('.x-list-pullnextpage-arrow').first(), 'rotate', {dir:'ccw',fromAngle:180,toAngle:0});
}
} else if (!scroller.isDragging()) {
// state 3
if (this.state !== 3) {
this.nextState = this.state;
this.state = 3;
this.nextEl.hide();
if (this.nextState == 1) {
this.loading = true;
this.lastUpdated = new Date();
this.loadPage(1);
this.callback = this.nextComplete();
}
}
} else {
// state 2
if (this.state !== 2) {
this.nextState = this.state;
this.state = 2;
this.nextTpl.overwrite(this.nextEl, {m:this.pullNextText,l:this.lastUpdated});
this.nextEl.show();
if (this.nextState == 1) {
Ext.Anim.run(this.nextEl.select('.x-list-pullnextpage-arrow').first(), 'rotate', {dir:'cw',fromAngle:0,toAngle:180});
}
}
}
}
}
},
//private
previousComplete: function() {
this.loading = false;
this.lastUpdated = new Date();
this.previousTpl.overwrite(this.previousEl, {m:this.pullPreviousText,l:this.lastUpdated});
},
nextComplete: function() {
this.loading = false;
this.lastUpdated = new Date();
this.nextTpl.overwrite(this.nextEl, {m:this.pullNextText,l:this.lastUpdated});
},
handleStoreLoad:function (store, recs, success) {
Ext.plugins.ListPullPager.superclass.handleStoreLoad.apply(this, arguments);
var totalNum = this.getTotalRecs();
var numPages = Math.ceil(totalNum / store.pageSize);
if (store.currentPage > numPages) store.currentPage = numPages;
if (store.currentPage < 1) store.currentPage = 1;
var c = store.currentPage;
this.pullPreviousText = Ext.util.Format.format(this.langPullPrevious, c > 1 ? c - 1 : 1, numPages, totalNum);
this.pullNextText = Ext.util.Format.format(this.langPullNext, c < numPages ? c + 1 : numPages, numPages, totalNum);
if (this.callback) {
this.callback();
}
}
});
Ext.preg('listpullpager', Ext.plugins.ListPullPager);
CSS
Code:.x-list-pullprevpage {
display: -webkit-box;
display: box;
-webkit-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-align: center;
box-align: center;
-webkit-box-pack: center;
box-pack: center;
left: 0;
width: 100%;
height: 0
}
.x-list-pullnextpage {
display: -webkit-box;
display: box;
-webkit-box-orient: horizontal;
box-orient: horizontal;
-webkit-box-align: center;
box-align: center;
-webkit-box-pack: center;
box-pack: center;
position: absolute;
left: 0;
width: 100%;
height: 0
}
.x-list-pullrefresh-message {
font-weight: bold;
font-size: 1.0em;
margin-bottom: 0.1em;
text-align: center
}
.x-list-pullprevpage-arrow {
width: 2.5em;
height: 3.0em;
-webkit-mask: center center url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAA8CAYAAAAUufjgAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wBHwEEFZRBU1UAAAI7SURBVGje7dq/a5NRFMbxz6ttHSym4CK4+A8UtZPugpOrqKNiETqIq2tB3EQoIgjiIhZdCoIguLu1SkGFLi6Cmz+KQ432OvQGXjRN75vcN4ltDpwpL9xvnvecc885SRFCMMy2z5DbGBRFkfr8/kzn/k55KISwBZhoRUbATYRkBasqnsGadRyYU8GiLgXHB5IkFb71WEYF7UkFx0cKtiuGw2ohhP/kqku0CRzPdO5b/KwjSSaGOUmGHlBGwNrq4IF+KzgqM/18xQdxPtO5T/FjV8TgrgOcGGXxbs7iKdzMdO4tfN2TzcLAsvgEGgmFOhfgqYRC/Q1vWoAbuKJ/y6RLCauR22UF32MJF4ckeZ/g3d8xuIRpzAwYbjmybAVrCKG8fmvgHg4PCO4LrsX4E0L4B1BU8Y7+Lzc3cQOr5ZukXZlZxaP4Tfpp98tw273ist3F6T7Bvcb1dndxJ8AGFnGkZrjPuNCKuyqAYkY/rHEn08TlmLlddTPLWIiAdfjCdnApMVi2BziTWb1XuLpTP5gKOIWXOJoJ7hPO7tRyVQGEk3ieIR6bOIeV3B31Cubj9diLz6fAVY3Bsj2OCnRjL2JJSZ5JugE8FAvrsYpwH2Ph/15poOtyqpvBeuwjU3y9my6pF0CYw69En+t27Ox1Ll609ZNWJ3/Wy1zcK2ADax3g1hJmnVoBWwPXRhu4jfiZQQPCbBvA2Ryrj5y7mXI8LubazeQEnMSH6JPDCNiaZ6ZzbreK0d9SRoAjwM72B0xIAaqN33EkAAAAAElFTkSuQmCC') no-repeat;
-webkit-mask-size: 2em 3em;
-webkit-transform: rotate(0deg);
background-color: #111
}
.x-list-pullnextpage-arrow {
width: 2.5em;
height: 3.0em;
-webkit-mask: center center url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAA8CAYAAAAUufjgAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9wBHwEEFZRBU1UAAAI7SURBVGje7dq/a5NRFMbxz6ttHSym4CK4+A8UtZPugpOrqKNiETqIq2tB3EQoIgjiIhZdCoIguLu1SkGFLi6Cmz+KQ432OvQGXjRN75vcN4ltDpwpL9xvnvecc885SRFCMMy2z5DbGBRFkfr8/kzn/k55KISwBZhoRUbATYRkBasqnsGadRyYU8GiLgXHB5IkFb71WEYF7UkFx0cKtiuGw2ohhP/kqku0CRzPdO5b/KwjSSaGOUmGHlBGwNrq4IF+KzgqM/18xQdxPtO5T/FjV8TgrgOcGGXxbs7iKdzMdO4tfN2TzcLAsvgEGgmFOhfgqYRC/Q1vWoAbuKJ/y6RLCauR22UF32MJF4ckeZ/g3d8xuIRpzAwYbjmybAVrCKG8fmvgHg4PCO4LrsX4E0L4B1BU8Y7+Lzc3cQOr5ZukXZlZxaP4Tfpp98tw273ist3F6T7Bvcb1dndxJ8AGFnGkZrjPuNCKuyqAYkY/rHEn08TlmLlddTPLWIiAdfjCdnApMVi2BziTWb1XuLpTP5gKOIWXOJoJ7hPO7tRyVQGEk3ieIR6bOIeV3B31Cubj9diLz6fAVY3Bsj2OCnRjL2JJSZ5JugE8FAvrsYpwH2Ph/15poOtyqpvBeuwjU3y9my6pF0CYw69En+t27Ox1Ll609ZNWJ3/Wy1zcK2ADax3g1hJmnVoBWwPXRhu4jfiZQQPCbBvA2Ryrj5y7mXI8LubazeQEnMSH6JPDCNiaZ6ZzbreK0d9SRoAjwM72B0xIAaqN33EkAAAAAElFTkSuQmCC') no-repeat;
-webkit-mask-size: 2em 3em;
-webkit-transform: rotate(180deg);
background-color: #111
}
Hello Everyone,
I'm currently attempting to apply this plugin to a list in which accesses the Twitter API. My question is, if there is a PullRefresh.js, why do we need a plugin to do this? I understand that the Sencha developers are trying to watch the build size, so does this mean they are simply adding a place holder for an optional plugin?
I followed the Readme for the Sencha Touch 2 port of the pull to refresh plugin and am receiving this error. Wasn't sure if anyone could shed some light on what may be happening.
Thanks!
very nice, very helpful. But can someone help me how can I use this plugin to implement the same pull to refresh for bottom of the list? Thanks in advance guys.