From 9f4d0da80a6052d0fa879fa7834ba0646d64aea5 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 21 Nov 2009 02:36:26 +0000 Subject: [PATCH] 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 --- code/LeftAndMain.php | 1 + css/cms_right.css | 9 ++++ css/layout.css | 31 ++++++------- javascript/CMSMain.js | 75 +++++++++++++++++++------------ javascript/LeftAndMain.js | 76 +++++++++++++++----------------- javascript/ssui.core.js | 93 +++++++++++++++++++++++++++++++++++++++ templates/LeftAndMain.ss | 2 +- 7 files changed, 201 insertions(+), 86 deletions(-) create mode 100644 javascript/ssui.core.js diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 643ccfa2..706b4632 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -188,6 +188,7 @@ class LeftAndMain extends Controller { 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/fitheighttoparent/jquery.fitheighttoparent.js'); + Requirements::javascript(CMS_DIR . '/javascript/ssui.core.js'); // @todo Load separately so the CSS files can be inlined Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.all.css'); diff --git a/css/cms_right.css b/css/cms_right.css index 8ea26312..06ddc87b 100644 --- a/css/cms_right.css +++ b/css/cms_right.css @@ -480,3 +480,12 @@ position: relative; overflow-x: hidden; } + +/** + * "Insert Image" forms etc. + */ +#Form_EditorToolbarImageForm .field, +#Form_EditorToolbarFlashForm .field, +#Form_EditorToolbarLinkForm .field { + margin-left: 0; +} \ No newline at end of file diff --git a/css/layout.css b/css/layout.css index a48f141c..c4ecd816 100644 --- a/css/layout.css +++ b/css/layout.css @@ -35,7 +35,8 @@ body { } /* Overflow is handled by tabsets inside the panel */ -.ui-layout-center { +.ui-layout-center, +.ui-layout-east { overflow: hidden !important; } @@ -487,16 +488,11 @@ iframe { * This is our new right hand pane for inserting images and links etc */ #contentPanel { - background-color: #fff; - width: 205px; - position: absolute; - border: 1px solid #ACBBCC; - top: 45px; - padding: 0; - margin-right: 10px; - overflow: hidden; font-size: 12px; } +#contentPanel .content { + overflow: auto; +} #contentPanel div, #contentPanel p#TargetBlank { @@ -523,13 +519,9 @@ iframe { overflow-y: auto; margin-right: 0 !important; } - -#contentPanel fieldset { - padding: 5px; -} -#contentPanel h2 { - margin: -5px -5px 0 -5px; -} + #contentPanel .ui-dialog { + width: auto; + } #contentPanel .thumbnailstrip h2 { font-size: 1.1em; margin: 0; @@ -549,7 +541,6 @@ iframe { background:#E9E9E9 none repeat scroll 0%; display:block; padding:3px; - width:98%; } #contentPanel input.text { border:1px solid #A7A7A7; @@ -560,6 +551,10 @@ iframe { background: none; } +#contentPanel form { + display: none; +} + /* Image height and width inputs. We need to position them in the right places */ #contentPanel input#Form_EditorToolbarImageForm_Width, #contentPanel input#Form_EditorToolbarFlashForm_Width { @@ -613,7 +608,7 @@ iframe { border: 2px solid #e4e3e3; } #contentPanel div.Actions { - margin: 2px 5px 0 0; + margin: 5px; text-align: right; } #contentPanel #FolderImages a.selectedImage img, diff --git a/javascript/CMSMain.js b/javascript/CMSMain.js index 0f5c37da..5ed056c7 100644 --- a/javascript/CMSMain.js +++ b/javascript/CMSMain.js @@ -1,28 +1,35 @@ (function($) { - $('body.CMSMain').concrete('ss.leftAndMain', { + $('body.CMSMain').concrete('ss', function($){return{ + + /** + * Reference to jQuery.layout element + */ MainLayout: null, onmatch: function() { var self = this; - this.concrete("ss.leftAndMain").setMainLayout(this.concrete("ss.leftAndMain")._setupLayout()); + this.setMainLayout(this._setupLayout()); // artificially delay the resize event 200ms // to avoid overlapping height changes in different onresize() methods $(window).resize(function () { var timerID = "timerCMSMainResize"; 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(); }, _resizeChildren: function() { - $("#treepanes").accordion("resize"); - $('#sitetree_and_tools').fitHeightToParent(); + $("#treepanes", this).accordion("resize"); + $('#sitetree_and_tools', this).fitHeightToParent(); + $('#contentPanel form', this).fitHeightToParent(); + $('#contentPanel form fieldset', this).fitHeightToParent(); + $('#contentPanel form fieldset .content', this).fitHeightToParent(); this._super(); }, @@ -45,7 +52,9 @@ togglerTip_open: '', togglerTip_closed: '', resizerTip: '', - sliderTip: '' + sliderTip: '', + onresize: function() {self._resizeChildren();}, + onopen: function() {self._resizeChildren();}, }, north: { slidable: false, @@ -61,13 +70,12 @@ }, west: { size: 250, - onresize: function() {self.concrete()._resizeChildren();}, - onopen: function() {self.concrete()._resizeChildren();}, fxName: "none" }, east: { initClosed: true, - fxName: "none" + fxName: "none", + size: 250 }, center: {} }); @@ -81,12 +89,12 @@ return layout; } - }); + }}); /** * CMS-specific form behaviour */ - $('#Form_EditForm').concrete({ + $('#Form_EditForm').concrete('ss', function($){return{ onmatch: function() { // Alert the user on change of page-type - this might have implications // on the available form fields etc. @@ -98,13 +106,13 @@ this.find(':input[name=ParentID]') } - }); + }}); /** * ParentType / ParentID field combination - mostly toggling between * the two radiobuttons and setting the hidden "ParentID" field */ - $('#Form_EditForm_ParentType').concrete({ + $('#Form_EditForm_ParentType').concrete('ss', function($){return{ onmatch : function() { var parentTypeRootEl = $('#Form_EditForm_ParentType_root'); var parentTypeSubpageEl = $('#Form_EditForm_ParentType_subpage'); @@ -130,13 +138,13 @@ $('#ParentID').show(); } } - }); + }}); /** * Email containing the link to the archived version of the page. * 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) { window.open( 'mailto:?subject=' @@ -148,13 +156,13 @@ return false; } - }); + }}); /** * Open a printable representation of the form in a new window. * 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) { var printURL = $(this[0].form).attr('action').replace(/\?.*$/,'') + '/printable/' @@ -165,21 +173,34 @@ return false; } - }); + }}); /** * 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) { // @todo i18n 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(document).ready(function() { - // @todo remove - jQuery.concrete.triggerMatching(); -}); \ No newline at end of file +})(jQuery); \ No newline at end of file diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 1484aeec..5f9e5761 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -10,12 +10,17 @@ * - beforeValidate * - afterValidate */ - $('.LeftAndMain').concrete('ss.leftAndMain', { + $('.LeftAndMain').concrete('ss', function($){return{ + + /** + * + */ PingIntervalSeconds: 5*60, onmatch: function() { - this.concrete("ss.leftAndMain")._setupPinging(); - this.concrete("ss.leftAndMain")._setupButtons(); + this._setupPinging(); + this._setupButtons(); + this._resizeChildren(); this._super(); }, @@ -23,7 +28,7 @@ _setupPinging: function() { // setup pinging for login expiry setInterval(function() { - $.get("Security/ping"); + jQuery.get("Security/ping"); }, this.PingIntervalSeconds() * 1000); }, @@ -52,15 +57,30 @@ $(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 * and reloading itself through the ajax return values. * Takes care of resizing tabsets within the layout container. */ - $('#Form_EditForm').concrete('ss.editForm',{ + $('#Form_EditForm').concrete('ss',function($){return{ onmatch: function() { var self = this; @@ -69,14 +89,12 @@ $(window).resize(function () { var timerID = "timerLeftAndMainResize"; 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 // @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)) { $('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. * We need this onclick overloading because we can't get to the * clicked button from a form.onsubmit event. */ - $('#Form_EditForm .Actions :submit').concrete({ + $('#Form_EditForm .Actions :submit').concrete('ss', function($){return{ onclick: function(e) { $(this[0].form).ajaxSubmit(this); return false; } - }); + }}); - $('#TreeActions').concrete({ + $('#TreeActions').concrete('ss', function($){return{ onmatch: function() { // setup "create", "search", "batch actions" layers above tree this.tabs({ @@ -219,27 +222,22 @@ collapsible: true }); } - }); + }}); /** * Link for editing the profile for a logged-in member * through a popup. Required "greybox" javascript library. */ - $('#EditMemberProfile').concrete({ + $('#EditMemberProfile').concrete('ss', function($){return{ onclick: function(e) { GB_show('Edit Profile', this.attr('href'), 290, 500); return false; } - }); + }}); })(jQuery); -jQuery(document).ready(function() { - // @todo remove - jQuery.concrete.triggerMatching(); -}); - @@ -263,9 +261,7 @@ Behaviour.register({ window.location.href = this.getElementsByTagName('a')[0].href; Event.stop(event); } - }, - - + } }); diff --git a/javascript/ssui.core.js b/javascript/ssui.core.js new file mode 100644 index 00000000..cc83b378 --- /dev/null +++ b/javascript/ssui.core.js @@ -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 = $('') + .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 = $('')) + .addClass( + 'ui-icon ' + + 'ui-icon-closethick' + ) + .text(options.closeText) + .appendTo(uiDialogTitlebarClose); + } + + var uiDialogTitle = $('') + .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)); \ No newline at end of file diff --git a/templates/LeftAndMain.ss b/templates/LeftAndMain.ss index a87c4b89..7aba7e57 100644 --- a/templates/LeftAndMain.ss +++ b/templates/LeftAndMain.ss @@ -23,7 +23,7 @@ $Right -
+
<% control EditorToolbar %> $ImageForm $LinkForm