Friday, January 10, 2014

Extending an MVVM KendoUI widget to support custom event bindings

In my previous post, I put together a simple Kendo widget that is MVVM compatible within the KendoUI framework. In this post, I will add custom event bindings to the widget to allow the MVVM bindings to establish event bindings to dependent methods within your viewmodel. This will allow the widget to trigger custom events when the user clicks on the icon in our custom text box. Starting with the previous widget, we now need some DOM elements for the user to interact with. I had found a posting that explained a way to make simple KendoUI widget that was not MVVM aware that added a magnifying glass icon to a standard textbox. This seemed good for this example. It uses and existing Kendo style for the magnifying glass.

        _create: function () {
            // cache a reference to this
            var that = this;

            // setup the icon
            var template = kendo.template(that._templates.icon);
            that.icon = $(template(that.options));

            // setup the textbox
            template = kendo.template(that._templates.textbox);
            that.textbox = $(template(that.options));
            
            // append all elements to the DOM
            that.element.attr("name", that.options.name);
            that.element.addClass("k-input");
            that.element.css("width", "100%");
            that.element.wrap(that.textbox);
            
            that.element.after(that.icon);
        },
        //HTML for the templates that comprise the widget
        _templates: {
            textbox: "<span style='width: #: width #px;' class='k-widget k-datepicker k-header tb'><span class='k-picker-wrap k-state-default'></span></span>",
            icon: "<span unselectable='on' class='k-select' role='button'><span unselectable='on' class='k-icon #: iconclass #'>select</span></span>"        },
The _create method adds additional dom elements as well as some kendo styles to create the effect. Width is used from the options collection and the icon class also comes from options, so we can override it if we choose to. Now that we have something to click on ,we need to add a line to _create to wire up a click event on the icon.
  that.icon.on("click", $.proxy(that._buttonclick, that));
A simple jquery click event is added via a proxy. From the previous example, we use a proxy to ensure that the scope of the event fired contains the widget when fired. We pass the widget in as scope for the proxy. The handler is tied to a new internal function in our widget, _buttonclick.
        _buttonclick: function (element) {
            var that = this;
            that.trigger("buttonclick", { element: element });
            return that;
        },
The handler for the widgets icon click event fires the custom event BUTTONCLICK to alert any listeners that the event has occured. The widget will be the scope and the element will be the icon DOM element. Now we have to declare the event in our events collection so the MVVM framework knows that the binding is available.
events: ["change", "buttonclick"],
By exporting the event via the events collection, the MVVM framework is aware that our widget can fire an event called 'buttonclick'. We can consume the event in MVVM bindings with the same binding syntax as other kendo widgets.
<input data-role="buttontextbox" data-bind="value: simpleValue, events: { buttonclick: onSomeButtonClick }" />

The buttonclick event binding will call into the dependent method specified as onSomeButtonClick. Our widget can now export custom events from events that are internal to the widget itself.
A functional fiddle with all the code is at:

http://jsfiddle.net/cn172/s7RF3/

No comments:

Post a Comment