PDA

View Full Version : Bookmarking and History in extjs ?



vasanth.kvj
9 Nov 2011, 12:56 AM
Can any one tel me how to implement handling mechanism for History in extjs?

I'm able to add history using hidden history form and the method - Ext.util.History.add(id). My page contains panels,tree and grids. Suppose if I'm maintaining history for an node, i want the details of tree, panel and the viewport it belongs to. ( currently I'm doing this manually by adding delimiters ) so that when user clicks back\forward browser buttons i can render the elements.

Is there any way to maintain the state of all elements at one shot inside history stack? My application is growing bigger. i cant maintain history by manually adding Ext.util.History.add(id + delimiter + other id's) for all actions.

Need some direction to implement bookmarking in extjs.. Thanks in Advance !

mitchellsimoens
16 Nov 2011, 12:29 PM
I don't believe that restoring an app based on the hash is working right now. Using the history example it's not working.

isuvaish
4 Mar 2013, 10:36 PM
I need some help with the same. I'm using hash, clearly I can't restore the app back when I use its " id + delimiter + other id's" URL to navigate to the page directly.

Please help !



var tabPanel=new Ext.TabPanel({

// Configured for use in Viewport as needed
width:1000,
height:700,
activeTab:0,
layout:'fit',
region:'north',
renderTo:Ext.getBody(),
listeners:{
tabchange:function(tabPanel,currTab){
window.location.hash='#'+currTab.itemId;
}
},
items:[
//included tabs
]
});

var token=window.location.hash.substr(1);
if (token){

var tab=tabPanel.getActiveTab(token);
if (!tab){
tab=new Ext.Panel({
itemId:token,
title:'tab:'+token
});
tabPanel.add(tab);
}

tabPanel.setActiveTab(tab);
}



The tab id gets appended to the page url. When I try using the url (Copy/paste) to reload the tab again, it goes back to my first tab. (url changes).

Am I going wrong somewhere ? Or am I missing something here ?

vasanth.kvj
4 Mar 2013, 11:25 PM
It would be helpful to understand the requirement if we have sample code and expected behavior. Please post your code.

isuvaish
5 Mar 2013, 2:00 AM
Hope the snippet helps . Am I missing something ?

vasanth.kvj
5 Mar 2013, 2:15 AM
assume your url is like < yourapp > /index.html#myTabs/1

var currentTab = 0,
myUrl = window.location.href.split('#');

if (myUrl && myUrl[1] && myUrl[0] == 'myTabs') {
currentTab = myUrl[1];
}

var tabPanel = new Ext.TabPanel({
// Configured for use in Viewport as needed
width: 1000,
height: 700,
activeTab: currentTab,
layout: 'fit',
region: 'north',
renderTo: Ext.getBody(),
listeners: {
tabchange: function (tabPanel, currTab) {
window.location.hash = '#myTabs/' + currTab.position;
}
},
items: [//included tabs with custom attribute/config (position)]
});

vasanth.kvj
5 Mar 2013, 2:22 AM
also using window.location.hash in IE might reload the page.

In your case for each tab change page reloads.

Instead we can use Ext.util.History

(http: //docs.sencha.com/ext-js/4-1/#!/api/Ext.util.History)

isuvaish
7 Mar 2013, 1:47 AM
I don't quite understand the purpose of the changes you've added. Could you elaborate?

My requirement is that when I change my tab (using tabchange method) , and copy/paste the URL in another browser tab, the activeTab should be the tab id that follows the hash.



<br>
assume your url is like < yourapp > /index.html#myTabs/1<br>
<br>
var currentTab = 0,<br>
&nbsp;&nbsp; &nbsp;myUrl = window.location.href.split('#');<br>
<br>
if (myUrl && myUrl[1] && myUrl[0] == 'myTabs') {<br>
&nbsp;&nbsp; &nbsp;currentTab = myUrl[1];<br>
}<br>
<br>
var tabPanel = new Ext.TabPanel({<br>
&nbsp;&nbsp; &nbsp;// Configured for use in Viewport as needed<br>
&nbsp;&nbsp; &nbsp;width: 1000,<br>
&nbsp;&nbsp; &nbsp;height: 700,<br>
&nbsp;&nbsp; &nbsp;activeTab: currentTab,<br>
&nbsp;&nbsp; &nbsp;layout: 'fit',<br>
&nbsp;&nbsp; &nbsp;region: 'north',<br>
&nbsp;&nbsp; &nbsp;renderTo: Ext.getBody(),<br>
&nbsp;&nbsp; &nbsp;listeners: {<br>
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;tabchange: function (tabPanel, currTab) {<br>
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;window.location.hash = '#myTabs/' + currTab.position;<br>
&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;}<br>
&nbsp;&nbsp; &nbsp;},<br>
&nbsp;&nbsp; &nbsp;items: [//included tabs with custom attribute/config (position)]<br>
});<br>

vasanth.kvj
7 Mar 2013, 2:42 AM
By Default your active Tab is 0.

Whenever the page loads, before rendering your Tab panel, from the url you can get the tab which needs to be the active tab.




var currentTab = 0,
myUrl = window.location.href.split('#');

if (myUrl && myUrl[1] && myUrl[0] == 'myTabs') {
currentTab = myUrl[1];



Now map the “currentTab” to your tab panel



var tabPanel = new Ext.TabPanel({
// Configured for use in Viewport as needed
width: 1000,
height: 700,
activeTab: currentTab,
layout: 'fit',



In app we may have more components, pages etc.. Its good to have an identifier i.e. "myTabs" in the below url, here 1 is your active tab


< yourapp > /index.html#myTabs/1


You might also have url's for other pages as,


< yourapp > /index.html#myGrid/user/editmode
< yourapp > /index.html#myGrid/user/readonly


This will help to map the events, loading the components when refresh/ copy-paste in new tab happens. Depending on id's might be complex. Having myTabs, myGrids as additional token along with id's makes simple to understand.

Sample : http://jsfiddle.net/QQz5X/43/

isuvaish
7 Mar 2013, 5:14 AM
Still having trouble, the active tab goes back to the first tab (Which was set as default).

Please help. Thanks !

vasanth.kvj
8 Mar 2013, 7:49 AM
Its working , can you please check here http://jsfiddle.net/F8J75/ (used random number instead of url split)

isuvaish
10 Mar 2013, 9:52 PM
How does page refresh let my tab stay in the same place ? Your random number generation code moves my current tab to another tab.
Eg : if my current tab is
...apps/Bookmarking/services.html#myTabs/5
and I refresh the page or say, copy the link to a new page in the same/another browser, it should stay in the same tab.


I hope my requirement is clear.

PS: Please try refreshing the output frame for your jsFiddle link, you'll understand what I mean.

isuvaish
10 Mar 2013, 9:58 PM
I have solved the problem currently by saving the current state of the page using the expires config (using Ext.state.Manager and Ext.state.CookieProvider) as follows:

Ext.state.Manager.setProvider(new Ext.state.CookieProvider(
{
expires : new Date(new Date().getTime()
+ (1000 * 60 * 60 * 24 * 7))
}));



However, the url I use should be valid for over any length of time.



Also, when if I last visited URL is .../apps/Bookmarking/services.html#myTabs/5
and I chnage my URL back to .../apps/Bookmarking/services.html, it should go back to my default (first in my case) tab. Instead it navigates back to .../apps/Bookmarking/services.html#myTabs/5.

How can I rectify that ?

vasanth.kvj
10 Mar 2013, 10:47 PM
Random number used since we cannot change or edit the url in jsFiddle.
In your code, instead of random number, get the current url , split it (with #) and make its as tokens.

I hope your application contains MVC pattern, in app.js - before rendering your view get the url token and pass the token as input to that particular view.

Class:



Ext.define('AppName.view.ClassName', {
extend: 'Ext.container.Container',
alias: 'widget.shortname',
id: 'SampleClass',
currentTab: '',
initComponent: function () {

Ext.apply(this, {
items: [{
xtype: 'tabpanel',
width: 1000,
height: 700,
activeTab: this.currentTab,
layout: 'fit',
region: 'north',
renderTo: Ext.getBody(),
listeners: {
tabchange: function (tabPanel, currTab) {
//Change url on tab change
}
}
}]
});
this.callParent(arguments);
}
});

App:



Ext.application({
name: 'AppName',
appFolder: 'app',
controllers: ['AnyController'],

launch: function () {
var myUrl = window.location.href.split('#');

// Tab Page
if (myUrl[0] && myUrl[0] == 'myTabs') {
var currentTabNumber = 0;
if (myUrl[1]) {
currentTabNumber = myUrl[1];
}
Ext.create('AppName.view.ClassName', {
layout: 'auto',
currentTab: currentTabNumber
renderTo: Ext.getBody()
});
}

// Grid Page
if (myUrl[0] && myUrl[0] == 'myGrids') {
// create other pages based on token (myUrl[0])
}
}
});