Example - Developing a widget
The following scenario will guide you through the process of developing a simple page builder widget step-by-step with full code samples. For more detailed information about the underlying development principles, see our general pages about developing widgets, widget properties and inline editors.
Prerequisite
To be able to use the widget in the page builder, you need to enable the page builder feature and set up an editable area.
When finished, the widget displays a simple message with a number of your choice. The number is set via a widget property and can be modified through an inline property editor or the properties dialog. The widget can be added to an editable area and displayed on the live site.
Note: The following example is based on the LearningKit project. To use the code samples in your project, you need to modify the namespaces, identifiers and other occurrences where LearningKit is mentioned to match your project’s name.
Widget
Create a widget with one modifiable integer property.
Property model
Create a property model NumberWidgetProperties.cs in the ~/Models/Widgets/NumberWidget folder:
using Kentico.Forms.Web.Mvc;
using Kentico.PageBuilder.Web.Mvc;
namespace LearningKit.Models.Widgets.NumberWidget
{
public class NumberWidgetProperties : IWidgetProperties
{
// Defines a property and sets its default value
// Assigns the default Xperience text input component, which allows users to enter
// a numeric value for the property in the widget's configuration dialog
[EditingComponent(IntInputComponent.IDENTIFIER, Order = 0, Label = "Number")]
public int Number { get; set; } = 22;
}
}
Partial view
Create a partial view _NumberWidget.cshtml in the ~/Views/Shared/Widgets folder:
@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc
@using LearningKit.Models.InlineEditors.NumberEditor
@using LearningKit.Models.Widgets.NumberWidget
@model ComponentViewModel<NumberWidgetProperties>
<h3 style="background-color: #dddddd;">The number you chose for today is: @Model.Properties.Number</h3>
@* Shows an inline editor when rendered in the edit mode of the Pages application in Xperience *@
@if (Context.Kentico().PageBuilder().EditMode)
{
Html.RenderPartial("InlineEditors/_NumberEditor", new NumberEditorModel
{
@* Use the nameof() operator to get the name of the edited property from the widget property model *@
PropertyName = nameof(NumberWidgetProperties.Number),
Number = Model.Properties.Number
});
}
Widget registration
Register the widget into the system using the RegisterWidget assembly attribute. We recommend adding a dedicated code file to your project’s ~/App_Start folder for the purposes of component registration, for example named PageBuilderComponentRegister.cs.
using LearningKit.Models.Widgets.NumberWidget;
using Kentico.PageBuilder.Web.Mvc;
// Registers the 'Selected number' widget (it uses the system's default controller and ComponentViewModel)
[assembly: RegisterWidget("LearningKit.Widgets.NumberWidget",
"Selected number",
typeof(NumberWidgetProperties),
customViewName: "Widgets/_NumberWidget",
IconClass = "icon-octothorpe")]
Inline editor
Implement an inline editor able to modify the Number integer property.
Model
Create an editor model NumberEditorModel.cs in the ~/Models/InlineEditors/NumberEditor folder:
namespace LearningKit.Models.InlineEditors.NumberEditor
{
public class NumberEditorModel
{
public string PropertyName { get; set; }
public int Number { get; set; }
}
}
Partial view
Create a partial view _NumberEditor.cshtml in the ~/Views/Shared/InlineEditors folder:
@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc
@model LearningKit.Models.InlineEditors.NumberEditor.NumberEditorModel
@using (Html.Kentico().BeginInlineEditor("number-editor", Model.PropertyName))
{
<div style="position: absolute; top: 0px; right: 0px;">
<button id="plus-btn" type="button">+</button>
<button id="minus-btn" type="button">-</button>
</div>
}
JavaScript
Create a JavaScript file number-editor.js in the ~/Content/InlineEditors/NumberEditor folder:
(function () {
// Registers the 'number-editor' inline property editor within the page builder scripts
window.kentico.pageBuilder.registerInlineEditor("number-editor", {
init: function (options) {
var editor = options.editor;
// Click action for the 'Plus' button
editor.querySelector("#plus-btn").addEventListener("click", function () {
// Creates a custom event that notifies the widget about a change in the value of a property
var event = new CustomEvent("updateProperty", {
detail: {
value: options.propertyValue + 1,
name: options.propertyName
}
});
editor.dispatchEvent(event);
});
// Click action for the 'Minus' button
editor.querySelector("#minus-btn").addEventListener("click", function () {
var event = new CustomEvent("updateProperty", {
detail: {
value: options.propertyValue - 1,
name: options.propertyName
}
});
editor.dispatchEvent(event);
});
}
});
})();
The location of the script file under ~/Content/InlineEditors ensures that the script is automatically linked in the administration interface on pages containing editable areas (within a bundle of inline editor scripts).
Note: The following example is based on the LearningKit project. To use the code samples in your project, you need to modify the namespaces, identifiers and other occurrences where LearningKit is mentioned to match your project’s name.
Widget
Create a widget with one modifiable integer property.
Property model
Create a property model NumberWidgetProperties.cs in the ~/Component/Widgets/NumberWidget folder:
using Kentico.Forms.Web.Mvc;
using Kentico.PageBuilder.Web.Mvc;
namespace LearningKitCore.Components.PageBuilder.Widgets.NumberWidget
{
public class NumberWidgetProperties : IWidgetProperties
{
// Defines a property and sets its default value
// Assigns the default Xperience text input component, which allows users to enter
// a numeric value for the property in the widget's configuration dialog
[EditingComponent(IntInputComponent.IDENTIFIER, Order = 0, Label = "Number")]
public int Number { get; set; } = 22;
}
}
Partial view
Create a partial view _NumberWidget.cshtml in the ~/Components/Widgets/NumberWidget folder:
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using Kentico.PageBuilder.Web.Mvc
@using LearningKitCore.Components.PageBuilder.InlineEditors.NumberEditor
@using LearningKitCore.Components.PageBuilder.Widgets.NumberWidget
@inject IPageBuilderDataContextRetriever pageBuilderContext
@model ComponentViewModel<NumberWidgetProperties>
<h3 style="background-color: #dddddd;">The number you chose for today is: @Model.Properties.Number</h3>
@* Shows an inline editor when rendered in the edit mode of the Pages application in Xperience *@
@if (pageBuilderContext.Retrieve().EditMode)
{
var inlineEditorModel = new NumberEditorModel
{
@* Use the nameof() operator to get the name of the edited property from the widget property model *@
PropertyName = nameof(NumberWidgetProperties.Number),
Number = @Model.Properties.Number
};
<partial name="~/Components/PageBuilder/InlineEditors/NumberEditor/_NumberEditor.cshtml" model="inlineEditorModel" />
}
Widget registration
Register the widget into the system using the RegisterWidget assembly attribute.
[assembly: RegisterWidget("LearningKit.Widgets.NumberWidget",
"Number selector",
typeof(NumberWidgetProperties),
customViewName: "~/Components/PageBuilder/Widgets/NumberWidget/_NumberWidget.cshtml")]
Inline editor
Implement an inline editor able to modify the Number integer property.
Model
Create an editor model NumberEditorModel.cs in the ~/Components/InlineEditors/NumberEditor folder:
namespace LearningKitCore.Components.PageBuilder.InlineEditors.NumberEditor
{
public class NumberEditorModel
{
public string PropertyName { get; set; }
public int Number { get; set; }
}
}
Partial view
Create a partial view _NumberEditor.cshtml in the ~/Components/InlineEditors/NumberEditor folder:
@using Kentico.PageBuilder.Web.Mvc
@using Kentico.Web.Mvc
@model LearningKitCore.Components.PageBuilder.InlineEditors.NumberEditor.NumberEditorModel
@using (Html.Kentico().BeginInlineEditor("number-editor", Model.PropertyName))
{
<div style="position: absolute; top: 0px; right: 0px;">
<button id="plus-btn" type="button">+</button>
<button id="minus-btn" type="button">-</button>
</div>
}
JavaScript
Create a JavaScript file number-editor.js in the ~/wwwroot/PageBuilder/Admin/InlineEditors/NumberEditor folder (this example assumes the default configuration of the system’s bundling support, see Bundling static assets of builder components):
(function () {
// Registers the 'number-editor' inline property editor within the page builder scripts
window.kentico.pageBuilder.registerInlineEditor("number-editor", {
init: function (options) {
var editor = options.editor;
// Click action for the 'Plus' button
editor.querySelector("#plus-btn").addEventListener("click", function () {
// Creates a custom event that notifies the widget about a change in the value of a property
var event = new CustomEvent("updateProperty", {
detail: {
value: options.propertyValue + 1,
name: options.propertyName
}
});
editor.dispatchEvent(event);
});
// Click action for the 'Minus' button
editor.querySelector("#minus-btn").addEventListener("click", function () {
var event = new CustomEvent("updateProperty", {
detail: {
value: options.propertyValue - 1,
name: options.propertyName
}
});
editor.dispatchEvent(event);
});
}
});
})();
Dancing Goat sample site
If you implement this example on the Dancing Goat sample site, you need to manually trigger the bundling process to include component scripts in the administration interface. You need to do the following:
- Run the
pageBuilder
Grunt task available in the sample site to manually trigger the bundling process. - Clear cached web content in your browser.
The location of the script file under ~/wwwroot/PageBuilder/Admin/InlineEditors/NumberEditor ensures that the script is automatically linked in the administration interface on pages containing editable areas (within a bundle of inline editor scripts).