Completes: U4-3274 Create new Slider editor
This commit is contained in:
@@ -1,138 +1,138 @@
|
||||
/*!
|
||||
* Slider for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.slider {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
}
|
||||
.slider.slider-horizontal {
|
||||
width: 210px;
|
||||
height: 20px;
|
||||
}
|
||||
.slider.slider-horizontal .slider-track {
|
||||
height: 10px;
|
||||
width: 100%;
|
||||
margin-top: -5px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-selection {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle {
|
||||
margin-left: -10px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle.triangle {
|
||||
border-width: 0 10px 10px 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom-color: #0480be;
|
||||
margin-top: 0;
|
||||
}
|
||||
.slider.slider-vertical {
|
||||
height: 210px;
|
||||
width: 20px;
|
||||
}
|
||||
.slider.slider-vertical .slider-track {
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
margin-left: -5px;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-selection {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle {
|
||||
margin-left: -5px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle.triangle {
|
||||
border-width: 10px 0 10px 10px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border-left-color: #0480be;
|
||||
margin-left: 0;
|
||||
}
|
||||
.slider input {
|
||||
display: none;
|
||||
}
|
||||
.slider .tooltip-inner {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.slider-track {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-selection {
|
||||
position: absolute;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));
|
||||
background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-handle {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #0e90d2;
|
||||
background-image: -moz-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
|
||||
background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: -o-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: linear-gradient(to bottom, #149bdf, #0480be);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
opacity: 0.8;
|
||||
border: 0px solid transparent;
|
||||
}
|
||||
.slider-handle.round {
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.slider-handle.triangle {
|
||||
background: transparent none;
|
||||
/*!
|
||||
* Slider for Bootstrap
|
||||
*
|
||||
* Copyright 2012 Stefan Petre
|
||||
* Licensed under the Apache License v2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*/
|
||||
.slider {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
}
|
||||
.slider.slider-horizontal {
|
||||
width: 210px;
|
||||
height: 20px;
|
||||
}
|
||||
.slider.slider-horizontal .slider-track {
|
||||
height: 10px;
|
||||
width: 100%;
|
||||
margin-top: -5px;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-selection {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle {
|
||||
margin-left: -10px;
|
||||
margin-top: -5px;
|
||||
}
|
||||
.slider.slider-horizontal .slider-handle.triangle {
|
||||
border-width: 0 10px 10px 10px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom-color: #0480be;
|
||||
margin-top: 0;
|
||||
}
|
||||
.slider.slider-vertical {
|
||||
height: 210px;
|
||||
width: 20px;
|
||||
}
|
||||
.slider.slider-vertical .slider-track {
|
||||
width: 10px;
|
||||
height: 100%;
|
||||
margin-left: -5px;
|
||||
left: 50%;
|
||||
top: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-selection {
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle {
|
||||
margin-left: -5px;
|
||||
margin-top: -10px;
|
||||
}
|
||||
.slider.slider-vertical .slider-handle.triangle {
|
||||
border-width: 10px 0 10px 10px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
border-left-color: #0480be;
|
||||
margin-left: 0;
|
||||
}
|
||||
.slider input {
|
||||
display: none;
|
||||
}
|
||||
.slider .tooltip-inner {
|
||||
white-space: nowrap;
|
||||
}
|
||||
.slider-track {
|
||||
position: absolute;
|
||||
cursor: pointer;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
|
||||
background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
|
||||
background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-selection {
|
||||
position: absolute;
|
||||
background-color: #f7f7f7;
|
||||
background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));
|
||||
background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);
|
||||
background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.slider-handle {
|
||||
position: absolute;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-color: #0e90d2;
|
||||
background-image: -moz-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
|
||||
background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: -o-linear-gradient(top, #149bdf, #0480be);
|
||||
background-image: linear-gradient(to bottom, #149bdf, #0480be);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
|
||||
-webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
-moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);
|
||||
opacity: 0.8;
|
||||
border: 0px solid transparent;
|
||||
}
|
||||
.slider-handle.round {
|
||||
-webkit-border-radius: 20px;
|
||||
-moz-border-radius: 20px;
|
||||
border-radius: 20px;
|
||||
}
|
||||
.slider-handle.triangle {
|
||||
background: transparent none;
|
||||
}
|
||||
@@ -31,22 +31,24 @@ angular.module("umbraco")
|
||||
angular.forEach(editorConfig.stylesheets, function(val, key){
|
||||
stylesheets.push("/css/" + val + ".css");
|
||||
|
||||
stylesheetResource.getRulesByName(val).then(function(rules){
|
||||
angular.forEach(rules, function(rule){
|
||||
stylesheetResource.getRulesByName(val).then(function(rules) {
|
||||
angular.forEach(rules, function(rule) {
|
||||
var r = {};
|
||||
r.title = rule.name;
|
||||
if(rule.selector[0] == "."){
|
||||
if (rule.selector[0] == ".") {
|
||||
r.inline = "span";
|
||||
r.classes = rule.selector.substring(1);
|
||||
}else if(rule.selector[0] == "#"){
|
||||
}
|
||||
else if (rule.selector[0] == "#") {
|
||||
r.inline = "span";
|
||||
r.attributes = {id: rule.selector.substring(1)};
|
||||
}else{
|
||||
r.attributes = { id: rule.selector.substring(1) };
|
||||
}
|
||||
else {
|
||||
r.block = rule.selector;
|
||||
}
|
||||
|
||||
styleFormats.push(r);
|
||||
})
|
||||
styleFormats.push(r);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<div>
|
||||
<select ng-model="model.value" required name="orientation">
|
||||
<option value="horizontal">Horizontal</option>
|
||||
<option value="vertical">Vertical</option>
|
||||
</select>
|
||||
|
||||
<span class="help-inline" val-msg-for="orientation" val-toggle-msg="required">Required</span>
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title></title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,107 @@
|
||||
function sliderController($scope, $log, $element, assetsService, angularHelper) {
|
||||
|
||||
//configure some defaults
|
||||
if (!$scope.model.config.orientation) {
|
||||
$scope.model.config.orientation = "horizontal";
|
||||
}
|
||||
if (!$scope.model.config.initVal1) {
|
||||
$scope.model.config.initVal1 = 0;
|
||||
}
|
||||
else {
|
||||
$scope.model.config.initVal1 = parseFloat($scope.model.config.initVal1);
|
||||
}
|
||||
if (!$scope.model.config.initVal2) {
|
||||
$scope.model.config.initVal2 = 0;
|
||||
}
|
||||
else {
|
||||
$scope.model.config.initVal2 = parseFloat($scope.model.config.initVal2);
|
||||
}
|
||||
if (!$scope.model.config.minVal) {
|
||||
$scope.model.config.minVal = 0;
|
||||
}
|
||||
else {
|
||||
$scope.model.config.minVal = parseFloat($scope.model.config.minVal);
|
||||
}
|
||||
if (!$scope.model.config.maxVal) {
|
||||
$scope.model.config.maxVal = 100;
|
||||
}
|
||||
else {
|
||||
$scope.model.config.maxVal = parseFloat($scope.model.config.maxVal);
|
||||
}
|
||||
if (!$scope.model.config.step) {
|
||||
$scope.model.config.step = 1;
|
||||
}
|
||||
else {
|
||||
$scope.model.config.step = parseFloat($scope.model.config.step);
|
||||
}
|
||||
|
||||
/** This creates the slider with the model values - it's called on startup and if the model value changes */
|
||||
function createSlider() {
|
||||
|
||||
//the value that we'll give the slider - if it's a range, we store our value as a comma seperated val but this slider expects an array
|
||||
var sliderVal = null;
|
||||
|
||||
//configure the model value based on if range is enabled or not
|
||||
if ($scope.model.config.enableRange === "1") {
|
||||
//If no value saved yet - then use default value
|
||||
if (!$scope.model.value) {
|
||||
var i1 = parseFloat($scope.model.config.initVal1);
|
||||
var i2 = parseFloat($scope.model.config.initVal2);
|
||||
sliderVal = [
|
||||
isNaN(i1) ? $scope.model.config.minVal : (i1 >= $scope.model.config.minVal ? i1 : $scope.model.config.minVal),
|
||||
isNaN(i2) ? $scope.model.config.maxVal : (i2 > i1 ? (i2 <= $scope.model.config.maxVal ? i2 : $scope.model.config.maxVal) : $scope.model.config.maxVal)
|
||||
];
|
||||
}
|
||||
else if (!angular.isArray($scope.model.value)) {
|
||||
//this will mean it's a delimited value stored in the db, convert it to an array
|
||||
sliderVal = _.map($scope.model.value.split(','), function (item) {
|
||||
return parseFloat(item);
|
||||
});
|
||||
}
|
||||
}
|
||||
else {
|
||||
//If no value saved yet - then use default value
|
||||
if (!$scope.model.value) {
|
||||
sliderVal = parseFloat($scope.model.config.initVal1);
|
||||
}
|
||||
}
|
||||
|
||||
//initiate slider, add event handler and get the instance reference (stored in data)
|
||||
var slider = $element.find('.slider-item').slider({
|
||||
//set the slider val - we cannot do this with data- attributes when using ranges
|
||||
value: sliderVal
|
||||
}).on('slideStop', function () {
|
||||
angularHelper.safeApply($scope, function () {
|
||||
//Get the value from the slider and format it correctly, if it is a range we want a comma delimited value
|
||||
if ($scope.model.config.enableRange === "1") {
|
||||
$scope.model.value = slider.getValue().join(",");
|
||||
}
|
||||
else {
|
||||
$scope.model.value = slider.getValue();
|
||||
}
|
||||
});
|
||||
}).data('slider');
|
||||
|
||||
}
|
||||
|
||||
//tell the assetsService to load the bootstrap slider
|
||||
//libs from the plugin folder
|
||||
assetsService
|
||||
.loadJs("lib/slider/bootstrap-slider.js")
|
||||
.then(function () {
|
||||
|
||||
createSlider();
|
||||
|
||||
//here we declare a special method which will be called whenever the value has changed from the server
|
||||
//this is instead of doing a watch on the model.value = faster
|
||||
$scope.model.onValueChanged = function (newVal, oldVal) {
|
||||
createSlider();
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
//load the seperate css for the editor to avoid it blocking our js loading
|
||||
assetsService.loadCss("lib/slider/slider.css");
|
||||
|
||||
}
|
||||
angular.module("umbraco").controller("Umbraco.PropertyEditors.SliderController", sliderController);
|
||||
@@ -0,0 +1,11 @@
|
||||
<div ng-controller="Umbraco.PropertyEditors.SliderController">
|
||||
|
||||
<input type="text" name="slider" class="slider-item"
|
||||
data-slider-min="{{ model.config.minVal }}"
|
||||
data-slider-max="{{ model.config.maxVal }}"
|
||||
data-slider-step="{{ model.config.step }}"
|
||||
data-slider-orientation="{{ model.config.orientation }}"
|
||||
data-slider-selection="after"
|
||||
data-slider-tooltip="show" />
|
||||
|
||||
</div>
|
||||
@@ -13,17 +13,14 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
internal class SliderPreValueEditor : PreValueEditor
|
||||
{
|
||||
|
||||
|
||||
[PreValueField("enableRange", "Enable range", "boolean")]
|
||||
public string Type { get; set; }
|
||||
|
||||
[PreValueField("rangeType", "Range type", "views/propertyeditors/slider/rangetype.prevalues.html")]
|
||||
public string RangeType { get; set; }
|
||||
|
||||
|
||||
[PreValueField("initVal1", "Initial value", "number")]
|
||||
public int InitialValue { get; set; }
|
||||
|
||||
[PreValueField("initVal2", "Initial value 2", "number")]
|
||||
[PreValueField("initVal2", "Initial value 2", "number", Description = "Used when range is enabled")]
|
||||
public int InitialValue2 { get; set; }
|
||||
|
||||
[PreValueField("minVal", "Minimum value", "number")]
|
||||
@@ -31,13 +28,13 @@ namespace Umbraco.Web.PropertyEditors
|
||||
|
||||
[PreValueField("maxVal", "Maximum value", "number")]
|
||||
public int MaximumValue { get; set; }
|
||||
|
||||
[PreValueField("enabledSteps", "Enable step increments", "boolean")]
|
||||
public bool EnableSteps { get; set; }
|
||||
|
||||
|
||||
[PreValueField("step", "Step increments", "number")]
|
||||
public int StepIncrements { get; set; }
|
||||
|
||||
[PreValueField("orientation", "Orientation", "views/propertyeditors/slider/orientation.prevalues.html")]
|
||||
public string Orientation { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user