Widget Basics - Knockout

NOTE: This article assumes that you have successfully linked all the necessary scripts. If not, read the Installation guide first.

From this article, you will learn to perform basic operations on a DevExtreme widget using the Knockout framework. Similar articles are available for the jQuery library and the AngularJS framework.

Create and Configure a Widget

DevExtreme supplies a custom Knockout binding for each widget.

To create, for example, the dxChart widget, add a <div> element to the <body> tag of your page and use the dxChart binding as the following code shows.

HTML
<div data-bind="dxChart: { }"></div>

To configure a widget, add properties to the object passed to the widget binding. Note that these properties mirror the options of the widget.

HTML
<div data-bind="dxChart: {
    dataSource: [
        { fruit: 'Oranges', total: 10 },
        { fruit: 'Apples', total: 15 },
        { fruit: 'Bananas', total: 9 }
    ],
    series: { argumentField: 'fruit', valueField: 'total' }
}"></div>
See Also
  • Reference | WidgetName | Configuration - describes all options of a specific DevExtreme widget.

You can initialize a widget option with the value of a view model property. For example, the following code declares the fruitsData property within a view model. The dataSource option of a dxChart is initialized with the value of this property.

JavaScript
var viewModel = {
    fruitsData: [
        { fruit: 'Oranges', total: 10 },
        { fruit: 'Apples', total: 15 },
        { fruit: 'Bananas', total: 9 }
    ]
};

ko.applyBindings(viewModel);
HTML
<div data-bind="dxChart: {
    dataSource: fruitsData,
    series: { argumentField: 'fruit', valueField: 'total' }
}"></div>

As an alternative, you can declare the whole object of widget options in the view model and pass it to the widget binding.

JavaScript
var viewModel = {
    chartOptions: {
        dataSource: [
            { fruit: 'Oranges', total: 10 },
            { fruit: 'Apples', total: 15 },
            { fruit: 'Bananas', total: 9 }
        ],
        series: { argumentField: 'fruit', valueField: 'total' }
    }
};

ko.applyBindings(viewModel);
HTML
<div data-bind="dxChart: chartOptions"></div>

Change Options

To be able to change a widget option, declare its value an observable.

JavaScript
var viewModel = {
    rangeSelectorOptions: {
        // ...
        selectedRangeColor: ko.observable('yellow'),
        sliderMarker: {
            visible: ko.observable(false)
        }
    }
};

viewModel.changeObservables = function () {
    viewModel.rangeSelectorOptions.selectedRangeColor('blue');
    viewModel.rangeSelectorOptions.sliderMarker.visible(true);
};

ko.applyBindings(viewModel);

Now, if you change an observable in code, the widget will catch up the changes and update the UI.

In exceptional cases, you need things to be working the other way around as well, that is, you need an observable to get updated when a user changes the UI. For example, consider the following configuration of the dxRangeSelector widget.

JavaScript
var viewModel = {
    rangeSelectorOptions: {
        // ...
        selectedRange: {
            startValue: ko.observable(10),
            endValue: ko.observable(20)
        }
    }
};

Here, when a user changes the selected range in the UI, these observables stay intact. But what you need is that observables always be synced with the UI. For this purpose, declare the whole selectedRange object an observable.

JavaScript
var viewModel = {
    rangeSelectorOptions: {
        // ...
        selectedRange: ko.observable({
            startValue: 10,
            endValue: 20
        })
    }
};

Call Methods

To call a method, you need to obtain the widget instance first. You can use jQuery to do this.

JavaScript
var chartInstance = $("#chartContainer").dxChart("instance");

As an alternative, you can save the widget instance in a view model property once the widget is initialized.

JavaScript
var viewModel = {
    chartInstance: {},
    chartOptions: {
        // ...
        onInitialized: function (e) {
            viewModel.chartInstance = e.component;    
        }
    }
};

ko.applyBindings(viewModel);

After that, you can call any method of the saved instance.

JavaScript
var series = viewModel.chartInstance.getAllSeries();
See Also
  • Reference | WidgetName | Methods - describes all methods of a specific DevExtreme widget.

Handle Events

Subscribe to an Event

You can subscribe to an event using a configuration option. All event handling options are given names that begin with on.

JavaScript
var viewModel = {
    chartOptions: {
        // ...
        onLegendClick: function (info) {
            // Handles the "legendClick" event
        },
        onArgumentAxisClick: function (info) {
            // Handles the "argumentAxisClick" event
        }
    }
};

ko.applyBindings(viewModel);

As a more flexible solution, you can use the on() method. It allows you to subscribe to events at runtime and even to attach several handlers to a single event.

JavaScript
// Subscribes to the "legendClick" and "argumentAxisClick" events
chartInstance
    .on({
        "legendClick": handler1,
        "argumentAxisClick": handler2
    });
JavaScript
// Attaches several handlers to the "legendClick" event
chartInstance
    .on("legendClick", handler1)
    .on("legendClick", handler2);

NOTE: In case you need information about calling methods, see the Call Methods topic.

Unsubscribe from an Event

To detach all the handlers that you attached with the on() method, call the off() method without arguments.

JavaScript
chartInstance.off();

You can also call this method to detach a specific handler from an event or all handlers from a particular event.

JavaScript
// Detaches the "handler1" from the "legendClick" event leaving other handlers (if any) intact
chartInstance
    .off("legendClick", handler1)

// Detaches all handlers from the "legendClick" event
chartInstance
    .off("legendClick")

If you subscribed to an event using an on... option, you can unsubscribe from it by setting this option to undefined.

JavaScript
chartInstance.option("onLegendClick", undefined);
See Also
  • Reference | WidgetName | Events - describes all events of a specific DevExtreme widget.

Destroy a Widget

To destroy a DevExtreme widget, remove the DOM node associated with this widget.

JavaScript
$("#chartContainer").remove();