In the last post I described how to extend the All properties view. I changed the behavior of forms editing by subscribing to events between widgets. But code did not affect the On Page edit view. It was possible to edit message details, while it was not possible to change the ShowMaintenanceMessage bool property state. It would be much more convenient for the editors to turn the checkbox on/off directly on the page.
The page markup would look like this:
1 2 3 |
<EPiServer:Property PropertyName="ShowMaintenanceMessage" runat="server" Visible='<%# PageEditing.PageIsInEditMode %>'> <RenderSettings Tag="InlineCheckbox"></RenderSettings> </EPiServer:Property> |
In the code above the InlineCheckbox tag points to the custom property renderer for ShowMaintenanceMessage property. Markup is simple, it’s just a preview of one of the two texts:
1 2 3 4 |
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CheckboxProperty.ascx.cs" Inherits="EpiServerThumbnail.Views.Properties.CheckboxProperty" %> <div class="property-checkbox"> <%# this.CurrentData == null || this.CurrentData.Value == false ? "Maintenance message hidden": "Maintenance message visible" %> </div> |
The PageEditing.PageIsInEditMode setting will show the property only in On Page edit mode. With those two small pieces of code we got the desired functionality working. Editor will be able to set ShowMaintenanceMessage directly in the On Page edit mode. But there is one more thing that could be improved – the property overlay editor. Now the the editor appears in a dialog with just one element to click.
It would be much better if we implemented an inline editor. This behaviour is controlled by uiWrapperType of CustomEditorSettings setting in EditorDescriptor. There are several available wrapper types – Inline, Flyout, Floating, Dialog and LegacyProperty. All of above constants are defined in UiWrapperType static class. In our case we are going to use Inline wrapper.
After I changed the wrapper type to inline I got a few client side exceptions saying that some methods are not implemented in the widget. So another thing to change was an underlying dojo widget assigned in uiType. EPiServer checkbox widget is displayed using epi.shell.widget.CheckBox classs. By default this class is used in On Page edit and in All Properties view modes. If we need to set On Page editing mode only, then we can use uiType key. Below is the full EditorDescriptor class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
using System; using System.Collections.Generic; using EPiServer.Shell; using EPiServer.Shell.ObjectEditing; using EPiServer.Shell.ObjectEditing.EditorDescriptors; namespace EpiServerThumbnail.Business.EditorDescriptors { [EditorDescriptorRegistration(TargetType = typeof (bool), UIHint = UiHint)] [EditorDescriptorRegistration(TargetType = typeof(bool?), UIHint = UiHint)] public class InlineBoleanEditorDescriptor : BooleanEditorDescriptor { public const string UiHint = "InlineBoolean"; public InlineBoleanEditorDescriptor() { this.ClientEditingClass = "epi.shell.widget.CheckBox"; } public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes) { base.ModifyMetadata(metadata, attributes); metadata.CustomEditorSettings["uiWrapperType"] = UiWrapperType.Inline; metadata.CustomEditorSettings["uiType"] = "alloy.editors.inlineCheckbox"; } } } |
The last thing left was to extend the checkbox widget by adding necessary methods. We needed to implement the isEditing, isValid and focus methods. I also created a title label linked to the checkbox.
The widget just extends the built in epi/shell/widget/CheckBox widget.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
define([ "dojo/_base/array", "dojo/_base/connect", "dojo/_base/declare", "dojo/_base/lang", "dojo/dom-construct", "dijit/focus", "dojo/on", "dojo/query", "dojo/dom-attr", "dojo/dom-style", "epi/dependency", "dijit/Tooltip", "epi/shell/widget/CheckBox" ], function( array, connect, declare, lang, domConstruct, focusUtil, on, query, domAttr, domStyle, dependency, Tooltip, CheckBox ) { return declare("alloy.editors.inlineCheckbox", [CheckBox], { labelNode: null, postCreate: function () { this.inherited(arguments); this.own( on(this.checkbox, "change", lang.hitch(this, function(e) { this._updateText(); })) ); this.labelNode = domConstruct.toDom("<label style='font-weight: bold;'>Show/hide message</label>"); domAttr.set(this.labelNode, "for", this.checkbox.id); domConstruct.place(this.labelNode, this.checkbox.domNode, "after"); domStyle.set(this.domNode, "padding", "20px"); }, focus: function () { this._makeContentEditable(); this.inherited(arguments); }, isValid: function (/*Boolean*/ isFocused) { return true; }, _makeContentEditable: function () { focusUtil.focus(this.domNode); }, isEditing: function () { return false; }, _updateText: function() { var value = this.get('value'); var propertyText = query('.property-checkbox', this.get("overlayItem").sourceItemNode); if (value) { propertyText.text("Maintenance message visible"); } else { propertyText.text("Maintenance message hidden"); } } }); }); |
Now we have the On Page edit with inline checkbox editor.
The full source code can be found on Gist.