TruMan1
TruMan1

Reputation: 36078

How to nest custom widgets in Kendo UI?

I would like to create a custom widget that will display several widgets within it. For example, I would like a custom widget to be composed of a listview, a combobox, a calender, and a menu. Is this possible?

What I am thinking is adding the HTML in the refresh method, then initialize DOM elements such as below. I would like to use MVVM as well.

refresh: function() {
    var that = this,
        view = that.dataSource.view(),
        html = kendo.render(that.template, view);

    // trigger the dataBinding event
    that.trigger(DATABINDING);

    // mutate the DOM (AKA build the widget UI)
    that.element.html(html);

    // is this safe???
    kendo.bind(that.element, { source: this.dataSource });

    // or do this???
    this.element.find('.listview').kendoListView({ dataSource: this.dataSource });

    // trigger the dataBound event
    that.trigger(DATABOUND);
}

It feels weird to call a kendo.bind in a widget where it is probably initialized via Kendo MVVM as well. Is there a better way to do this?

Upvotes: 0

Views: 653

Answers (1)

D.T.
D.T.

Reputation: 350

Yes it is possible, you have to create a plugin of yours which will generate the controls, You can refer the ways to create a plugin. create basic jquery plugin

Below code is just a sample to help you start with, it is not a running code. You can modify this and make it run as per your requirement I have created a sample for binding combobox, you can add up other controls in the same manner.

 $.fn.customControl = function (options) {
    var settings = $.extend({}, options);
    return this.each(function () {
        var $this = $(this);

        var comboboxDatasource, listviewDatasource, menuDatasource; // as many controls you want to bind
        $.each(settings.controls, function (index, value) {
            switch (value.type) {
                case "combobox":
                    comboboxDatasource = value.datasource;
                    var $combobox = "<input data-role='combobox' " +
                                               " data-text-field='" + value.textField + "'" +
                                               " data-value-field='" + value.valueField + "'" +
                                               " data-bind='source: '" + value.datasource + "'," +
                                                " events: {" +
                                                " change: onChange," + //pass it in the custom control parameters if you want to have a custom event for the control
                                                " }' />";

                    $this.append($combobox); // Appends a control to the DOM which can be later bound to data using MVVM kendo.observable
                    break;
                case "listview":
                //Create listview and other controls as demo'ed for the combobox.
                    break;
                case "calendar":
                    break;
                case "menu":
                    break;
            }
        });
        //Create the kendo Observable object to bind the controls
        var viewModel = kendo.observable({
            comboboxDatasourceProperty: new kendo.data.DataSource({ //Fetch the datasource for each list control based on the parameters sent
                transport: {
                    read: {
                        url: "url to datasource",
                        dataType: "dataType you want e.g. jsonp"
                    }
                }
            }),
            listviewDatasourceProperty: function () { },
            menuDatasourceProperty: function () { }
        });

        // Bind the View to the div which contains all the other controls
        kendo.bind($($this), viewModel);

    });  // return this.each

};  //customControl

Basic settings to use it is to create a div in the page which will actually contain all the other controls

<div id="customControlDiv"></div>

In the page you can use the control as below to create and bind the controls, if you want to bind it to the refresh function in observable then, write the below code within the refresh function

$("customControlDiv").customControl({    controls: [
    { type:'listview',id:'listviewID',datasource='path to datasource for listview',textField='text',valueField='id' }, //if you want to pass your datasource url, make a prop. and pass the url 
    { type:'combobox',id:'comboboxID',datasource='path to datasource for combobox',textField='id',valueField='id' },   // which can be accessed in the plugin to fetch datasource
    { type:'calendar',:'calenderID',datasource='',textField='',valueField='' },
    { type:'menu',id:'menuID',datasource='path to datasource for menu',textField='text',valueField='id' }
]
});

Hope this helps :)

Upvotes: 2

Related Questions