2011-03-23 10:51:00 +01:00
|
|
|
/**
|
|
|
|
* File: LeftAndMain.js
|
|
|
|
*/
|
|
|
|
(function($) {
|
2011-04-15 05:32:43 +02:00
|
|
|
|
|
|
|
$.metadata.setType('html5');
|
|
|
|
|
2011-03-23 10:51:00 +01:00
|
|
|
$.entwine('ss', function($){
|
2011-04-15 05:32:43 +02:00
|
|
|
|
2011-03-23 10:51:00 +01:00
|
|
|
/**
|
|
|
|
* Position the loading spinner animation below the ss logo
|
|
|
|
*/
|
|
|
|
var positionLoadingSpinner = function() {
|
|
|
|
var offset = 120; // offset from the ss logo
|
|
|
|
var spinner = $('.ss-loading-screen .loading-animation');
|
|
|
|
var top = ($(window).height() - spinner.height()) / 2;
|
|
|
|
spinner.css('top', top + offset);
|
|
|
|
spinner.show();
|
|
|
|
}
|
|
|
|
$(window).bind('resize', positionLoadingSpinner).trigger('resize');
|
|
|
|
|
|
|
|
// setup jquery.entwine
|
|
|
|
$.entwine.warningLevel = $.entwine.WARN_LEVEL_BESTPRACTISE;
|
|
|
|
|
|
|
|
// global ajax error handlers
|
|
|
|
$.ajaxSetup({
|
|
|
|
error: function(xmlhttp, status, error) {
|
|
|
|
var msg = (xmlhttp.getResponseHeader('X-Status')) ? xmlhttp.getResponseHeader('X-Status') : xmlhttp.statusText;
|
|
|
|
statusMessage(msg, 'bad');
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class: .LeftAndMain
|
|
|
|
*
|
|
|
|
* Main LeftAndMain interface with some control panel and an edit form.
|
|
|
|
*
|
|
|
|
* Events:
|
|
|
|
* ajaxsubmit - ...
|
|
|
|
* validate - ...
|
|
|
|
* loadnewpage - ...
|
|
|
|
*/
|
|
|
|
$('.LeftAndMain').entwine({
|
2011-06-09 03:49:52 +02:00
|
|
|
|
|
|
|
CurrentXHR: null,
|
|
|
|
|
2011-03-23 10:51:00 +01:00
|
|
|
/**
|
|
|
|
* Constructor: onmatch
|
|
|
|
*/
|
|
|
|
onmatch: function() {
|
|
|
|
var self = this;
|
2011-06-09 03:49:52 +02:00
|
|
|
|
2011-04-24 02:31:11 +02:00
|
|
|
// Browser detection
|
|
|
|
if($.browser.msie && parseInt($.browser.version, 10) < 7) {
|
|
|
|
$('.ss-loading-screen').append(
|
|
|
|
'<p><span class="notice">' +
|
|
|
|
ss.i18n._t('LeftAndMain.IncompatBrowserWarning') +
|
|
|
|
'</span></p>'
|
|
|
|
);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-04-14 07:10:50 +02:00
|
|
|
// Initialize layouts, inner to outer
|
2011-05-15 05:43:21 +02:00
|
|
|
this.redraw();
|
|
|
|
$(window).resize(function() {self.redraw()});
|
2011-04-15 00:35:09 +02:00
|
|
|
|
|
|
|
// Remove loading screen
|
|
|
|
$('.ss-loading-screen').hide();
|
|
|
|
$('body').removeClass('loading');
|
|
|
|
$(window).unbind('resize', positionLoadingSpinner);
|
2011-03-23 10:51:00 +01:00
|
|
|
|
2011-05-15 05:43:21 +02:00
|
|
|
$('.cms-edit-form').live('loadnewpage', function() {self.redraw()});
|
2011-06-09 03:49:52 +02:00
|
|
|
|
|
|
|
History.Adapter.bind(window,'statechange',function(){
|
|
|
|
self.handleStateChange();
|
|
|
|
});
|
2011-03-23 10:51:00 +01:00
|
|
|
|
|
|
|
this._super();
|
|
|
|
},
|
2011-05-13 03:30:49 +02:00
|
|
|
|
2011-05-15 05:43:21 +02:00
|
|
|
redraw: function() {
|
2011-06-08 01:35:56 +02:00
|
|
|
// Not all edit forms are layouted
|
|
|
|
var editForm = this.find('.cms-edit-form[data-layout]').layout();
|
2011-05-20 01:39:44 +02:00
|
|
|
this.find('.cms-content').layout();
|
|
|
|
this.find('.cms-container').layout({resize: false})
|
2011-06-09 03:49:52 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles ajax loading of new panels through the window.History object.
|
|
|
|
* To trigger loading, pass a new URL to window.History.pushState().
|
|
|
|
*
|
|
|
|
* Due to the nature of history management, no callbacks are allowed.
|
|
|
|
* Use the 'beforestatechange' and 'afterstatechange' events instead,
|
|
|
|
* or overwrite the beforeLoad() and afterLoad() methods on the
|
|
|
|
* DOM element you're loading the new content into.
|
|
|
|
* Although you can pass data into pushState(), it shouldn't contain
|
|
|
|
* DOM elements or callback closures.
|
|
|
|
*
|
|
|
|
* The passed URL should allow reconstructing important interface state
|
|
|
|
* without additional parameters, in the following use cases:
|
|
|
|
* - Explicit loading through History.pushState()
|
|
|
|
* - Implicit loading through browser navigation event triggered by the user (forward or back)
|
|
|
|
* - Full window refresh without ajax
|
|
|
|
* For example, a ModelAdmin search event should contain the search terms
|
|
|
|
* as URL parameters, and the result display should automatically appear
|
|
|
|
* if the URL is loaded without ajax.
|
|
|
|
*
|
|
|
|
* Alternatively, you can load new content via $('.cms-content').loadForm(<url>).
|
|
|
|
* In this case, the action won't be recorded in the browser history.
|
|
|
|
*/
|
|
|
|
handleStateChange: function() {
|
|
|
|
var self = this, h = window.History, state = h.getState();
|
|
|
|
|
|
|
|
// Don't allow parallel loading to avoid edge cases
|
|
|
|
if(this.getCurrentXHR()) this.getCurrentXHR().abort();
|
|
|
|
|
|
|
|
// TODO Support loading into multiple panels
|
|
|
|
var contentEl = $(state.data.selector || '.LeftAndMain .cms-content');
|
|
|
|
this.trigger('beforestatechange', {state: state});
|
|
|
|
contentEl.beforeLoad(state.url);
|
|
|
|
|
|
|
|
var xhr = $.ajax({
|
|
|
|
url: state.url,
|
|
|
|
success: function(data, status, xhr) {
|
2011-06-09 05:47:59 +02:00
|
|
|
// Update title
|
|
|
|
var title = xhr.getResponseHeader('X-Title');
|
|
|
|
if(title) document.title = title;
|
|
|
|
|
2011-06-09 03:49:52 +02:00
|
|
|
// Update panels
|
|
|
|
contentEl.afterLoad(data, status, xhr);
|
|
|
|
self.redraw();
|
|
|
|
|
|
|
|
self.trigger('afterstatechange', {data: data, status: status, xhr: xhr});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
this.setCurrentXHR(xhr);
|
2011-03-23 10:51:00 +01:00
|
|
|
}
|
|
|
|
});
|
2011-05-13 03:30:49 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Monitor all panels for layout changes
|
|
|
|
*/
|
|
|
|
$('.LeftAndMain .cms-panel').entwine({
|
|
|
|
ontoggle: function(e) {
|
2011-05-15 05:43:21 +02:00
|
|
|
this.parents('.LeftAndMain').redraw();
|
2011-05-13 03:30:49 +02:00
|
|
|
}
|
|
|
|
});
|
2011-03-23 10:51:00 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class: .LeftAndMain :submit, .LeftAndMain button, .LeftAndMain :reset
|
|
|
|
*
|
|
|
|
* Make all buttons "hoverable" with jQuery theming.
|
|
|
|
* Also sets the clicked button on a form submission, making it available through
|
|
|
|
* a new 'clickedButton' property on the form DOM element.
|
|
|
|
*/
|
|
|
|
$('.LeftAndMain :submit, .LeftAndMain button, .LeftAndMain :reset').entwine({
|
|
|
|
onmatch: function() {
|
2011-04-15 05:32:43 +02:00
|
|
|
// TODO Adding classes in onmatch confuses entwine
|
|
|
|
var self = this;
|
|
|
|
setTimeout(function() {self.addClass('ss-ui-button');}, 10);
|
|
|
|
|
2011-03-23 10:51:00 +01:00
|
|
|
this._super();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
2011-04-30 06:48:57 +02:00
|
|
|
* Class: a#profile-link
|
2011-03-23 10:51:00 +01:00
|
|
|
*
|
|
|
|
* Link for editing the profile for a logged-in member through a modal dialog.
|
|
|
|
*/
|
2011-04-30 06:48:57 +02:00
|
|
|
$('.LeftAndMain .profile-link').entwine({
|
2011-03-23 10:51:00 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Constructor: onmatch
|
|
|
|
*/
|
|
|
|
onmatch: function() {
|
|
|
|
var self = this;
|
|
|
|
|
|
|
|
this.bind('click', function(e) {return self._openPopup();});
|
|
|
|
|
|
|
|
$('body').append(
|
|
|
|
'<div id="ss-ui-dialog">'
|
|
|
|
+ '<iframe id="ss-ui-dialog-iframe" '
|
|
|
|
+ 'marginWidth="0" marginHeight="0" frameBorder="0" scrolling="auto">'
|
|
|
|
+ '</iframe>'
|
|
|
|
+ '</div>'
|
|
|
|
);
|
|
|
|
|
|
|
|
var cookieVal = (jQuery.cookie) ? JSON.parse(jQuery.cookie('ss-ui-dialog')) : false;
|
|
|
|
$("#ss-ui-dialog").dialog(jQuery.extend({
|
|
|
|
autoOpen: false,
|
|
|
|
bgiframe: true,
|
|
|
|
modal: true,
|
|
|
|
height: 300,
|
|
|
|
width: 500,
|
|
|
|
ghost: true,
|
|
|
|
resizeStop: function(e, ui) {
|
|
|
|
self._resize();
|
|
|
|
self._saveState();
|
|
|
|
},
|
|
|
|
dragStop: function(e, ui) {
|
|
|
|
self._saveState();
|
|
|
|
},
|
|
|
|
// TODO i18n
|
|
|
|
title: 'Edit Profile'
|
|
|
|
}, cookieVal)).css('overflow', 'hidden');
|
|
|
|
|
|
|
|
$('#ss-ui-dialog-iframe').bind('load', function(e) {self._resize();});
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function: _openPopup
|
|
|
|
*/
|
|
|
|
_openPopup: function(e) {
|
|
|
|
$('#ss-ui-dialog-iframe').attr('src', this.attr('href'));
|
|
|
|
|
|
|
|
$("#ss-ui-dialog").dialog('open');
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function: _resize
|
|
|
|
*/
|
|
|
|
_resize: function() {
|
|
|
|
var iframe = $('#ss-ui-dialog-iframe');
|
|
|
|
var container = $('#ss-ui-dialog');
|
|
|
|
|
|
|
|
iframe.attr('width',
|
|
|
|
container.innerWidth()
|
|
|
|
- parseFloat(container.css('paddingLeft'))
|
|
|
|
- parseFloat(container.css('paddingRight'))
|
|
|
|
);
|
|
|
|
iframe.attr('height',
|
|
|
|
container.innerHeight()
|
|
|
|
- parseFloat(container.css('paddingTop'))
|
|
|
|
- parseFloat(container.css('paddingBottom'))
|
|
|
|
);
|
|
|
|
|
|
|
|
this._saveState();
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function: _saveState
|
|
|
|
*/
|
|
|
|
_saveState: function() {
|
|
|
|
var container = $('#ss-ui-dialog');
|
|
|
|
|
|
|
|
// save size in cookie (optional)
|
|
|
|
if(jQuery.cookie && container.width() && container.height()) {
|
|
|
|
jQuery.cookie(
|
|
|
|
'ss-ui-dialog',
|
|
|
|
JSON.stringify({
|
|
|
|
width: parseInt(container.width(), 10),
|
|
|
|
height: parseInt(container.height(), 10),
|
|
|
|
position: [
|
|
|
|
parseInt(container.offset().top, 10),
|
|
|
|
parseInt(container.offset().left, 10)
|
|
|
|
]
|
|
|
|
}),
|
|
|
|
{ expires: 30, path: '/'}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class: #switchView a
|
|
|
|
*
|
|
|
|
* Updates the different stage links which are generated through
|
|
|
|
* the SilverStripeNavigator class on the serverside each time a form record
|
|
|
|
* is reloaded.
|
|
|
|
*/
|
|
|
|
$('#switchView').entwine({
|
|
|
|
onmatch: function() {
|
|
|
|
this._super();
|
|
|
|
|
2011-03-31 10:52:29 +02:00
|
|
|
$('.cms-edit-form').bind('loadnewpage delete', function(e) {
|
2011-03-23 10:51:00 +01:00
|
|
|
var updatedSwitchView = $('#AjaxSwitchView');
|
|
|
|
if(updatedSwitchView.length) {
|
|
|
|
$('#SwitchView').html(updatedSwitchView.html());
|
|
|
|
updatedSwitchView.remove();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class: #switchView a
|
|
|
|
*
|
|
|
|
* Links for viewing the currently loaded page
|
|
|
|
* in different modes: 'live', 'stage' or 'archived'.
|
|
|
|
*
|
|
|
|
* Requires:
|
|
|
|
* jquery.metadata
|
|
|
|
*/
|
|
|
|
$('#switchView a').entwine({
|
|
|
|
/**
|
|
|
|
* Function: onclick
|
|
|
|
*/
|
|
|
|
onclick: function(e) {
|
|
|
|
// Open in popup
|
|
|
|
window.open($(e.target).attr('href'));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
});
|
2011-04-15 05:32:43 +02:00
|
|
|
|
2011-04-30 08:34:14 +02:00
|
|
|
/**
|
|
|
|
* Duplicates functionality in DateField.js, but due to using entwine we can match
|
|
|
|
* the DOM element on creation, rather than onclick - which allows us to decorate
|
|
|
|
* the field with a calendar icon
|
|
|
|
*/
|
|
|
|
$('.LeftAndMain .field.date input.text').entwine({
|
|
|
|
onmatch: function() {
|
|
|
|
var holder = $(this).parents('.field.date:first'), config = holder.metadata({type: 'class'});
|
|
|
|
if(!config.showcalendar) return;
|
|
|
|
|
|
|
|
config.showOn = 'button';
|
|
|
|
if(config.locale && $.datepicker.regional[config.locale]) {
|
|
|
|
config = $.extend(config, $.datepicker.regional[config.locale], {});
|
|
|
|
}
|
|
|
|
|
|
|
|
$(this).datepicker(config);
|
|
|
|
// // Unfortunately jQuery UI only allows configuration of icon images, not sprites
|
|
|
|
// this.next('button').button('option', 'icons', {primary : 'ui-icon-calendar'});
|
|
|
|
|
|
|
|
this._super();
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2011-03-23 10:51:00 +01:00
|
|
|
});
|
|
|
|
}(jQuery));
|
|
|
|
|
|
|
|
// Backwards compatibility
|
|
|
|
var statusMessage = function(text, type) {
|
|
|
|
jQuery.noticeAdd({text: text, type: type});
|
|
|
|
};
|
|
|
|
|
|
|
|
var errorMessage = function(text) {
|
|
|
|
jQuery.noticeAdd({text: text, type: 'error'});
|
|
|
|
};
|
|
|
|
|
|
|
|
returnFalse = function() {
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Find and enable TinyMCE on all htmleditor fields
|
|
|
|
* Pulled in from old tinymce.template.js
|
|
|
|
*/
|
|
|
|
|
|
|
|
function nullConverter(url) {
|
|
|
|
return url;
|
|
|
|
};
|