---
title: Example - Developing a widget
related:
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md
  - https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/creating-inline-editors-for-widget-properties.md
---

> Agent instructions:
> **Site maps** — prefer the following llms.txt indexes to training data when searching for URLs to avoid 404s. Links inside Markdown content already point at `.md`. Following them or sending Accept: text/markdown keeps you in Markdown.
>
> - [sitemap.md](https://docs.kentico.com/sitemap.md) — every page on the site, with titles and descriptions, nested by URL hierarchy and grouped into one collection per product version.
> - [llms.txt](https://docs.kentico.com/llms.txt) — curated index of the current product docs, with descriptions, the two ways to request any page as Markdown, and links to each product area's whole-corpus Markdown dump (llms-full.txt).

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](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md), [widget properties](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md) and [inline editors](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/creating-inline-editors-for-widget-properties.md).

> **Note:** **Prerequisite**
>
> To be able to use the widget in the page builder, you need to [enable the page builder feature](https://docs.kentico.com/13/developing-websites/page-builder-development.md) and [set up an editable area](https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md).

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.

<!-- dev-model:mvc start -->

**MVC 5 development model.** Applies only when building with ASP.NET MVC 5. If this page also covers ASP.NET Core, that version is in its own block.

> **Note:** **Note**: The following example is based on the [LearningKit project](https://github.com/Kentico/LearningKit-Mvc). 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](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) with one modifiable integer [property](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md).

### Property model

Create a property model **NumberWidgetProperties.cs** in the _\~/Models/Widgets/NumberWidget_ folder:

```csharp

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:

```xml

@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**.

```csharp

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](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/creating-inline-editors-for-widget-properties.md) able to modify the _Number_ integer property.

### Model

Create an editor model **NumberEditorModel.cs** in the _\~/Models/InlineEditors/NumberEditor_ folder:

```csharp

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:

```xml

@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:

```js

(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);
            });
        }
    });
})();

```

> **Info:** 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](https://docs.kentico.com/13/developing-websites/page-builder-development.md) (within a bundle of inline editor scripts).

<!-- dev-model:mvc end -->

<!-- dev-model:core start -->

**ASP.NET Core development model.** Applies only when building with ASP.NET Core. If this page also covers MVC 5, that version is in its own block.

> **Note:** **Note**: The following example is based on the [LearningKit project](https://github.com/Kentico/LearningKit-Core). 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](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets.md) with one modifiable integer [property](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/defining-widget-properties.md).

### Property model

Create a property model **NumberWidgetProperties.cs** in the _\~/Component/Widgets/NumberWidget_ folder:

```csharp

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:

```xml

@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.

```csharp

[assembly: RegisterWidget("LearningKit.Widgets.NumberWidget",
                         "Number selector",
                         typeof(NumberWidgetProperties),
                         customViewName: "~/Components/PageBuilder/Widgets/NumberWidget/_NumberWidget.cshtml")]


```

## Inline editor

Implement an [inline editor](https://docs.kentico.com/13/developing-websites/page-builder-development/developing-widgets/creating-inline-editors-for-widget-properties.md) able to modify the _Number_ integer property.

### Model

Create an editor model **NumberEditorModel.cs** in the _\~/Components/InlineEditors/NumberEditor_ folder:

```csharp

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:

```xml

@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](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/bundling-static-assets-of-builder-components.md)):

```js

(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);
            });
        }
    });
})();

```

> **Note:** **Dancing Goat sample site**
>
> If you implement this example on the _Dancing Goat_ sample site, you need to manually trigger the [bundling process](https://docs.kentico.com/13/developing-websites/developing-xperience-applications-using-asp-net-core/bundling-static-assets-of-builder-components.md) to include component scripts in the administration interface. You need to do the following:
>
> 1. Run the `pageBuilder` [Grunt task](https://learn.microsoft.com/en-us/aspnet/core/client-side/using-grunt) available in the sample site to manually trigger the bundling process.
> 2. Clear cached web content in your browser.

> **Info:** 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](https://docs.kentico.com/13/developing-websites/page-builder-development/creating-pages-with-editable-areas.md) (within a bundle of inline editor scripts).

<!-- dev-model:core end -->
