diff --git a/layouts/joomla/form/field/color/advanced.php b/layouts/joomla/form/field/color/advanced.php index aaef836012c55..2971e462aaab9 100644 --- a/layouts/joomla/form/field/color/advanced.php +++ b/layouts/joomla/form/field/color/advanced.php @@ -36,16 +36,21 @@ * @var integer $size Size attribute of the input. * @var boolean $spellchec Spellcheck state for the form field. * @var string $validate Validation rules to apply. - * @var string $value Value attribute of the field. + * @var string $color Value attribute of the field. * @var array $checkedOptions Options that will be set as checked. * @var boolean $hasValue Has this field a value assigned? * @var array $options Options available for this field. * @var array $checked Is this field checked? * @var array $position Is this field checked? * @var array $control Is this field checked? + * @var boolean $changeFormat Shows buttons to change between formats ? */ -if ($validate !== 'color' && in_array($format, array('rgb', 'rgba'), true)) +if ($changeFormat) +{ + $format = $color[0] != '#' && strpos($color, 'rgb') === 0 ? (strpos($color, 'rgba') === 0 ? 'rgba' : 'rgb') : 'hex'; +} +if (in_array($format, array('rgb', 'rgba'), true) && $validate !== 'color') { $alpha = ($format === 'rgba'); $placeholder = $alpha ? 'rgba(0, 0, 0, 0.5)' : 'rgb(0, 0, 0)'; @@ -54,11 +59,10 @@ { $placeholder = '#rrggbb'; } - $inputclass = ($keywords && ! in_array($format, array('rgb', 'rgba'), true)) ? ' keywords' : ' ' . $format; $class = ' class="' . trim('minicolors ' . $class) . ($validate === 'color' ? '' : $inputclass) . '"'; $control = $control ? ' data-control="' . $control . '"' : ''; -$format = $format ? ' data-format="' . $format . '"' : ''; +$dataformat = $format ? ' data-format="' . $format . '"' : ''; $keywords = $keywords ? ' data-keywords="' . $keywords . '"' : ''; $validate = $validate ? ' data-validate="' . $validate . '"' : ''; $disabled = $disabled ? ' disabled' : ''; @@ -73,8 +77,21 @@ JHtml::_('jquery.framework'); JHtml::_('script', 'system/html5fallback.js', array('version' => 'auto', 'relative' => true)); JHtml::_('script', 'jui/jquery.minicolors.min.js', array('version' => 'auto', 'relative' => true)); -JHtml::_('stylesheet', 'jui/jquery.minicolors.css', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'jui/jquery.minicolors.min.css', array('version' => 'auto', 'relative' => true)); +JHtml::_('stylesheet', 'system/fields/color.min.css', array('version' => 'auto', 'relative' => true)); JHtml::_('script', 'system/color-field-adv-init.min.js', array('version' => 'auto', 'relative' => true)); ?> -/> +
+ /> + +
+ + + +
+ +
diff --git a/libraries/joomla/form/fields/color.php b/libraries/joomla/form/fields/color.php index d3d329c440d58..4bce0df1dac8c 100644 --- a/libraries/joomla/form/fields/color.php +++ b/libraries/joomla/form/fields/color.php @@ -40,7 +40,15 @@ class JFormFieldColor extends JFormField * @var string * @since 3.6.0 */ - protected $format = 'hex'; + protected $format = ''; + + /** + * Show buttons to change formats between hex, rgb, rgba. + * + * @var boolean + * @since 3.7.0 + */ + protected $changeFormat = false; /** * The keywords (transparent,initial,inherit). @@ -100,6 +108,7 @@ public function __get($name) case 'keywords': case 'exclude': case 'colors': + case 'changeFormat': case 'split': return $this->$name; } @@ -134,7 +143,9 @@ public function __set($name, $value) case 'colors': $this->$name = (string) $value; break; - + case 'changeFormat': + $this->$name = (bool) json_decode($value); + break; default: parent::__set($name, $value); } @@ -161,11 +172,12 @@ public function setup(SimpleXMLElement $element, $value, $group = null) if ($return) { $this->control = isset($this->element['control']) ? (string) $this->element['control'] : 'hue'; - $this->format = isset($this->element['format']) ? (string) $this->element['format'] : 'hex'; + $this->format = isset($this->element['format']) ? (string) $this->element['format'] : ''; $this->keywords = isset($this->element['keywords']) ? (string) $this->element['keywords'] : ''; $this->position = isset($this->element['position']) ? (string) $this->element['position'] : 'default'; $this->colors = (string) $this->element['colors']; $this->split = isset($this->element['split']) ? (int) $this->element['split'] : 3; + $this->changeFormat = isset($this->element['changeformat']) ? (bool) json_decode($this->element['changeformat']) : false; } return $return; @@ -221,7 +233,8 @@ protected function getLayoutData() 'format' => $this->format, 'keywords' => $this->keywords, 'position' => $position, - 'validate' => $this->validate + 'validate' => $this->validate, + 'changeFormat' => $this->changeFormat ); return array_merge($data, $extraData, $controlModeData); diff --git a/media/jui/css/jquery.minicolors.min.css b/media/jui/css/jquery.minicolors.min.css new file mode 100644 index 0000000000000..b01237b9b8c0b --- /dev/null +++ b/media/jui/css/jquery.minicolors.min.css @@ -0,0 +1 @@ +.minicolors{position:relative;display:inline-block;z-index:11}.minicolors-focus{z-index:12}.minicolors.minicolors-theme-default .minicolors-input{margin:0;margin-right:3px;border:solid 1px #CCC;font:14px sans-serif;width:65px;height:16px;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.04);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.04);box-shadow:inset 0 2px 4px rgba(0,0,0,.04);padding:2px;margin-right:-1px}.minicolors-theme-default.minicolors .minicolors-input{vertical-align:middle;outline:0}.minicolors-theme-default.minicolors-swatch-left .minicolors-input{margin-left:-1px;margin-right:auto}.minicolors-theme-default.minicolors-focus .minicolors-input,.minicolors-theme-default.minicolors-focus .minicolors-swatch{border-color:#999}.minicolors-hidden{position:absolute;left:-9999em}.minicolors-swatch{position:relative;width:20px;height:20px;background:url(../img/jquery.minicolors.png) -80px 0;border:solid 1px #CCC;vertical-align:middle;display:inline-block}.minicolors-swatch span{position:absolute;width:100%;height:100%;background:0;-webkit-box-shadow:inset 0 9px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 9px 0 rgba(255,255,255,.1);box-shadow:inset 0 9px 0 rgba(255,255,255,.1);display:inline-block}.minicolors-panel{position:absolute;top:26px;left:0;width:173px;height:152px;background:white;border:solid 1px #CCC;-webkit-box-shadow:0 0 20px rgba(0,0,0,.2);-moz-box-shadow:0 0 20px rgba(0,0,0,.2);box-shadow:0 0 20px rgba(0,0,0,.2);display:none}.minicolors-position-top .minicolors-panel{top:-156px}.minicolors-position-left .minicolors-panel{left:-83px}.minicolors-position-left.minicolors-with-opacity .minicolors-panel{left:-104px}.minicolors-with-opacity .minicolors-panel{width:194px}.minicolors .minicolors-grid{position:absolute;top:1px;left:1px;width:150px;height:150px;background:url(../img/jquery.minicolors.png) -120px 0;cursor:crosshair}.minicolors .minicolors-grid-inner{position:absolute;top:0;left:0;width:150px;height:150px;background:0}.minicolors-slider-saturation .minicolors-grid{background-position:-420px 0}.minicolors-slider-saturation .minicolors-grid-inner{background:url(../img/jquery.minicolors.png) -270px 0}.minicolors-slider-brightness .minicolors-grid{background-position:-570px 0}.minicolors-slider-brightness .minicolors-grid-inner{background:black}.minicolors-slider-wheel .minicolors-grid{background-position:-720px 0}.minicolors-slider,.minicolors-opacity-slider{position:absolute;top:1px;left:152px;width:20px;height:150px;background:#fff url(../img/jquery.minicolors.png) 0 0;cursor:crosshair}.minicolors-slider-saturation .minicolors-slider{background-position:-60px 0}.minicolors-slider-brightness .minicolors-slider{background-position:-20px 0}.minicolors-slider-wheel .minicolors-slider{background-position:-20px 0}.minicolors-opacity-slider{left:173px;background-position:-40px 0;display:none}.minicolors-with-opacity .minicolors-opacity-slider{display:block}.minicolors-grid .minicolors-picker{position:absolute;top:70px;left:70px;width:10px;height:10px;border:solid 1px black;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;margin-top:-6px;margin-left:-6px;background:0}.minicolors-grid .minicolors-picker span{position:absolute;top:0;left:0;width:6px;height:6px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;border:solid 2px white}.minicolors-picker{position:absolute;top:0;left:0;width:18px;height:2px;background:white;border:solid 1px black;margin-top:-2px}.minicolors-inline .minicolors-input,.minicolors-inline .minicolors-swatch{display:none}.minicolors-inline .minicolors-panel{position:relative;top:auto;left:auto;display:inline-block}.minicolors-theme-bootstrap .minicolors-input{padding:4px 6px;padding-left:30px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;font-size:14px;height:19px;width:65px;margin:0}.minicolors-theme-bootstrap .hex{width:65px}.minicolors-theme-bootstrap .keywords{width:100px}.minicolors-theme-bootstrap .rgb{width:160px}.minicolors-theme-bootstrap .rgba{width:220px}.minicolors-theme-bootstrap .minicolors-input[disabled]{background-color:#eee}.minicolors-theme-bootstrap .minicolors-swatch{cursor:pointer;position:absolute;left:4px;top:4px;z-index:12;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;overflow:hidden}.minicolors-theme-bootstrap.minicolors-swatch-position-right .minicolors-input{padding-left:6px;padding-right:30px}.minicolors-theme-bootstrap.minicolors-swatch-position-right .minicolors-swatch{left:auto;right:4px}.minicolors-theme-bootstrap .minicolors-panel{top:-68px;left:100%;z-index:13;padding:5px;border:1px solid #ddd;*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box}.minicolors-theme-bootstrap .minicolors-slider,.minicolors-theme-bootstrap .minicolors-opacity-slider{top:6px;margin-left:5px}.minicolors-theme-bootstrap .minicolors-grid{top:6px;left:6px}.minicolors-theme-bootstrap.minicolors-position-left .minicolors-panel{right:100%;left:auto}.minicolors-theme-bootstrap.minicolors-position-top .minicolors-panel{top:-164px;left:-6px}.minicolors-theme-bootstrap.minicolors-position-bottom .minicolors-panel{left:-6px;top:30px} \ No newline at end of file diff --git a/media/system/css/fields/color.css b/media/system/css/fields/color.css new file mode 100644 index 0000000000000..b18437efce238 --- /dev/null +++ b/media/system/css/fields/color.css @@ -0,0 +1,29 @@ +.minicolors.minicolors-input { + border: none; + padding-bottom: 6px; +} +.color-picker-group { + display: inline-block; + border: 1px solid #ccc; + border-radius: 4px; +} +.color-format-group { + display: inline-block; +} +.color-format-group .color-format-btn { + background-color: transparent; + border: none; + border-radius: 0; + margin: 0; + height: 30px; +} +.color-format-group .color-format-btn:focus, +.color-format-group .color-format-btn:active, +.color-format-group .color-format-btn:visited { + outline: none; +} +.color-format-group .color-format-btn.active { + background-color: #46a546; + color: white; + pointer-events: none; +} \ No newline at end of file diff --git a/media/system/css/fields/color.min.css b/media/system/css/fields/color.min.css new file mode 100644 index 0000000000000..bf0315fee5a03 --- /dev/null +++ b/media/system/css/fields/color.min.css @@ -0,0 +1 @@ +.minicolors.minicolors-input{border:0;padding-bottom:6px}.color-picker-group{display:inline-block;border:1px solid #ccc;border-radius:4px}.color-format-group{display:inline-block}.color-format-group .color-format-btn{background-color:transparent;border:0;border-radius:0;margin:0;height:30px}.color-format-group .color-format-btn:focus,.color-format-group .color-format-btn:active,.color-format-group .color-format-btn:visited{outline:0}.color-format-group .color-format-btn.active{background-color:#46a546;color:white;pointer-events:none} \ No newline at end of file diff --git a/media/system/js/color-field-adv-init.js b/media/system/js/color-field-adv-init.js index 8bf87ac9e57e5..04e896a3e9ffe 100644 --- a/media/system/js/color-field-adv-init.js +++ b/media/system/js/color-field-adv-init.js @@ -1,23 +1,73 @@ -jQuery(document).ready(function ($){ - - function initMinicolors(event, container) { - $(container || document).find('.minicolors').each(function() { - $(this).minicolors({ - control: $(this).attr('data-control') || 'hue', - format: $(this).attr('data-validate') === 'color' - ? 'hex' - : ($(this).attr('data-format') === 'rgba' - ? 'rgb' - : $(this).attr('data-format')) - || 'hex', - keywords: $(this).attr('data-keywords') || '', - opacity: $(this).attr('data-format') === 'rgba' ? true : false || false, - position: $(this).attr('data-position') || 'default', - theme: 'bootstrap' +jQuery(document).ready(function ($) { + // Array of rendered color-pickers + var $miniColors = [], + lineNum, $input, format; + + $('.minicolors').each(function () { + $miniColors.push($(this).minicolors({ + control: $(this).attr('data-control') || 'hue', + format: (function() { + if ($(this).attr('data-validate') === 'color') + { + return 'hex' + } + if ($(this).attr('data-format') === 'rgba') + { + return 'rgb' + } + return $(this).attr('data-format') + })(), + keywords: $(this).attr('data-keywords') || '', + opacity: $(this).attr('data-format') === 'rgba', + position: $(this).attr('data-position') || 'default', + theme: 'bootstrap' + })); + }); + + $('.color-picker-group .color-format-btn').each(function () { + $(this).click(function () { + // Get the line number from button format number + lineNum = Math.floor($('.color-format-btn').index(this) / 3); + format = $(this).data('format'); + + // Radio input implementation + $(this).parent().find('.color-format-btn').removeClass('active'); + $(this).addClass('active'); + + $input = $(this).parent().parent().find("input.minicolors-input"); + $input.removeClass("hex").removeClass("rgb").removeClass("rgba").addClass(format); + + // Replace input value + switch (format) { + case 'rgba': + $input.val($miniColors[lineNum].minicolors('rgbaString')); + break; + case 'rgb': + $input.val($miniColors[lineNum].minicolors('rgbString')); + break; + case 'hex': + $input.val(rgbToHex($input.val())); + break; + } + + $miniColors[lineNum].minicolors('settings', { + format: format == 'rgba' ? 'rgb' : format, + opacity: format == 'rgba' }); }); + }); + + // Convert number to hex + function componentToHex(c) { + var hex = c.toString(16); + return hex.length == 1 ? "0" + hex : hex; + } + + function rgbToHex(rgb) { + rgb = rgb.indexOf("rgba") === 0 ? rgb.slice(5) : rgb.slice(4); + rgb = rgb.replace(")", "").split(","); + + return "#" + componentToHex(parseInt(rgb[0])) + componentToHex(parseInt(rgb[1])) + componentToHex(parseInt(rgb[2])); } - initMinicolors(); - $(document).on('subform-row-add', initMinicolors); }); diff --git a/media/system/js/color-field-adv-init.min.js b/media/system/js/color-field-adv-init.min.js index 62b5fc62e0e00..17372eb7a09e4 100644 --- a/media/system/js/color-field-adv-init.min.js +++ b/media/system/js/color-field-adv-init.min.js @@ -1 +1 @@ -jQuery(document).ready(function($){function initMinicolors(event,container){$(container||document).find(".minicolors").each(function(){$(this).minicolors({control:$(this).attr("data-control")||"hue",format:$(this).attr("data-validate")==="color"?"hex":($(this).attr("data-format")==="rgba"?"rgb":$(this).attr("data-format"))||"hex",keywords:$(this).attr("data-keywords")||"",opacity:$(this).attr("data-format")==="rgba"?true:false||false,position:$(this).attr("data-position")||"default",theme:"bootstrap"})})}initMinicolors();$(document).on("subform-row-add",initMinicolors)}); \ No newline at end of file +jQuery(document).ready(function(t){function a(t){var a=t.toString(16);return 1==a.length?"0"+a:a}function r(t){return t=t.slice(0===t.indexOf("rgba")?5:4),t=t.replace(")","").split(","),"#"+a(parseInt(t[0]))+a(parseInt(t[1]))+a(parseInt(t[2]))}var o,i,s,n=[];t(".minicolors").each(function(){n.push(t(this).minicolors({control:t(this).attr("data-control")||"hue",format:function(){return"color"===t(this).attr("data-validate")?"hex":"rgba"===t(this).attr("data-format")?"rgb":t(this).attr("data-format")}(),keywords:t(this).attr("data-keywords")||"",opacity:"rgba"===t(this).attr("data-format"),position:t(this).attr("data-position")||"default",theme:"bootstrap"}))}),t(".color-picker-group .color-format-btn").each(function(){t(this).click(function(){switch(o=Math.floor(t(".color-format-btn").index(this)/3),s=t(this).data("format"),t(this).parent().find(".color-format-btn").removeClass("active"),t(this).addClass("active"),i=t(this).parent().parent().find("input.minicolors-input"),i.removeClass("hex").removeClass("rgb").removeClass("rgba").addClass(s),s){case"rgba":i.val(n[o].minicolors("rgbaString"));break;case"rgb":i.val(n[o].minicolors("rgbString"));break;case"hex":i.val(r(i.val()))}n[o].minicolors("settings",{format:"rgba"==s?"rgb":s,opacity:"rgba"==s})})})}); diff --git a/templates/protostar/templateDetails.xml b/templates/protostar/templateDetails.xml index 78e1f05593c04..e377b3b1af431 100644 --- a/templates/protostar/templateDetails.xml +++ b/templates/protostar/templateDetails.xml @@ -59,6 +59,7 @@ description="TPL_PROTOSTAR_COLOR_DESC" class="" default="#08C" + changeformat="true" />