ENHANCEMENT Reimplemented ModelAdmin history feature as separate javascript file based on jQuery.concrete. It removes any dependencies to PHP code or existing markup, which means it can be disabled if not required.

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92769 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-11-21 03:17:41 +00:00
parent 233221e2e0
commit 650d44dd57
4 changed files with 179 additions and 2 deletions

View File

@ -149,6 +149,7 @@ abstract class ModelAdmin extends LeftAndMain {
Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/ui.tabs.js');
Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery/jquery_improvements.js');
Requirements::javascript(CMS_DIR . '/javascript/ModelAdmin.js');
Requirements::javascript(CMS_DIR . '/javascript/ModelAdmin.History.js');
}
/**

View File

@ -146,3 +146,20 @@ form .message {
margin: .3em 0;
padding: 0.3em;
}
body.ModelAdmin .historyNav {
background: #aaa;
padding: 0 10px;
overflow: auto;
}
body.ModelAdmin .historyNav a {
display: block;
color: white;
margin: 3px 0;
}
body.ModelAdmin .historyNav a.back {
float: left;
}
body.ModelAdmin .historyNav a.forward {
float: right;
}

View File

@ -0,0 +1,156 @@
(function($) {
/**
* A simple ajax browser history implementation tailored towards
* navigating through search results and different forms loaded into
* the ModelAdmin right panels. The logic listens to search and form loading
* events, keeps track of the loaded URLs, and will display graphical back/forward
* buttons where appropriate. A search action will cause the history to be reset.
*
* Note: The logic does not replay save operations or hook into any form actions.
*
* Available Events:
* - historyAdd
* - historyStart
* - historyGoFoward
* - historyGoBack
*
* @todo Switch tab state when re-displaying search forms
* @todo Reload search parameters into forms
*
* @name ss.ModelAdmin
*/
$('.ModelAdmin').concrete('ss', function($){
return/** @lends ss.ModelAdmin */ {
History: [],
Future: [],
onmatch: function() {
var self = this;
this._super();
// generate markup
this.find('#right').prepend(
'<div class="historyNav">'
+ '<a href="#" class="back">&lt; ' + ss.i18n._t('ModelAdmin.HISTORYBACK', 'back') + '</a>'
+ '<a href="#" class="forward">' + ss.i18n._t('ModelAdmin.HISTORYFORWARD', 'forward') + ' &gt;</a>'
+ '</div>'
).find('.back,.forward').hide();
this.find('.historyNav .back').live('click', function() {
self.goBack();
return false;
});
this.find('.historyNav .forward').live('click', function() {
self.goForward();
return false;
});
},
redraw: function() {
this.find('.historyNav .forward').toggle(Boolean(this.Future().length > 0));
this.find('.historyNav .back').toggle(Boolean(this.History().length > 1));
},
startHistory: function(url, data) {
this.trigger('historyStart', {url: url, data: data});
this.setHistory([]);
this.addHistory(url, data);
},
/**
* Add an item to the history, to be accessed by goBack and goForward
*/
addHistory: function(url, data) {
this.trigger('historyAdd', {url: url, data: data});
// Combine data into URL
if(data) {
if(url.indexOf('?') == -1) url += '?' + $.param(data);
else url += '&' + $.param(data);
}
// Add to history
this.History().push(url);
// Reset future
this.setFuture([]);
this.redraw();
},
goBack: function() {
if(this.History() && this.History().length) {
if(this.Future() == null) this.setFuture([]);
var currentPage = this.History().pop();
var previousPage = this.History()[this.History().length-1];
this.Future().push(currentPage);
this.trigger('historyGoBack', {url:previousPage});
// load new location
$('#Form_EditForm').concrete('ss').loadForm(previousPage);
this.redraw();
}
},
goForward: function() {
if(this.Future() && this.Future().length) {
if(this.Future() == null) this.setFuture([]);
var nextPage = this.Future().pop();
this.History().push(nextPage);
this.trigger('historyGoForward', {url:nextPage});
// load new location
$('#Form_EditForm').concrete('ss').loadForm(nextPage);
this.redraw();
}
}
};
});
/**
* A search action will cause the history to be reset.
*/
$('#SearchForm_holder form').concrete('ss', function($) {
return{
onmatch: function() {
var self = this;
this.bind('beforeSubmit', function(e) {
$('.ModelAdmin').concrete('ss').startHistory(
self.attr('action'),
self.serializeArray()
);
});
}
};
});
/**
* We have to apply this to the result table buttons instead of the
* more generic form loading.
*/
$('form[name=Form_ResultsForm] tbody td a').concrete('ss', function($) {
return{
onmatch: function() {
var self = this;
this.bind('click', function(e) {
$('.ModelAdmin').addHistory(self.attr('href'));
});
}
};
});
})(jQuery);

View File

@ -9,7 +9,7 @@
* @todo alias the $ function instead of literal jQuery
*/
(function($) {
//////////////////////////////////////////////////////////////////
// Search form
//////////////////////////////////////////////////////////////////
@ -43,9 +43,12 @@
$('#SearchForm_holder form').concrete({
onmatch: function() {
var self = this;
this.bind('submit', function(e) {
// Import forms are processed without ajax
if(self.is('#Form_ImportForm')) return true;
self.trigger('beforeSubmit');
$('#Form_EditForm').concrete('ss').loadForm(
self.attr('action'),
@ -129,7 +132,7 @@
this.bind('click', function() {
var confirmed = confirm(ss.i18n._t('ModelAdmin.REALLYDELETE', 'Really delete?'));
if(!confirmed) {
$(this).removeClass('loading')
$(this).removeClass('loading');
return false;
}
});