ENHANCEMENT Integrating right panels ('insert image', etc.) in CMS with new layout manager, adjusting title bar to jQuery UI styling, making panel content scrollable

MINOR Updated cmsmain/leftandmain javascript to concrete API changes

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92609 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Ingo Schommer 2009-11-21 02:36:26 +00:00
parent d5ec175cfb
commit 9f4d0da80a
7 changed files with 201 additions and 86 deletions

View File

@ -188,6 +188,7 @@ class LeftAndMain extends Controller {
Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/effects.scale.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery/ui/effects.scale.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/layout/jquery.layout.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/layout/jquery.layout.js');
Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/fitheighttoparent/jquery.fitheighttoparent.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery/plugins/fitheighttoparent/jquery.fitheighttoparent.js');
Requirements::javascript(CMS_DIR . '/javascript/ssui.core.js');
// @todo Load separately so the CSS files can be inlined // @todo Load separately so the CSS files can be inlined
Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.all.css'); Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.all.css');

View File

@ -480,3 +480,12 @@
position: relative; position: relative;
overflow-x: hidden; overflow-x: hidden;
} }
/**
* "Insert Image" forms etc.
*/
#Form_EditorToolbarImageForm .field,
#Form_EditorToolbarFlashForm .field,
#Form_EditorToolbarLinkForm .field {
margin-left: 0;
}

View File

@ -35,7 +35,8 @@ body {
} }
/* Overflow is handled by tabsets inside the panel */ /* Overflow is handled by tabsets inside the panel */
.ui-layout-center { .ui-layout-center,
.ui-layout-east {
overflow: hidden !important; overflow: hidden !important;
} }
@ -487,16 +488,11 @@ iframe {
* This is our new right hand pane for inserting images and links etc * This is our new right hand pane for inserting images and links etc
*/ */
#contentPanel { #contentPanel {
background-color: #fff;
width: 205px;
position: absolute;
border: 1px solid #ACBBCC;
top: 45px;
padding: 0;
margin-right: 10px;
overflow: hidden;
font-size: 12px; font-size: 12px;
} }
#contentPanel .content {
overflow: auto;
}
#contentPanel div, #contentPanel div,
#contentPanel p#TargetBlank { #contentPanel p#TargetBlank {
@ -523,13 +519,9 @@ iframe {
overflow-y: auto; overflow-y: auto;
margin-right: 0 !important; margin-right: 0 !important;
} }
#contentPanel .ui-dialog {
#contentPanel fieldset { width: auto;
padding: 5px; }
}
#contentPanel h2 {
margin: -5px -5px 0 -5px;
}
#contentPanel .thumbnailstrip h2 { #contentPanel .thumbnailstrip h2 {
font-size: 1.1em; font-size: 1.1em;
margin: 0; margin: 0;
@ -549,7 +541,6 @@ iframe {
background:#E9E9E9 none repeat scroll 0%; background:#E9E9E9 none repeat scroll 0%;
display:block; display:block;
padding:3px; padding:3px;
width:98%;
} }
#contentPanel input.text { #contentPanel input.text {
border:1px solid #A7A7A7; border:1px solid #A7A7A7;
@ -560,6 +551,10 @@ iframe {
background: none; background: none;
} }
#contentPanel form {
display: none;
}
/* Image height and width inputs. We need to position them in the right places */ /* Image height and width inputs. We need to position them in the right places */
#contentPanel input#Form_EditorToolbarImageForm_Width, #contentPanel input#Form_EditorToolbarImageForm_Width,
#contentPanel input#Form_EditorToolbarFlashForm_Width { #contentPanel input#Form_EditorToolbarFlashForm_Width {
@ -613,7 +608,7 @@ iframe {
border: 2px solid #e4e3e3; border: 2px solid #e4e3e3;
} }
#contentPanel div.Actions { #contentPanel div.Actions {
margin: 2px 5px 0 0; margin: 5px;
text-align: right; text-align: right;
} }
#contentPanel #FolderImages a.selectedImage img, #contentPanel #FolderImages a.selectedImage img,

View File

@ -1,28 +1,35 @@
(function($) { (function($) {
$('body.CMSMain').concrete('ss.leftAndMain', { $('body.CMSMain').concrete('ss', function($){return{
/**
* Reference to jQuery.layout element
*/
MainLayout: null, MainLayout: null,
onmatch: function() { onmatch: function() {
var self = this; var self = this;
this.concrete("ss.leftAndMain").setMainLayout(this.concrete("ss.leftAndMain")._setupLayout()); this.setMainLayout(this._setupLayout());
// artificially delay the resize event 200ms // artificially delay the resize event 200ms
// to avoid overlapping height changes in different onresize() methods // to avoid overlapping height changes in different onresize() methods
$(window).resize(function () { $(window).resize(function () {
var timerID = "timerCMSMainResize"; var timerID = "timerCMSMainResize";
if (window[timerID]) clearTimeout(window[timerID]); if (window[timerID]) clearTimeout(window[timerID]);
window[timerID] = setTimeout(function() {self.concrete("ss.leftAndMain")._resizeChildren();}, 200); window[timerID] = setTimeout(function() {self._resizeChildren();}, 200);
}); });
this.concrete("ss.leftAndMain")._resizeChildren(); this._resizeChildren();
this._super(); this._super();
}, },
_resizeChildren: function() { _resizeChildren: function() {
$("#treepanes").accordion("resize"); $("#treepanes", this).accordion("resize");
$('#sitetree_and_tools').fitHeightToParent(); $('#sitetree_and_tools', this).fitHeightToParent();
$('#contentPanel form', this).fitHeightToParent();
$('#contentPanel form fieldset', this).fitHeightToParent();
$('#contentPanel form fieldset .content', this).fitHeightToParent();
this._super(); this._super();
}, },
@ -45,7 +52,9 @@
togglerTip_open: '', togglerTip_open: '',
togglerTip_closed: '', togglerTip_closed: '',
resizerTip: '', resizerTip: '',
sliderTip: '' sliderTip: '',
onresize: function() {self._resizeChildren();},
onopen: function() {self._resizeChildren();},
}, },
north: { north: {
slidable: false, slidable: false,
@ -61,13 +70,12 @@
}, },
west: { west: {
size: 250, size: 250,
onresize: function() {self.concrete()._resizeChildren();},
onopen: function() {self.concrete()._resizeChildren();},
fxName: "none" fxName: "none"
}, },
east: { east: {
initClosed: true, initClosed: true,
fxName: "none" fxName: "none",
size: 250
}, },
center: {} center: {}
}); });
@ -81,12 +89,12 @@
return layout; return layout;
} }
}); }});
/** /**
* CMS-specific form behaviour * CMS-specific form behaviour
*/ */
$('#Form_EditForm').concrete({ $('#Form_EditForm').concrete('ss', function($){return{
onmatch: function() { onmatch: function() {
// Alert the user on change of page-type - this might have implications // Alert the user on change of page-type - this might have implications
// on the available form fields etc. // on the available form fields etc.
@ -98,13 +106,13 @@
this.find(':input[name=ParentID]') this.find(':input[name=ParentID]')
} }
}); }});
/** /**
* ParentType / ParentID field combination - mostly toggling between * ParentType / ParentID field combination - mostly toggling between
* the two radiobuttons and setting the hidden "ParentID" field * the two radiobuttons and setting the hidden "ParentID" field
*/ */
$('#Form_EditForm_ParentType').concrete({ $('#Form_EditForm_ParentType').concrete('ss', function($){return{
onmatch : function() { onmatch : function() {
var parentTypeRootEl = $('#Form_EditForm_ParentType_root'); var parentTypeRootEl = $('#Form_EditForm_ParentType_root');
var parentTypeSubpageEl = $('#Form_EditForm_ParentType_subpage'); var parentTypeSubpageEl = $('#Form_EditForm_ParentType_subpage');
@ -130,13 +138,13 @@
$('#ParentID').show(); $('#ParentID').show();
} }
} }
}); }});
/** /**
* Email containing the link to the archived version of the page. * Email containing the link to the archived version of the page.
* Visible on readonly older versions of a specific page at the moment. * Visible on readonly older versions of a specific page at the moment.
*/ */
$('#Form_EditForm .Actions #Form_EditForm_action_email').concrete({ $('#Form_EditForm .Actions #Form_EditForm_action_email').concrete('ss', function($){return{
onclick: function(e) { onclick: function(e) {
window.open( window.open(
'mailto:?subject=' 'mailto:?subject='
@ -148,13 +156,13 @@
return false; return false;
} }
}); }});
/** /**
* Open a printable representation of the form in a new window. * Open a printable representation of the form in a new window.
* Used for readonly older versions of a specific page. * Used for readonly older versions of a specific page.
*/ */
$('#Form_EditForm .Actions #Form_EditForm_action_print').concrete({ $('#Form_EditForm .Actions #Form_EditForm_action_print').concrete('ss', function($){return{
onclick: function(e) { onclick: function(e) {
var printURL = $(this[0].form).attr('action').replace(/\?.*$/,'') var printURL = $(this[0].form).attr('action').replace(/\?.*$/,'')
+ '/printable/' + '/printable/'
@ -165,21 +173,34 @@
return false; return false;
} }
}); }});
/** /**
* A "rollback" to a specific version needs user confirmation. * A "rollback" to a specific version needs user confirmation.
*/ */
$('#Form_EditForm .Actions #Form_EditForm_action_rollback').concrete({ $('#Form_EditForm .Actions #Form_EditForm_action_rollback').concrete('ss', function($){return{
onclick: function(e) { onclick: function(e) {
// @todo i18n // @todo i18n
return confirm("Do you really want to copy the published content to the stage site?"); return confirm("Do you really want to copy the published content to the stage site?");
} }
}); }});
/**
* All forms in the right content panel should have closeable jQuery UI style titles.
*/
$('#contentPanel form').concrete('ss', function($){return{
onmatch: function() {
// Style as title bar
this.find(':header:first').titlebar({
closeButton:true
});
// The close button should close the east panel of the layout
this.find(':header:first .ui-dialog-titlebar-close').bind('click', function(e) {
$('body.CMSMain').concrete('ss').MainLayout().close('east');
return false;
});
}
}});
})(jQuery); })(jQuery);
jQuery(document).ready(function() {
// @todo remove
jQuery.concrete.triggerMatching();
});

View File

@ -10,12 +10,17 @@
* - beforeValidate * - beforeValidate
* - afterValidate * - afterValidate
*/ */
$('.LeftAndMain').concrete('ss.leftAndMain', { $('.LeftAndMain').concrete('ss', function($){return{
/**
*
*/
PingIntervalSeconds: 5*60, PingIntervalSeconds: 5*60,
onmatch: function() { onmatch: function() {
this.concrete("ss.leftAndMain")._setupPinging(); this._setupPinging();
this.concrete("ss.leftAndMain")._setupButtons(); this._setupButtons();
this._resizeChildren();
this._super(); this._super();
}, },
@ -23,7 +28,7 @@
_setupPinging: function() { _setupPinging: function() {
// setup pinging for login expiry // setup pinging for login expiry
setInterval(function() { setInterval(function() {
$.get("Security/ping"); jQuery.get("Security/ping");
}, this.PingIntervalSeconds() * 1000); }, this.PingIntervalSeconds() * 1000);
}, },
@ -52,15 +57,30 @@
$(this).removeClass('ui-state-focus'); $(this).removeClass('ui-state-focus');
}); });
}); });
},
/**
* Resize elements in center panel
* to fit the boundary box provided by the layout manager
*/
_resizeChildren: function() {
$('#Form_EditForm').fitHeightToParent();
$('#Form_EditForm fieldset', this).fitHeightToParent();
// Order of resizing is important: Outer to inner
// TODO Only supports two levels of tabs at the moment
$('#Form_EditForm fieldset > .ss-tabset', this).fitHeightToParent();
$('#Form_EditForm fieldset > .ss-tabset > .tab', this).fitHeightToParent();
$('#Form_EditForm fieldset > .ss-tabset > .tab > .ss-tabset', this).fitHeightToParent();
$('#Form_EditForm fieldset > .ss-tabset > .tab > .ss-tabset > .tab', this).fitHeightToParent();
} }
}); }});
/** /**
* Base edit form, provides ajaxified saving * Base edit form, provides ajaxified saving
* and reloading itself through the ajax return values. * and reloading itself through the ajax return values.
* Takes care of resizing tabsets within the layout container. * Takes care of resizing tabsets within the layout container.
*/ */
$('#Form_EditForm').concrete('ss.editForm',{ $('#Form_EditForm').concrete('ss',function($){return{
onmatch: function() { onmatch: function() {
var self = this; var self = this;
@ -69,14 +89,12 @@
$(window).resize(function () { $(window).resize(function () {
var timerID = "timerLeftAndMainResize"; var timerID = "timerLeftAndMainResize";
if (window[timerID]) clearTimeout(window[timerID]); if (window[timerID]) clearTimeout(window[timerID]);
window[timerID] = setTimeout(function() {self.concrete('ss.editForm')._resizeChildren();}, 200); window[timerID] = setTimeout(function() {self._resizeChildren();}, 200);
}); });
this.concrete('ss.editForm')._resizeChildren();
// trigger resize whenever new tabs are shown // trigger resize whenever new tabs are shown
// @todo This is called multiple times when tabs are loaded // @todo This is called multiple times when tabs are loaded
this.find('.ss-tabset').bind('tabsshow', function() {self.concrete('ss.editForm')._resizeChildren();}); this.find('.ss-tabset').bind('tabsshow', function() {self._resizeChildren();});
}, },
/** /**
@ -181,37 +199,22 @@
if($('input#Form_EditForm_Title') && $('input#Form_EditForm_Title').value.match(/^new/i)) { if($('input#Form_EditForm_Title') && $('input#Form_EditForm_Title').value.match(/^new/i)) {
$('input#Form_EditForm_Title').select(); $('input#Form_EditForm_Title').select();
} }
},
/**
* Resize elements in center panel
* to fit the boundary box provided by the layout manager
*/
_resizeChildren: function() {
this.fitHeightToParent();
$('fieldset', this).fitHeightToParent();
// Order of resizing is important: Outer to inner
// TODO Only supports two levels of tabs at the moment
$('fieldset > .ss-tabset', this).fitHeightToParent();
$('fieldset > .ss-tabset > .tab', this).fitHeightToParent();
$('fieldset > .ss-tabset > .tab > .ss-tabset', this).fitHeightToParent();
$('fieldset > .ss-tabset > .tab > .ss-tabset > .tab', this).fitHeightToParent();
} }
}); }});
/** /**
* All buttons in the right CMS form go through here by default. * All buttons in the right CMS form go through here by default.
* We need this onclick overloading because we can't get to the * We need this onclick overloading because we can't get to the
* clicked button from a form.onsubmit event. * clicked button from a form.onsubmit event.
*/ */
$('#Form_EditForm .Actions :submit').concrete({ $('#Form_EditForm .Actions :submit').concrete('ss', function($){return{
onclick: function(e) { onclick: function(e) {
$(this[0].form).ajaxSubmit(this); $(this[0].form).ajaxSubmit(this);
return false; return false;
} }
}); }});
$('#TreeActions').concrete({ $('#TreeActions').concrete('ss', function($){return{
onmatch: function() { onmatch: function() {
// setup "create", "search", "batch actions" layers above tree // setup "create", "search", "batch actions" layers above tree
this.tabs({ this.tabs({
@ -219,27 +222,22 @@
collapsible: true collapsible: true
}); });
} }
}); }});
/** /**
* Link for editing the profile for a logged-in member * Link for editing the profile for a logged-in member
* through a popup. Required "greybox" javascript library. * through a popup. Required "greybox" javascript library.
*/ */
$('#EditMemberProfile').concrete({ $('#EditMemberProfile').concrete('ss', function($){return{
onclick: function(e) { onclick: function(e) {
GB_show('Edit Profile', this.attr('href'), 290, 500); GB_show('Edit Profile', this.attr('href'), 290, 500);
return false; return false;
} }
}); }});
})(jQuery); })(jQuery);
jQuery(document).ready(function() {
// @todo remove
jQuery.concrete.triggerMatching();
});
@ -263,9 +261,7 @@ Behaviour.register({
window.location.href = this.getElementsByTagName('a')[0].href; window.location.href = this.getElementsByTagName('a')[0].href;
Event.stop(event); Event.stop(event);
} }
}, }
}); });

93
javascript/ssui.core.js Normal file
View File

@ -0,0 +1,93 @@
(function($) {
$.widget("ssui.titlebar", {
_init: function() {
this.originalTitle = this.element.attr('title');
var self = this;
var options = this.options;
var title = options.title || this.originalTitle || ' ';
var titleId = $.ui.dialog.getTitleId(this.element);
this.element.parent().addClass('ui-dialog');
var uiDialogTitlebar = this.element.
addClass(
'ui-dialog-titlebar ' +
'ui-widget-header ' +
'ui-corner-all ' +
'ui-helper-clearfix'
);
// By default, the
if(options.closeButton) {
var uiDialogTitlebarClose = $('<a href="#"/>')
.addClass(
'ui-dialog-titlebar-close ' +
'ui-corner-all'
)
.attr('role', 'button')
.hover(
function() {
uiDialogTitlebarClose.addClass('ui-state-hover');
},
function() {
uiDialogTitlebarClose.removeClass('ui-state-hover');
}
)
.focus(function() {
uiDialogTitlebarClose.addClass('ui-state-focus');
})
.blur(function() {
uiDialogTitlebarClose.removeClass('ui-state-focus');
})
.mousedown(function(ev) {
ev.stopPropagation();
})
.appendTo(uiDialogTitlebar);
var uiDialogTitlebarCloseText = (this.uiDialogTitlebarCloseText = $('<span/>'))
.addClass(
'ui-icon ' +
'ui-icon-closethick'
)
.text(options.closeText)
.appendTo(uiDialogTitlebarClose);
}
var uiDialogTitle = $('<span/>')
.addClass('ui-dialog-title')
.attr('id', titleId)
.html(title)
.prependTo(uiDialogTitlebar);
uiDialogTitlebar.find("*").add(uiDialogTitlebar).disableSelection();
},
destroy: function() {
this.element
.unbind('.dialog')
.removeData('dialog')
.removeClass('ui-dialog-content ui-widget-content')
.hide().appendTo('body');
(this.originalTitle && this.element.attr('title', this.originalTitle));
}
});
$.extend($.ssui.titlebar, {
version: "0.0.1",
defaults: {
title: '',
closeButton: false,
closeText: 'close'
},
uuid: 0,
getTitleId: function($el) {
return 'ui-dialog-title-' + ($el.attr('id') || ++this.uuid);
}
});
}(jQuery));

View File

@ -23,7 +23,7 @@
$Right $Right
</div> </div>
<div class="ui-layout-east"> <div class="ui-layout-east" id="contentPanel">
<% control EditorToolbar %> <% control EditorToolbar %>
$ImageForm $ImageForm
$LinkForm $LinkForm