From 9a340e7eb46783c770bacafa6d41596217298047 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 5 Aug 2011 15:46:57 +1200 Subject: [PATCH] ENHANCEMENT: Added Chosen jQuery library for providing styled and searchable dropdowns. BUGFIX: removed explict width on TreeDropdownFields, instead using a width from jQuery. --- admin/code/LeftAndMain.php | 5 +++ admin/css/screen.css | 30 +++++++++----- admin/javascript/LeftAndMain.js | 20 +++++++++- admin/scss/_forms.scss | 69 ++++++++++++++++++++++++++++----- admin/scss/_style.scss | 25 ++++++++---- css/TreeDropdownField.css | 43 +++++++++++++++++--- javascript/TreeDropdownField.js | 27 +++++++++++-- 7 files changed, 179 insertions(+), 40 deletions(-) diff --git a/admin/code/LeftAndMain.php b/admin/code/LeftAndMain.php index e305db9c6..d46c0a78c 100755 --- a/admin/code/LeftAndMain.php +++ b/admin/code/LeftAndMain.php @@ -246,11 +246,16 @@ class LeftAndMain extends Controller { Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/thirdparty/history-js/scripts/uncompressed/history.html4.js'); Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/thirdparty/history-js/scripts/uncompressed/history.adapter.jquery.js'); + // styled selects (with search) + Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/thirdparty/chosen/chosen/chosen.jquery.js'); + Requirements::css(SAPPHIRE_ADMIN_DIR .'/thirdparty/chosen/chosen/chosen.css'); + Requirements::javascript(THIRDPARTY_DIR . '/behaviour/behaviour.js'); Requirements::javascript(THIRDPARTY_DIR . '/jquery-cookie/jquery.cookie.js'); Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js'); Requirements::javascript(SAPPHIRE_ADMIN_DIR . '/javascript/jquery-changetracker/lib/jquery.changetracker.js'); + Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang'); Requirements::add_i18n_javascript(SAPPHIRE_ADMIN_DIR . '/javascript/lang'); diff --git a/admin/css/screen.css b/admin/css/screen.css index e9cde4fb7..4d7764bf2 100644 --- a/admin/css/screen.css +++ b/admin/css/screen.css @@ -206,17 +206,25 @@ form.nostyle .field { display: inline; padding: 0; border: 0; } form.nostyle label { float: none; width: auto; } form.nostyle .middleColumn { margin-left: 0; } -.field { display: block; padding: 0 8px 7px 8px; margin: 0 -8px 8px -8px; border-bottom: 1px solid rgba(201, 205, 206, 0.8); overflow: hidden; /* TreeDropdowns */ } +.field { display: block; padding: 0 8px 7px 8px; margin: 0 -8px 8px -8px; border-bottom: 1px solid rgba(201, 205, 206, 0.8); *zoom: 1; /* TreeDropdowns */ /* dropdowns */ /* chzn override */ } +.field:after { content: "\0020"; display: block; height: 0; clear: both; overflow: hidden; visibility: hidden; } .field.noLabel .middleColumn { margin-left: 0; } .field label.left { float: left; width: 176px; padding: 8px 8px 8px 0; line-height: 16px; } .field label.left span { display: block; font-size: 11px; color: #848484; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; o-text-overflow: ellipsis; } .field .middleColumn { margin-left: 184px; /* 23 as we lose a column on the field padding */ } -.field input.text, .field textarea, .field select { width: 90%; max-width: 512px; } -.field input.text, .field textarea, .field .TreeDropdownField { background: #fff; border: 1px solid #b3b3b3; padding: 7px 7px; margin: 0; outline: none; -moz-border-radius: 4px; -webkit-border-radius: 4px; -o-border-radius: 4px; -ms-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -ms-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); } -.field input.text:focus, .field textarea:focus, .field .TreeDropdownField:focus { border: 1px solid gray; } -.field .TreeDropdownField { padding: 0; } -.field .TreeDropdownField .panel { margin-top: -4px; border: 1px solid #b3b3b3; border-top: none; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -o-border-bottom-left-radius: 4px; -ms-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -o-border-bottom-right-radius: 4px; -ms-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } -.field select { margin-top: 8px; } +.field input.text, .field textarea, .field select, .field .TreeDropdownField { width: 90%; max-width: 512px; } +.field input.text, .field textarea, .field .TreeDropdownField { background: #fff; border: 1px solid #b3b3b3; padding: 8px 8px; margin: 0; outline: none; -moz-border-radius: 4px; -webkit-border-radius: 4px; -o-border-radius: 4px; -ms-border-radius: 4px; -khtml-border-radius: 4px; border-radius: 4px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -ms-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); } +.field input.text:focus, .field textarea:focus, .field .TreeDropdownField:focus { border: 1px solid #b3b3b3; -moz-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); -o-box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); } +.field .TreeDropdownField { padding: 0 14px 0 0; } +.field .TreeDropdownField .panel { margin-top: -2px; border: 1px solid #b3b3b3; border-top: none; padding-right: 14px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -o-border-bottom-left-radius: 4px; -ms-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -o-border-bottom-right-radius: 4px; -ms-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } +.field .TreeDropdownField .toggle-panel-link { margin-right: -14px; } +.field .dropdown select { margin-top: 8px; } +.field .chzn-container .chzn-results li { font-size: 11px; line-height: 16px; padding: 4px 4px; } +.field .chzn-container-active .chzn-single { border: 1px solid #9a9a9a; } +.field .chzn-container-single .chzn-single { height: 30px; line-height: 32px; /* not relative, as then we'd had to redo most of chzn */ font-size: 12px; background-image: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #efefef), color-stop(10%, #ffffff), color-stop(90%, #ffffff), color-stop(100%, #efefef)); background-image: -webkit-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -moz-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -o-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: -ms-linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); background-image: linear-gradient(#efefef, #ffffff 10%, #ffffff 90%, #efefef); } +.field .chzn-container-single .chzn-single:hover, .field .chzn-container-single .chzn-single:focus, .field .chzn-container-single .chzn-single:active { text-decoration: none; outline: none; } +.field .chzn-container-single .chzn-single div { width: 24px; } +.field .chzn-container-single .chzn-single div b { background-position: 3px 4px; } /** ---------------------------------------------------- Buttons ---------------------------------------------------- */ .cms .ui-widget { /* loading */ } @@ -351,7 +359,7 @@ html article, html aside, html details, html figcaption, html figure, html foote .message.error { background-color: #ffbe66; border-color: #ff9300; } /** -------------------------------------------- ModelAdmin -------------------------------------------- */ -.ModelAdmin .cms-content-tools { width: 300px; } +.ModelAdmin .cms-content-tools { width: 192px; } .ModelAdmin .ResultAssemblyBlock { display: none; } /** -------------------------------------------- "Add page" dialog -------------------------------------------- */ @@ -363,7 +371,8 @@ html article, html aside, html details, html figcaption, html figure, html foote .cms-page-add-form-dialog #PageType li .description { font-style: italic; } /** -------------------------------------------- Content toolbar -------------------------------------------- */ -.cms-content-toolbar { overflow: hidden; *zoom: 1; display: block; margin: 0 0 15px 0; border-bottom-width: 2px; border-bottom: 2px groove rgba(255, 255, 255, 0.8); -webkit-border-image: url(../images/textures/bg_fieldset_elements_border.png) 2 stretch stretch; border-image: url(../images/textures/bg_fieldset_elements_border.png) 2 stretch stretch; } +.cms-content-toolbar { display: block; margin: 0 0 15px 0; border-bottom: 1px solid rgba(201, 205, 206, 0.8); -webkit-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); -moz-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); -o-box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); box-shadow: 0 1px 0 rgba(255, 255, 255, 0.8); *zoom: 1; } +.cms-content-toolbar:after { content: "\0020"; display: block; height: 0; clear: both; overflow: hidden; visibility: hidden; } .cms-content-toolbar > * { float: left; } .cms-content-toolbar .cms-tree-view-modes * { display: inline-block; } .cms-content-toolbar .cms-content-batchactions form > * { display: inline-block; } @@ -401,7 +410,8 @@ form.member-profile-form .formattingHelpText { margin: 5px auto; color: #333; pa form.member-profile-form .formattingHelpText ul { padding: 0; } form.member-profile-form .formattingHelpText li { font-size: 11px; color: #333; margin-bottom: 2px; } -.cms .cms-content-fields { overflow: auto; background: none; } +.cms .cms-content { border-right: 1px solid rgba(201, 205, 206, 0.8); -moz-box-shadow: 3px 0 4px rgba(0, 0, 0, 0.15); -webkit-box-shadow: 3px 0 4px rgba(0, 0, 0, 0.15); -o-box-shadow: 3px 0 4px rgba(0, 0, 0, 0.15); box-shadow: 3px 0 4px rgba(0, 0, 0, 0.15); -moz-border-radius: 0; -webkit-border-radius: 0; -o-border-radius: 0; -ms-border-radius: 0; -khtml-border-radius: 0; border-radius: 0; } +.cms .cms-content-fields { /* always show a y scroll bar as popups like TreeDropdowns can trigger longer pages and the extra scroll bar doesn't fire our sizing bar */ overflow-y: scroll; overflow-x: auto; background: none; } /** -------------------------------------------- Panels -------------------------------------------- */ .cms-panel { overflow: hidden; } diff --git a/admin/javascript/LeftAndMain.js b/admin/javascript/LeftAndMain.js index b69ae9f61..4e987222b 100755 --- a/admin/javascript/LeftAndMain.js +++ b/admin/javascript/LeftAndMain.js @@ -321,10 +321,26 @@ this._super(); } - }) + }); + /** + * Styled dropdown select fields via chosen. Allows things like search and optgroup + * selection support. Rather than manually adding classes to selects we want + * styled, we style everything but the ones we tell it not to. + * + * For the CMS we also need to tell the parent div that his has a select so + * we can fix the height cropping. + */ + + $('.cms-container .field.dropdown').entwine({ + onmatch: function() { + $(this).find("select:not(.no-chzn)").chosen(); + $(this).addClass("has-chzn"); + + this._super(); + } + }); }); - }(jQuery)); // Backwards compatibility diff --git a/admin/scss/_forms.scss b/admin/scss/_forms.scss index 13946975c..25f92ac1b 100755 --- a/admin/scss/_forms.scss +++ b/admin/scss/_forms.scss @@ -23,7 +23,11 @@ form.nostyle { padding: 0 $grid-horizontal $grid-vertical - 1 $grid-horizontal; margin: 0 ($grid-horizontal * -1) $grid-vertical ($grid-horizontal * -1); border-bottom: 1px solid $color-shadow-light; - overflow: hidden; + + // using the legacy version as some of the more complex form fields + // need to use relative positioning and overflow hidden will not expand + // the containing boxes + @include legacy-pie-clearfix(); &.noLabel { .middleColumn { @@ -53,7 +57,8 @@ form.nostyle { input.text, textarea, - select { + select, + .TreeDropdownField { width: 90%; max-width: $grid-horizontal * 64; } @@ -63,9 +68,7 @@ form.nostyle { .TreeDropdownField { background: #fff; border: 1px solid lighten($color-medium-separator, 20%); - - // remove 1px for the border. - padding: ($grid-vertical - 1) ($grid-horizontal - 1); + padding: $grid-vertical $grid-horizontal; margin: 0; outline: none; @@ -73,26 +76,71 @@ form.nostyle { @include background-image(linear-gradient(#efefef, #fff 10%, #fff 90%, #efefef)); &:focus { - border: 1px solid $color-medium-separator; + border: 1px solid lighten($color-medium-separator, 20%); + + @include box-shadow(0 0 5px rgba(0,0,0,0.2)); } } /* TreeDropdowns */ .TreeDropdownField { - padding: 0; + padding: 0 14px 0 0; .panel { - margin-top: $grid-vertical * -0.5; + margin-top: -2px; border: 1px solid lighten($color-medium-separator, 20%); border-top: none; + padding-right: 14px; @include border-bottom-left-radius(4px); @include border-bottom-right-radius(4px); } + .toggle-panel-link { + margin-right: -14px; + } } - select { - margin-top: $grid-vertical; + /* dropdowns */ + .dropdown { + select { + margin-top: $grid-vertical; + } + } + + /* chzn override */ + .chzn-container { + .chzn-results li { + font-size: 11px; + line-height: $grid-vertical * 2; + padding: $grid-vertical / 2 $grid-horizontal / 2; + } + } + .chzn-container-active { + .chzn-single { + border: 1px solid lighten($color-medium-separator, 10%); + } + } + + .chzn-container-single .chzn-single { + height: 30px; + line-height: 32px; /* not relative, as then we'd had to redo most of chzn */ + font-size: $font-base-size; + + @include background-image(linear-gradient(#efefef, #fff 10%, #fff 90%, #efefef)); + + + &:hover, &:focus, &:active { + text-decoration: none; + outline: none; + } + + div { + width: 24px; + + b { + background-position: 3px 4px; + } + } } } @@ -111,6 +159,7 @@ form.nostyle { background: $color-button-disabled url(../../images/network-save.gif) no-repeat 4px center; border-color: darken($color-button-disabled, 10%); cursor: default; + @include text-shadow(none); @include box-shadow(none); diff --git a/admin/scss/_style.scss b/admin/scss/_style.scss index 2b00ab4c6..31d906775 100755 --- a/admin/scss/_style.scss +++ b/admin/scss/_style.scss @@ -354,7 +354,7 @@ html,body { .ModelAdmin { .cms-content-tools { - width: 300px; + width: $grid-horizontal * 24; } // Disable by default, will be replaced by more intuitive column selection in new data grid @@ -401,15 +401,13 @@ html,body { * -------------------------------------------- */ .cms-content-toolbar { - @include clearfix; + display: block; margin: 0 0 15px 0; - border-bottom-width: 2px; - border-bottom: 2px groove lighten($color-shadow-light, 95%); - -webkit-border-image: url(../images/textures/bg_fieldset_elements_border.png) 2 stretch stretch; - border-image: url(../images/textures/bg_fieldset_elements_border.png) 2 stretch stretch; - //TODO: use single border line with shadow instead:: http://daverupert.com/2011/06/two-tone-borders-with-css3/ + @include doubleborder(bottom, $color-light-separator, lighten($color-light-separator, 50%)); + @include legacy-pie-clearfix(); + & > * { float: left; } @@ -551,8 +549,19 @@ form.member-profile-form { } .cms { + .cms-content { + border-right: 1px solid $color-light-separator; + + @include box-shadow(3px 0 4px rgba(0,0,0,0.15)); + @include border-radius(0); + } + .cms-content-fields { - overflow: auto; + /* always show a y scroll bar as popups like TreeDropdowns + can trigger longer pages and the extra scroll bar doesn't + fire our sizing bar */ + overflow-y: scroll; + overflow-x: auto; background: none; } } diff --git a/css/TreeDropdownField.css b/css/TreeDropdownField.css index d980ea2b1..0282526a8 100644 --- a/css/TreeDropdownField.css +++ b/css/TreeDropdownField.css @@ -1,7 +1,7 @@ div.TreeDropdownField { width: 400px; background: #fff; - border: 1px solid #666; + border: 1px solid #aaa; cursor: pointer; overflow: hidden; } @@ -16,6 +16,7 @@ div.TreeDropdownField { div.TreeDropdownField .title { float: left; padding: 7px; + line-height: 16px; overflow:hidden; } @@ -25,13 +26,16 @@ div.TreeDropdownField { overflow: auto; display: none; cursor: default; - border: 1px solid #666; + border: 1px solid #aaa; border-top: none; margin: 1px 0 0 -1px; /* account for border on container div */ - width: 400px; height: 200px; background-color: #fff; z-index: 50; + -webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15); + -moz-box-shadow : 0 4px 5px rgba(0,0,0,.15); + -o-box-shadow : 0 4px 5px rgba(0,0,0,.15); + box-shadow : 0 4px 5px rgba(0,0,0,.15); } div.TreeDropdownField .panel ul.tree { margin: 0; @@ -42,12 +46,39 @@ div.TreeDropdownField { div.TreeDropdownField .toggle-panel-link { border: none; - text-decoration: none; - margin: 4px 4px 0 0; + margin: 0; z-index: 0; - overflow: hidden; + padding: 7px 3px; float: right; + overflow: hidden; + -webkit-border-radius: 0 4px 4px 0; + -moz-border-radius: 0 4px 4px 0; + border-radius: 0 4px 4px 0; + -moz-background-clip : padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + background: #ccc; + background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, #ccc), color-stop(0.6, #eee)); + background-image: -webkit-linear-gradient(center bottom, #ccc 0%, #eee 60%); + background-image: -moz-linear-gradient(center bottom, #ccc 0%, #eee 60%); + background-image: -o-linear-gradient(bottom, #ccc 0%, #eee 60%); + background-image: -ms-linear-gradient(top, #cccccc 0%,#eeeeee 60%); + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#cccccc', endColorstr='#eeeeee',GradientType=0 ); + background-image: linear-gradient(top, #cccccc 0%,#eeeeee 60%); + border-left: 1px solid #aaa; } + div.TreeDropdownField .toggle-panel-link.open-tree { + background: transparent; + border: none; + } + + div.TreeDropdownField .toggle-panel-link a { + text-decoration: none; + display: block; + border: 0; + margin: 0; + opacity: 0.5; + } div.TreeDropdownField .loading, div.TreeDropdownField .jstree-themeroller a.jstree-loading .jstree-icon { diff --git a/javascript/TreeDropdownField.js b/javascript/TreeDropdownField.js index 6dcb8e3c7..3b80b0960 100644 --- a/javascript/TreeDropdownField.js +++ b/javascript/TreeDropdownField.js @@ -1,5 +1,12 @@ (function($) { $.entwine('ss', function($){ + /** + * On resize of any close the open treedropdownfields + * as we'll need to redo with widths + */ + $(window).resize(function() { + $('.TreeDropdownField').closePanel(); + }); var strings = { 'openlink': 'Open', @@ -17,12 +24,16 @@ * @todo Expand title height to fit all elements */ $('.TreeDropdownField').entwine({ - onmatch: function() { + onmatch: function() { this.append( '' + - '' + + '' + '
' ); + + var linkTitle = strings.openLink; + if(linkTitle) this.find("toggle-panel-link a").attr('title', linkTitle); + if(this.data('title')) this.setTitle(this.data('title')); this.getPanel().hide(); @@ -36,10 +47,15 @@ // set the panel to the bottom of the field panel.css('top', this.position().top + this.height()); + panel.css('width', this.width()); + panel.show(); // swap the down arrow with an up arrow - this.find(".toggle-panel-link") + var toggle = this.find(".toggle-panel-link"); + toggle.addClass('open-tree'); + + toggle.find("a") .removeClass('ui-icon-triangle-1-s') .addClass('ui-icon-triangle-1-n'); @@ -47,7 +63,10 @@ }, closePanel: function() { // swap the up arrow with a down arrow - this.find(".toggle-panel-link") + var toggle = this.find(".toggle-panel-link"); + toggle.removeClass('open-tree'); + + toggle.find("a") .removeClass('ui-icon-triangle-1-n') .addClass('ui-icon-triangle-1-s');