mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUGFIX Fixed form change tracking in the CMS, integrated it into menu changes. Reduced TinyMCE coupling.
This commit is contained in:
parent
a6e2316766
commit
482324b6ae
@ -70,7 +70,7 @@
|
||||
}
|
||||
|
||||
// Alert when unsaved changes are present
|
||||
if(form._checkChangeTracker(true) == false) return false;
|
||||
if(!form.confirmUnsavedChanges()) return false;
|
||||
|
||||
// hide existing form - shown again through _loadResponse()
|
||||
form.addClass('loading');
|
||||
@ -138,14 +138,12 @@
|
||||
// default to first button if none given - simulates browser behaviour
|
||||
if(!button) button = this.find('.Actions :submit:first');
|
||||
|
||||
form.trigger('beforesave');
|
||||
this.trigger('submitform', {form: form, button: button});
|
||||
|
||||
// set button to "submitting" state
|
||||
$(button).addClass('loading');
|
||||
|
||||
// @todo TinyMCE coupling
|
||||
if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();
|
||||
|
||||
// validate if required
|
||||
if(!form.validate()) {
|
||||
// TODO Automatically switch to the tab/position of the first error
|
||||
@ -252,7 +250,7 @@
|
||||
removeForm: function(form, placeholderHtml) {
|
||||
if(!placeholderHtml) placeholderHtml = this.getPlaceholderHtml();
|
||||
// Alert when unsaved changes are present
|
||||
if(form._checkChangeTracker(true) == false) return;
|
||||
if(!form.confirmUnsavedChanges()) return;
|
||||
this.trigger('removeform');
|
||||
this.html(placeholderHtml);
|
||||
// TODO This should be using the plugin API
|
||||
|
@ -113,34 +113,20 @@
|
||||
},
|
||||
|
||||
/**
|
||||
* Function: _checkChangeTracker
|
||||
* Function: confirmUnsavedChanges
|
||||
*
|
||||
* Checks the jquery.changetracker plugin status for this form.
|
||||
* Usually bound to window.onbeforeunload.
|
||||
*
|
||||
* Parameters:
|
||||
* {boolean} isUnloadEvent - ..
|
||||
* Checks the jquery.changetracker plugin status for this form,
|
||||
* and asks the user for confirmation via a browser dialog if changes are detected.
|
||||
* Doesn't cancel any unload or form removal events, you'll need to implement this based on the return
|
||||
* value of this message.
|
||||
*
|
||||
* Returns:
|
||||
* (String) Either a string with a confirmation message, or the result of a confirm() dialog,
|
||||
* based on the isUnloadEvent parameter.
|
||||
* (Boolean) FALSE if the user wants to abort with changes present, TRUE if no changes are detected
|
||||
* or the user wants to discard them.
|
||||
*/
|
||||
_checkChangeTracker: function(isUnloadEvent) {
|
||||
var self = this;
|
||||
|
||||
// @todo TinyMCE coupling
|
||||
if(typeof tinyMCE != 'undefined') tinyMCE.triggerSave();
|
||||
|
||||
// check for form changes
|
||||
if(self.is('.changed')) {
|
||||
// returned string will trigger a confirm() dialog,
|
||||
// but only if the method is triggered by an event
|
||||
if(isUnloadEvent) {
|
||||
return confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED'));
|
||||
} else {
|
||||
return ss.i18n._t('LeftAndMain.CONFIRMUNSAVEDSHORT');
|
||||
}
|
||||
}
|
||||
confirmUnsavedChanges: function() {
|
||||
this.trigger('beforesave');
|
||||
return (this.is('.changed')) ? confirm(ss.i18n._t('LeftAndMain.CONFIRMUNSAVED')) : true;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -205,6 +191,13 @@
|
||||
* Constructor: onmatch
|
||||
*/
|
||||
onmatch : function() {
|
||||
var self = this;
|
||||
this.closest('form').bind('beforesave', function() {
|
||||
tinyMCE.triggerSave();
|
||||
// TinyMCE assigns value attr directly, which doesn't trigger change event
|
||||
self.trigger('change');
|
||||
});
|
||||
|
||||
// Only works after TinyMCE.init() has been invoked, see $(window).bind() call below for details.
|
||||
this.redraw();
|
||||
|
||||
|
@ -22,6 +22,9 @@
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
*
|
||||
* Custom Events:
|
||||
* - 'select': Fires when a menu item is selected (on any level).
|
||||
*/
|
||||
$('.cms-menu-list').entwine({
|
||||
onmatch: function() {
|
||||
@ -82,7 +85,7 @@
|
||||
this.siblings().find('li').removeClass('current');
|
||||
if(parent) parent.addClass('current').siblings().removeClass('current');
|
||||
this.getMenu().updateItems();
|
||||
|
||||
|
||||
this.trigger('select');
|
||||
}
|
||||
});
|
||||
@ -108,10 +111,8 @@
|
||||
// Ignore external links, fallback to standard link behaviour
|
||||
if(e.which > 1 || this.is(':external')) return;
|
||||
e.preventDefault();
|
||||
|
||||
// Expand this, and collapse all other items
|
||||
|
||||
var item = this.getMenuItem();
|
||||
item.select();
|
||||
|
||||
var url = this.attr('href');
|
||||
if(this.is(':internal')) url = $('base').attr('href') + url;
|
||||
@ -119,13 +120,13 @@
|
||||
var children = item.find('li');
|
||||
if(children.length) {
|
||||
children.first().find('a').click();
|
||||
} else if(window.History.enabled) {
|
||||
// Active menu item is set based on X-Controller ajax header,
|
||||
// which matches one class on the menu
|
||||
window.History.pushState({}, '', url);
|
||||
} else {
|
||||
window.location = url;
|
||||
// Load URL, but give the loading logic an opportunity to veto the action
|
||||
// (e.g. because of unsaved changes)
|
||||
if(!$('.cms-container').loadPanel(url)) return false;
|
||||
}
|
||||
|
||||
item.select();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -112,7 +112,16 @@
|
||||
*/
|
||||
loadPanel: function(url, title, data) {
|
||||
var data = data || {}, selector = data.selector || '.cms-content', contentEl = $(selector);
|
||||
|
||||
// Check change tracking (can't use events as we need a way to cancel the current state change)
|
||||
var trackedEls = contentEl.find(':data(changetracker)').add(contentEl.filter(':data(changetracker)'));
|
||||
if(trackedEls.length) {
|
||||
var abort = false;
|
||||
trackedEls.each(function() {
|
||||
if(!$(this).confirmUnsavedChanges()) abort = true;
|
||||
});
|
||||
if(abort) return;
|
||||
}
|
||||
|
||||
if(window.History.enabled) {
|
||||
// Active menu item is set based on X-Controller ajax header,
|
||||
// which matches one class on the menu
|
||||
|
@ -68,6 +68,8 @@
|
||||
.each(function() {
|
||||
$(this).data('changetracker.origVal', $(this).val());
|
||||
});
|
||||
|
||||
this.data('changetracker', true);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user