NEW Save and restore tab state upon CMS navigation (fixes #7647)

Implemented independently of URL state to ensure that
state is retained on every user interaction, rather than
having to add it to each URL specifically.
Same reasons for not saving it as HTML5 history metadata,
as that's only inspected on history events, not
normal CMS navigation.
This commit is contained in:
Ingo Schommer 2012-07-13 16:46:23 +02:00
parent d45b33e9c7
commit 155758f546

View File

@ -162,6 +162,9 @@ jQuery.noConflict();
if(abort) return;
}
// Save tab selections so we can restore them later
this.saveTabState();
if(window.History.enabled) {
// Active menu item is set based on X-Controller ajax header,
// which matches one class on the menu
@ -208,12 +211,6 @@ jQuery.noConflict();
return false;
}
// save tab selections in order to reconstruct them later
var selectedTabs = [];
form.find('.cms-tabset').each(function(i, el) {
if($(el).attr('id')) selectedTabs.push({id:$(el).attr('id'), selected:$(el).tabs('option', 'selected')});
});
// get all data from the form
var formData = form.serializeArray();
// add button action
@ -223,6 +220,9 @@ jQuery.noConflict();
// as automatic browser ajax response redirects seem to discard the hash/fragment.
formData.push({name: 'BackURL', value:History.getPageUrl()});
// Save tab selections so we can restore them later
this.saveTabState();
// Standard Pjax behaviour is to replace the submitted form with new content.
// The returned view isn't always decided upon when the request
// is fired, so the server might decide to change it based on its own logic,
@ -242,17 +242,7 @@ jQuery.noConflict();
var newContentEls = self.handleAjaxResponse(data, status, xhr);
if(!newContentEls) return;
var newForm = newContentEls.filter('form');
// Re-init tabs (in case the form tag itself is a tabset)
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
// re-select previously saved tabs
$.each(selectedTabs, function(i, selectedTab) {
newForm.find('#' + selectedTab.id).tabs('select', selectedTab.selected);
});
newForm.trigger('aftersubmitform', {status: status, xhr: xhr, formData: formData});
newContentEls.filter('form').trigger('aftersubmitform', {status: status, xhr: xhr, formData: formData});
}
}, ajaxOptions));
@ -337,7 +327,7 @@ jQuery.noConflict();
* Can be hooked into an ajax 'success' callback.
*/
handleAjaxResponse: function(data, status, xhr) {
var self = this;
var self = this, url, selectedTabs;
// Pseudo-redirects via X-ControllerURL might return empty data, in which
// case we'll ignore the response
@ -401,8 +391,14 @@ jQuery.noConflict();
if(origVisible) newContentEl.css('visibility', 'visible');
});
// Re-init tabs (in case the form tag itself is a tabset)
var newForm = newContentEls.filter('form');
if(newForm.hasClass('cms-tabset')) newForm.removeClass('cms-tabset').addClass('cms-tabset');
this.redraw();
this.restoreTabState();
return newContentEls;
},
@ -435,6 +431,46 @@ jQuery.noConflict();
$(window).trigger('statechange');
$(this).redraw();
},
/**
* Save tab selections in order to reconstruct them later.
* Requires HTML5 sessionStorage support.
*/
saveTabState: function() {
if(typeof(window.sessionStorage)=="undefined") return;
var selectedTabs = [], url = this._tabStateUrl();
this.find('.cms-tabset,.ss-tabset').each(function(i, el) {
var id = $(el).attr('id');
if(!id) return; // we need a unique reference
selectedTabs.push({id:id, selected:$(el).tabs('option', 'selected')});
});
if(selectedTabs) window.sessionStorage.setItem('tabs-' + url, JSON.stringify(selectedTabs));
},
/**
* Re-select previously saved tabs.
* Requires HTML5 sessionStorage support.
*/
restoreTabState: function() {
if(typeof(window.sessionStorage)=="undefined") return;
var self = this, url = this._tabStateUrl(),
data = window.sessionStorage.getItem('tabs-' + url),
selectedTabs = data ? JSON.parse(data) : false;
if(selectedTabs) {
$.each(selectedTabs, function(i, selectedTab) {
self.find('#' + selectedTab.id).tabs('select', selectedTab.selected);
});
}
},
_tabStateUrl: function() {
return History.getState().url
.replace(/\?.*/, '')
.replace(/#.*/, '')
.replace($('base').attr('href'), '');
}
});