Capture page number in Ext.PagingToolbar - extjs

I'm working on a ExtJS.Grid that uses a Ext.data.Store with jsonp proxy and Ext.PagingToolbar to control paging. It's all working fine.
But some users are complaining that they further browse pages, leave the grid, and when they come back they are back to page 1. They want "the grid to remember" the page they were and starts on it.
I use a Ext.onReady(function(){},false); to define all components and another Ext.onReady(function(){}); to create the grid with a store.loadPage(1); to make the first load after everything is done.
If I could listen to some event from the Ext.PagingToolbar, when a new load happens, and capture the page it was used, I could pehaps store it in some cookie or something, and retrieve it to load that page again.
I looked on http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.toolbar.Paging and found no event that could be used. Anybody has any idea of where I could do it?

You can track the change event of the Ext.toolbar.Paging and remember the currentPage in a cookie.
pagingtoolbar.on('change', function(pb, pageData) {
Ext.util.Cookies.set('lastGridPage', pageData.currentPage, new Date('1/1/2016'));
});
And setup your grid to load that page on afterrender
grid.on('afterrender', function() {
var pageNumber = Ext.util.Cookies.get('lastGridPage') || 1;
grid.store.loadPage(pageNumber);
})

Related

Browser back button doesn't trigger reload after using Angular's $location.path() update

Situation:
On one of the views of my AngularJS app I have two pagination buttons that use $http to request the next and previous data. I'm using ng-click="getNext(url)" rather than an anchor tag with href="#/items/:itemId". The reason I'm doing this is so that I can quickly page through my content asynchronously w/o triggering a page reload. This works just fine, but using this method bypasses updating the page's URL so its possible to have your current content out of sync with your URL's id (i.e. path is #/items/3 but you're currently viewing item 9). This can be easily fixed by updating the URL in the JS using $location.path('items/' + rsp.id). Now I can fetch data in an async manner and still be able to refresh, bookmark, send links and have the correct/current item display.
Problem:
The problem with this is if a user hits getNext() a few times and then tries to go back using the browser's back button the URL updates like it should but for some reason the browser doesn't perform a refresh–it just sits there and updates the URL. This only occurs with when the item in history is from the same view and I have updated the ID with the location service.
Any ideas would be appreciated.
What I tried so far
Promises + Flags
I've been playing with window.onpopstate, but as of right now I don't have any way to have window.onpopstate differentiate between a browser click and a UI click that updates the URL with $location.path(); Right now it fires the event regardless of the source. So I tried setting a flag to assume that every time this event fires its a browser event, but when its a UI-based event I can disabled that flag because my _myRequestFn() will handle it. Even with this promise setup it still fires the window.onpopstate when _myRequestFn() is fired.
var flag = true; // Assume all requests are browser-based
window.onpopstate = function() {
if (flag) {
$route.reload();
}
console.log('onpopstate fired');
};
_myRequestFn = function(id) {
someService.getMyData(id)
.then(function(rsp) {
// Do a bunch of stuff including...
$location.path('items/' + rsp.id);
return rsp;
})
.then(function() {
// Everything is done reset flag
flag = true;
});
};
$scope.getNext(url) {
flag = false;
_myRequestFn(url);
};
Spoofing
Hitting back through #/item/5 > #/item/4 > #/item/3 just updates the URL and not the path, but if the history has a different param #/thing/2 > #/item/2 that triggers a page refresh. Since the browser back button works if the history is from a different param I wanted to see if I loaded a different param it would work. So I created an #/item-a and #/item-b route that loaded the same template and used the same controllers, just toggled from a/b with each request. I would never recommend this solution to someone, I was more just seeing if I could get the refresh to trigger.
Update
Lots of people on IRC are suggesting that I use UI-Router. I'm really trying to use the out of the box Angular solution. Refactoring my whole routing setup to use UI-Router is not an optimal solution.
app.config(['$locationProvider',
function($locationProvider) {
// Enable html5 mode
$locationProvider.html5Mode(true);
}]);
From the docs:
In HTML5 mode, the $location service getters and setters interact with the browser URL address through the HTML5 history API. This allows for use of regular URL path and search segments, instead of their hashbang equivalents.

How do I listen to store's refresh event?

I'm using Sencha Touch 2 and wonder how I listen to the Store's refresh event in my Ext.dataview.List? I want that my list automatically updates when there are new records in my store, so the refresh event seems to do the job for me, but how do I set up a listener?
Edit: Thanks to Anand Gupta I realized my problem isn't refreshing the list but just displaying it. So I will give you some more information and hope you can help me. I use NavigationView inside tabpanel. I have one list loading from localstorage which works just fine, if you tap disclose indicator you come to a form with a button "auto complete".
By tapping autocomplete the following method is called:
e.stopEvent();
var lastname = this.getNewUserForm().down("textfield[name=lastname]").getValue();
if(lastname!=="")
{
var complete = this.getApplication().getController("Complete");
this.getUserNav().push(complete.getView());
complete.setSearch(this.getNewUserForm().down("textfield[name=firstname]").getValue(), lastname);
}
else
{
//errormessage
}
The getView() method is a ref with auto create and the "setSearch" Message on Complete Controller simply loads the Store through jsonP Proxy:
var store = Ext.getStore("Playernames");
store.setParams({firstname:firstname, lastname:lastname});
store.load({callback: function(){
console.log(this);
}});
I added a log to see that the store is properly loaded and store is properly loaded.
Thanks for help
Ok after some more hard search I found my bug: I had a List view embedded in a Panel with an undefined layout. So I changed the layout to "fit" and it works fine.

AngularJS - using Angular UI router - how to fetch the next content via AJAX without removing the current content

I'm using Angular UI router in my app. This is what I'm doing.
A main view contains a child view and a div container for "pagination"
By default, initially, a first set of contents is loaded
When a user clicks on "next page", next set of contents is loaded (with the URL also being changed to /content/2 (where 2 indicates the next page number)
All is working well, but each time the contents are loaded, it goes "blank" before it loads. So it seems like it's reloading the view (which is obvious).
What I would like to do is reload the content without having that "blank" page. How can I achieve this?
At first thought, I think you could you the same approach as infinite-scroll, which is what I'm using. So you make a GET request to the server to get new content and push it to the list on clicking 'next'. However, since the URL changes also. This will cause the controller to be reloaded. You can actually bypass this by setting reloadOnSearch to false.

Backbone.js: How to utilize router.navigate to manipulate browser history?

I am writing something like a registration process containing several steps, and I want to make it a single-page like system so after some studying Backbone.js is my choice.
Every time the user completes the current step they will click on a NEXT button I create and I use the router.navigate method to update the url, as well as loading the content of the next page and doing some fancy transition with javascript.
Result is, URL is updated which the page is not refreshed, giving a smooth user experience. However, when the user clicks on the back button of the browser, the URL gets updated to that of a previous step, but the content stays the same. My question is through what way I can capture such an event and currently load the content of the previous step and present that to the user? Or even better, can I rely on browser cache to load that previously loaded page?
EDIT: in particular, I'm trying something like mentioned in this article.
You should not use route.navigate but let the router decide which form to display based on the current route.
exemple :
a link in your current form of the registration process :
<a href="#form/2" ...
in the router definition :
routes:{
"form/:formNumber" : "gotoForm"
},
gotoForm:function(formNumber){
// the code to display the correct form for the current url based on formNumber
}
and then use Backbone.history.start() to bootstrap routing

Single Page website with CakePHP

I'm currently working on a single-page scrollable website (5 pages displaying as a single page) using CakePHP. I have worked on each controller action and everything runs well. I have one layout for the entire app and a view for each action. My challenge is finding a way to load the view of each action without reloading the page inside the layout. Should I just put all the view content inside the layout (without echoing $content_for_layout) or could there be a better way to do it?
Considering the div you want to update has the id #content:
$.ajax({
url:"http://yourdomain.com/controller/action",
context:document.body,
dataType:"html",
data:{id:123}, // in case you need to pass some params
success:function(data){
$("#content").html(data);
}
})
The action must return the HTML you want to display inside that div. If you want to have each pags loaded in different div's, you will have to create one div for each page and call AJAX for each one.
When the page is loaded for the first time, you can just pull the data for whatever default action you defined. Then, when you want to change the content, just call AJAX.

Resources