Did this article resolve your question/issue?



How to create custom grid widget designer

« Go Back


TitleHow to create custom grid widget designer
URL Namehow-to-create-custom-layout-designer
Article Number000114716
EnvironmentProduct: Sitefinity
Version: 8.x, 9.x, 10.x, 11.x, 12.x
OS: All supported OS versions
Database: All supported Microsoft SQL Server versions
Question/Problem Description
How to create a custom Designer for MVC Grid widgets?
By default, the grid widgets have editable properties based on: Sitefinity documentation, Add customizable grid widgets to MVC templates .
Those editable properties are the CSS class and the Label of the grid widget.
Can editable options for other HTML elements in the grid widget be added?
Is it possible to also add WCAG 2.0 Compliance attributes such as aria-labelledby?
Steps to Reproduce
Clarifying Information
Error Message
Defect Number
Enhancement Number
This sample will show how to add title HTML attribute to one of the <div> elements of Grid widget.
The approach to customizing the grid widget designer consists of modifying the View of the designer and page-editor-services.js . When modifying the designer for grid widgets all grid widgets will use the same modified designer as it is a single designer for shared for all grid widgets.

Refer to the attached files to the KB article. The sample consists of a custom grid widget that has the title html attribute added to the <div> elements. The value of the title element will be editable via the custom designer.
1. mycustomgrid.html is the grid widget that will be used for a sample it has the below markup where "title" attribute is added to each element that have the sf_colsIn and row css classes and are processed by Sitefinity. 
<div class="row myCustomCss" data-sf-element="Row" data-placeholder-label="Row" title="">
    <div class="myCustomCss" title=""></div>
    <div class="sf_colsIn sidebar" data-sf-element="Column 1" data-placeholder-label="LeftColum" title="">
    <div class="sf_colsIn results_wrapper right" data-sf-element="Column 2" data-placeholder-label="RightColum" title="">

2. In Designer.cshtml additional textbox to enter a title that will be added to the markup of the designer
<input id="prop-{{item.title}}" type="text" class="form-control" ng-model="item.title" />
The designer for the grid widgets Designer.cshtml. Since Sitefinity MVC implementation is open source the markup is located here:

3.  The other file is page-editor-services.js. Since Sitefinity MVC implementation is open source the code is located

In the fuction gridElement a new a property is added to pass the Title from the Designer.cshtml
var gridElement = function (id, name, css, label, isPlaceholder, title) {
            //the location where we try to persist the Title
   = id;
   = name;
            this.css = css;
            this.label = label;
            this.isPlaceholder = isPlaceholder;
            this.title = title;

After this in  var getInnerElements = function (layoutRoot) the title is also passed on.
var getInnerElements = function (layoutRoot) {
            var gridElements = [];
            var elements = $(layoutRoot).find('[data-sf-element]');
            //Sort out the inner columns
            for (var i = 0; i < elements.length; i++) {
                var element = elements[i];
                var id = $(element).attr('id');
                var classValue = $(element).attr('class');
                var displayClass = classValue.replace('sf_colsIn', '').trim();
                var columnName = $(element).attr('data-sf-element');
                var label = $(element).attr('data-placeholder-label');
                var isPlaceholder = $(element).hasClass('sf_colsIn');
                var title = $(element).attr('title');
 gridElements.push(new gridElement(id, columnName, displayClass, label, isPlaceholder, title));
After this in var constructLayoutHtml = function (elements) this section is added
var title = elements[i].title;
                    if (title) {
                        $(innerDiv).attr('title', title);
                    else {

The next step is to extend refreshContainer fucntion as shown below.

var refreshContainer = function (elements) {
            for (var i = 0; i < elements.length; i++) {
                var innerDiv = elements[i].id ? $(gridContext.layoutContainer).find('#' + elements[i].id) : $(gridContext.layoutContainer).find('[data-sf-element=' + elements[i].name + ']');

                if (innerDiv) {
                    var css = elements[i].isPlaceholder ? 'sf_colsIn ' + elements[i].css : elements[i].css;
                    $(innerDiv).attr('class', css.trim());
                    var title = elements[i].title;// ? 'sf_colsIn ' + elements[i].css : elements[i].css;
                    $(innerDiv).attr('title', title.trim());

                    var label = elements[i].label;
                    var labelElement = $(innerDiv).find('.zeDockZoneLabel b');

To apply the customization there are two approaches depending on the page framework (for more info on the page framework refer to Sitefinity documentation, MVC modes
  • For MVC only pages:
    • Place the grid widget (\GridSystem\Templates\mycustomgrid.html) in folder \ResourcePackages\Bootstrap\GridSystem\Templates\mycustomgrid.html
    • Place the Designers and its contents folder under the root of the sitefinity project
    • Place folder Mvc\Views\GridDesigner\Designer.cshtml under \ResourcePackages\Bootstrap folder
  • For Hybrid pages
    • Place the grid widget (\GridSystem\Templates\mycustomgrid.html) in the root of the sitefinity project
    • Place the Designers and its contents folder in the root of the sitefinity project
    • Place folder Mvc\Views\GridDesigner\Designer.cshtml in the root of the sitefinity project
Note that using the above approach any attribute can be added, for example, aria-labelledby (WCAG 2.0 Compliance).
Last Modified Date3/24/2020 2:30 PM
Disclaimer The origins of the information on this site may be internal or external to Progress Software Corporation (“Progress”). Progress Software Corporation makes all reasonable efforts to verify this information. However, the information provided is for your information only. Progress Software Corporation makes no explicit or implied claims to the validity of this information.

Any sample code provided on this site is not supported under any Progress support program or service. The sample code is provided on an "AS IS" basis. Progress makes no warranties, express or implied, and disclaims all implied warranties including, without limitation, the implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample code is borne by the user. In no event shall Progress, its employees, or anyone else involved in the creation, production, or delivery of the code be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample code, even if Progress has been advised of the possibility of such damages.