Compare commits

...

29 Commits

Author SHA1 Message Date
Niels Lyngsoe 92453c4652 fix front-end requirement of umb-checkbox 2019-03-06 11:18:07 +01:00
Shannon Deminick 5ddba3e64e Merge pull request #3851 from umbraco/temp-fix-formdatacollection-3796
Fixes binding of FormDataCollection for GET requests which fixes the …
2019-03-05 13:39:37 +10:00
Niels Lyngsø c72a5c07fe Merge pull request #3464 from BatJan/feature/temp-U4-3463
3463 - Suggestion: Make checkboxes look prettier in checkbox lists
2019-03-04 11:39:08 +01:00
Niels Lyngsoe 409ae99bf7 renaming of umb-form-control to umb-form-check 2019-03-04 10:29:58 +01:00
Jan Skovgaard 969a9c1193 Update radiobuttons view to make use of the umb-radiobutton directive 2019-02-27 09:56:22 +01:00
Jan Skovgaard 3643e170c5 Add radiobutton directive 2019-02-27 09:55:52 +01:00
Jan Skovgaard afc872de5a Refactor checkboxlist to make use of the umbcheckbox directive 2019-02-27 09:40:48 +01:00
Jan Skovgaard 56aef39014 Add checkbox directive 2019-02-27 09:40:25 +01:00
Jan Skovgaard ae07b2b299 Refactor modifiers so they're done on the top level of the block instead 2019-02-26 21:42:24 +01:00
Jan Skovgaard b99cf238e0 Fix order of pseudo selectors to :focus is actually also set on the focused radio button 2019-02-26 21:26:14 +01:00
Jan Skovgaard 68457b7eaf Refactor styling of checkbox and radiobuttons so they're now both "umb-form-control" with modifiers, which makes it easier to reuse especially the checkbox throughout the UI. The umb-editor has been extented to have a item element and a list modfier too. Overall less code too 2019-02-26 21:21:55 +01:00
Jan Skovgaard 24c74676f6 Merge branch 'dev-v7' into feature/temp-U4-3463 2019-02-26 19:45:51 +01:00
Per Søndergaard Jensen ac1ee2fe0c #4428 - Replaced Log.Add calls with AuditService.Add in translations 2019-02-26 11:17:08 +01:00
Jan Skovgaard 94a4e34e0c Make sure to hide the whole state element for screen readers rather than just the icon 2019-01-27 15:32:52 +01:00
Jan Skovgaard 7d42583177 Fix animation 2019-01-27 15:30:02 +01:00
Jan Skovgaard 77a8697ca7 Make sure the border is green when the checkbox is checked and that it's darker gray when it is focused (also while checked) 2019-01-27 15:24:49 +01:00
Jan Skovgaard 7462686778 Add styles and minor refactoring so we no longer use the "wing" icon when a radio button is checked but rather make it look like a readio button 2019-01-27 15:22:37 +01:00
Jan Skovgaard 44d5ce4a2e Include the radiobuttonlist component 2019-01-27 15:21:54 +01:00
Jan Skovgaard 34888f31e6 Place the ul styling in the proper context 2019-01-27 14:50:15 +01:00
Jan Skovgaard 0994aac656 Restructure markup to ensure the label text is properly wrapped and make sure it all aligns nicely on small breakpoints too 2019-01-27 14:38:27 +01:00
Jan Skovgaard 0e0d38be30 Refactor styling of the checkbox so the boxes are now a tad smaller and better aligned with one another and the UI in general 2019-01-27 14:18:41 +01:00
Jan Skovgaard 91735e7e3f Fix bad merge 2019-01-27 14:17:59 +01:00
Jan Skovgaard 0d4b3e4173 Merge branch 'dev-v7' into feature/temp-U4-3463
# Conflicts:
#	src/Umbraco.Web.UI.Client/src/less/components/umb-radiobuttons-list.less
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.html
#	src/Umbraco.Web.UI.Client/src/views/propertyeditors/radiobuttons/radiobuttons.html
2019-01-27 13:31:33 +01:00
Shannon a0f15bba44 Fixes binding of FormDataCollection for GET requests which fixes the compatibility with the latest WebApi 5.2.7 version 2018-12-11 11:58:39 +11:00
Jan Skovgaard 007cdeb9ab Fix long label issue on RADIO button list 2018-10-31 21:48:47 +01:00
Jan Skovgaard 5716353518 Offset the state 1 px to align it with the radio button list if they ever occur as properties beneath each other 2018-10-31 21:46:00 +01:00
Jan Skovgaard 87340d6c2c Fix width issue on the checkbox label 2018-10-31 21:24:35 +01:00
Jan Skovgaard fc742bcf18 Merge branch 'dev-v7' into feature/temp-U4-3463 2018-10-31 20:03:05 +01:00
Jan Skovgaard 4eb4cd8962 Refactor checkboxlist to show a prettier checkbox than the default browser one 2018-10-28 16:35:37 +01:00
18 changed files with 339 additions and 49 deletions
@@ -0,0 +1,55 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbCheckbox
@restrict E
@scope
@description
<b>Added in Umbraco version 7.14.0</b> Use this directive to render an umbraco checkbox.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-checkbox
name="checkboxlist"
value="{{key}}"
model="true"
text="{{text}}">
</umb-checkbox>
</div>
</pre>
@param {boolean} model Set to <code>true</code> or <code>false</code> to set the checkbox to checked or unchecked.
@param {string} value Set the value of the checkbox.
@param {string} name Set the name of the checkbox.
@param {string} text Set the text for the checkbox label.
**/
(function () {
'use strict';
function CheckboxDirective() {
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/forms/umb-checkbox.html',
scope: {
model: "=",
value: "@",
name: "@",
text: "@",
required: "="
}
};
return directive;
}
angular.module('umbraco.directives').directive('umbCheckbox', CheckboxDirective);
})();
@@ -0,0 +1,54 @@
/**
@ngdoc directive
@name umbraco.directives.directive:umbRadiobutton
@restrict E
@scope
@description
<b>Added in Umbraco version 7.14.0</b> Use this directive to render an umbraco radio button.
<h3>Markup example</h3>
<pre>
<div ng-controller="My.Controller as vm">
<umb-radiobutton
name="checkboxlist"
value="{{key}}"
model="true"
text="{{text}}">
</umb-radiobutton>
</div>
</pre>
@param {boolean} model Set to <code>true</code> or <code>false</code> to set the radiobutton to checked or unchecked.
@param {string} value Set the value of the radiobutton.
@param {string} name Set the name of the radiobutton.
@param {string} text Set the text for the radiobutton label.
**/
(function () {
'use strict';
function RadiobuttonDirective() {
var directive = {
restrict: 'E',
replace: true,
templateUrl: 'views/components/forms/umb-radiobutton.html',
scope: {
model: "=",
value: "@",
name: "@",
text: "@"
}
};
return directive;
}
angular.module('umbraco.directives').directive('umbRadiobutton', RadiobuttonDirective);
})();
@@ -101,6 +101,7 @@
@import "components/umb-confirm-action.less";
@import "components/umb-keyboard-shortcuts-overview.less";
@import "components/umb-checkbox-list.less";
@import "components/umb-form-check.less";
@import "components/umb-locked-field.less";
@import "components/umb-tabs.less";
@import "components/umb-load-indicator.less";
@@ -1,3 +1,6 @@
@checkboxWidth: 15px;
@checkboxHeight: 15px;
.umb-checkbox-list {
list-style: none;
margin-left: 0;
@@ -0,0 +1,125 @@
@checkboxWidth: 15px;
@checkboxHeight: 15px;
.umb-form-check {
display: flex;
flex-wrap: wrap;
align-items: center;
position: relative;
padding: 0;
margin: 0;
&__text{
margin: 0 0 0 26px;
position: relative;
top: 2px;
}
&__input{
position: absolute;
top: 0;
left: 0;
opacity: 0;
&:checked ~ .umb-form-check__state .umb-form-check__check{
border-color: @green;
}
&:focus:checked ~ .umb-form-check .umb-form-check__check,
&:focus ~ .umb-form-check__state .umb-form-check__check{
border-color: @gray-5;
}
&:checked ~ .umb-form-check__state{
.umb-form-check__check{
// This only happens if the state has a radiobutton modifier
.umb-form-check--radiobutton &{
&:before{
opacity: 1;
transform: scale(1);
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
&:before{
width: @checkboxWidth;
height: @checkboxHeight;
}
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
.umb-form-check__icon{
opacity: 1;
}
}
}
}
&__state{
height: 17px;
position: absolute;
top: 2px;
left: 0;
}
&__check{
position: relative;
border: 1px solid @gray-7;
width: @checkboxWidth;
height: @checkboxHeight;
&:before{
content: "";
background: @green;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
// This only happens if state has the radiobutton modifier
.umb-form-check--radiobutton &{
border-radius: 100%;
&:before{
width: 9px;
height: 9px;
border-radius: 100%;
opacity: 0;
transform: scale(0);
transition: .15s ease-out;
}
}
// This only happens if state has the checkbox modifier
.umb-form-check--checkbox &{
&:before{
width: 0;
height: 0;
transition: .05s ease-out;
}
}
}
&__icon{
color: @white;
text-align: center;
font-size: 10px;
opacity: 0;
transition: .2s ease-out;
&:before{
position: absolute;
top: -2px;
right: 0;
left: 0;
bottom: 0;
margin: auto;
}
}
}
@@ -13,7 +13,16 @@
&-push {
float:right;
}
}
&--list{
float: left;
}
&__item{
line-height: 1;
margin: 0 0 5px;
}
}
.umb-editor-tiny {
@@ -246,7 +255,7 @@ div.umb-codeeditor .umb-btn-toolbar {
margin: 24px 0 0;
display: flex;
}
&__input {
width: 100%;
&-wrap{
@@ -0,0 +1,14 @@
<label class="checkbox umb-form-check umb-form-check--checkbox">
<input type="checkbox" name="{{name}}"
value="{{value}}"
ng-model="model"
class="umb-form-check__input"
ng-required="required" />
<div class="umb-form-check__state umb-form-check__state" aria-hidden="true">
<div class="umb-form-check__check">
<i class="umb-form-check__icon icon-check"></i>
</div>
</div>
<span class="umb-form-check__text">{{text}}</span>
</label>
@@ -0,0 +1,11 @@
<label class="radio umb-form-check umb-form-check--radiobutton">
<input type="radio" name="radiobuttons-{{name}}"
value="{{value}}"
ng-model="model"
class="umb-form-check__input" />
<div class="umb-form-check__state umb-form-check__state" aria-hidden="true">
<div class="umb-form-check__check"></div>
</div>
<span class="umb-form-check__text">{{text}}</span>
</label>
@@ -1,14 +1,8 @@
<div class="umb-editor umb-checkboxlist" ng-controller="Umbraco.PropertyEditors.CheckboxListController">
<div class="umb-editor umb-editor--list" ng-controller="Umbraco.PropertyEditors.CheckboxListController">
<ul class="unstyled">
<li ng-repeat="item in selectedItems">
<label class="checkbox">
<input type="checkbox" name="checkboxlist"
value="{{item.key}}"
ng-model="item.checked"
ng-required="model.validation.mandatory && !model.value.length" />
{{item.val}}
</label>
<li ng-repeat="item in selectedItems" class="umb-editor__item">
<umb-checkbox name="checkboxlist" value="{{item.key}}" model="item.checked" text="{{item.val}}" required="model.validation.mandatory && !model.value.length"></umb-checkbox>
</li>
</ul>
@@ -1,12 +1,8 @@
<div class="umb-editor umb-radiobuttons" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<div class="umb-editor umb-edtitor--list" ng-controller="Umbraco.PropertyEditors.RadioButtonsController">
<ul class="unstyled">
<li ng-repeat="item in model.config.items">
<label class="radio">
<input type="radio" name="radiobuttons-{{model.alias}}"
value="{{item.id}}"
ng-model="model.value" />
{{item.value}}
</label>
<li ng-repeat="item in model.config.items" class="umb-editor__item">
<umb-radiobutton name="{{model.alias}}" value="{{item.id}}" model="model.value" text="{{item.value}}"></umb-radiobutton>
</li>
</ul>
</div>
</div>
@@ -7,6 +7,7 @@ using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.Trees;
@@ -31,8 +32,7 @@ namespace Umbraco.Web.Trees
/// <param name="queryStrings"></param>
/// <param name="onlyInitialized">An optional bool (defaults to true), if set to false it will also load uninitialized trees</param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public async Task<SectionRootNode> GetApplicationTrees(string application, string tree, FormDataCollection queryStrings, bool onlyInitialized = true)
public async Task<SectionRootNode> GetApplicationTrees(string application, string tree, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings, bool onlyInitialized = true)
{
application = application.CleanForXss();
@@ -15,6 +15,7 @@ using Umbraco.Web.WebApi.Filters;
using umbraco;
using umbraco.BusinessLogic.Actions;
using System.Globalization;
using System.Web.Http.ModelBinding;
using Umbraco.Core.Services;
namespace Umbraco.Web.Trees
@@ -30,8 +31,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetTreeNode(string id, FormDataCollection queryStrings)
public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
int asInt;
Guid asGuid = Guid.Empty;
@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using System.Web.Security;
using Umbraco.Core;
using Umbraco.Core.Models;
@@ -53,8 +54,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetTreeNode(string id, FormDataCollection queryStrings)
public TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
var node = GetSingleTreeNode(id, queryStrings);
+7 -9
View File
@@ -2,6 +2,7 @@
using System.Globalization;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http.ModelBinding;
using Umbraco.Core;
using Umbraco.Core.Events;
using Umbraco.Web.Models.Trees;
@@ -43,7 +44,7 @@ namespace Umbraco.Web.Trees
/// We are allowing an arbitrary number of query strings to be pased in so that developers are able to persist custom data from the front-end
/// to the back end to be used in the query for model data.
/// </remarks>
protected abstract TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings);
protected abstract TreeNodeCollection GetTreeNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
/// <summary>
/// Returns the menu structure for the node
@@ -51,7 +52,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
protected abstract MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings);
protected abstract MenuItemCollection GetMenuForNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings);
/// <summary>
/// The name to display on the root node
@@ -68,8 +69,7 @@ namespace Umbraco.Web.Trees
/// </summary>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public TreeNode GetRootNode(FormDataCollection queryStrings)
public TreeNode GetRootNode([ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var node = CreateRootNode(queryStrings);
@@ -108,8 +108,7 @@ namespace Umbraco.Web.Trees
/// We are allowing an arbitrary number of query strings to be pased in so that developers are able to persist custom data from the front-end
/// to the back end to be used in the query for model data.
/// </remarks>
[HttpQueryStringFilter("queryStrings")]
public TreeNodeCollection GetNodes(string id, FormDataCollection queryStrings)
public TreeNodeCollection GetNodes(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var nodes = GetTreeNodes(id, queryStrings);
@@ -140,8 +139,7 @@ namespace Umbraco.Web.Trees
/// <param name="id"></param>
/// <param name="queryStrings"></param>
/// <returns></returns>
[HttpQueryStringFilter("queryStrings")]
public MenuItemCollection GetMenu(string id, FormDataCollection queryStrings)
public MenuItemCollection GetMenu(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))]FormDataCollection queryStrings)
{
if (queryStrings == null) queryStrings = new FormDataCollection("");
var menu = GetMenuForNode(id, queryStrings);
@@ -390,4 +388,4 @@ namespace Umbraco.Web.Trees
if (handler != null) handler(instance, e);
}
}
}
}
+1
View File
@@ -840,6 +840,7 @@
<Compile Include="WebApi\Filters\EnableOverrideAuthorizationAttribute.cs" />
<Compile Include="WebApi\Filters\FeatureAuthorizeAttribute.cs" />
<Compile Include="WebApi\Filters\FilterGrouping.cs" />
<Compile Include="WebApi\Filters\HttpQueryStringModelBinder.cs" />
<Compile Include="WebApi\Filters\LegacyTreeAuthorizeAttribute.cs" />
<Compile Include="WebApi\Filters\OutgoingEditorModelEventAttribute.cs" />
<Compile Include="WebApi\Filters\OutgoingNoHyphenGuidFormatAttribute.cs" />
@@ -6,13 +6,7 @@ using System.Web.Http.Filters;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// Allows an Action to execute with an arbitrary number of QueryStrings
/// </summary>
/// <remarks>
/// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number
/// but this will allow you to do it
/// </remarks>
[Obsolete("Use HttpQueryStringModelBinder to model bind FormDataCollection in a GET request")]
public sealed class HttpQueryStringFilterAttribute : ActionFilterAttribute
{
public string ParameterName { get; private set; }
@@ -40,4 +34,4 @@ namespace Umbraco.Web.WebApi.Filters
base.OnActionExecuting(actionContext);
}
}
}
}
@@ -0,0 +1,32 @@
using System.Collections.Generic;
using System.Net.Http.Formatting;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// Allows an Action to execute with an arbitrary number of QueryStrings
/// </summary>
/// <remarks>
/// Just like you can POST an arbitrary number of parameters to an Action, you can't GET an arbitrary number
/// but this will allow you to do it
/// </remarks>
public sealed class HttpQueryStringModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
//get the query strings from the request properties
if (actionContext.Request.Properties.ContainsKey("MS_QueryNameValuePairs"))
{
if (actionContext.Request.Properties["MS_QueryNameValuePairs"] is IEnumerable<KeyValuePair<string, string>> queryStrings)
{
var formData = new FormDataCollection(queryStrings);
bindingContext.Model = formData;
return true;
}
}
return false;
}
}
}
@@ -4,12 +4,13 @@ using System.Text.RegularExpressions;
using System.Web;
using Umbraco.Core.Logging;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.language;
using umbraco.cms.businesslogic.property;
using umbraco.cms.businesslogic.task;
using umbraco.cms.businesslogic.web;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Language = umbraco.cms.businesslogic.language.Language;
using Property = umbraco.cms.businesslogic.property.Property;
using Task = umbraco.cms.businesslogic.task.Task;
namespace umbraco.cms.businesslogic.translation
{
@@ -32,8 +33,10 @@ namespace umbraco.cms.businesslogic.translation
task.Save();
// Add log entry
// Note: not updated to LogHelper as LogTypes.SendToTranslate might be something special, not sure
Log.Add(LogTypes.SendToTranslate, user, node.Id, "Translator: " + translator.Name + ", Language: " + language.FriendlyName);
ApplicationContext.Current.Services.AuditService.Add(AuditType.SendToTranslate,
"Translator: " + translator.Name + ", Language: " + language.FriendlyName,
user.Id,
node.Id);
// send it
if (sendEmail)
@@ -128,4 +131,4 @@ namespace umbraco.cms.businesslogic.translation
return collection.Count;
}
}
}
}