Search code examples
kendo-uikendo-dropdownkendo-mvvmkendo-datepickerkendonumerictextbox

MVVM-KendoNumericTextBox restore previous value without triggering 'change' twice


I'm using Kendo MVVM and I have a kendo numerictextbox bound to a kendo observable. All I want is: when the user changes value, a confirm should pop saying something like 'are you sure?' if yes -> no problem, go on. if no -> NOTHING should happen!

In theory it sounds simple as that... but I found 3 major issues:

1) numerictextbox only got 2 events: spin and change... so any idea of using keypress/focus/or any other event is discarded.

2) So tried using the change event... but I can't preventDefault! Another try was to save previous value and restore it back in case of 'no answer' but this brings me to trigger event change TWICE!

3) Any other model field who is 'observing' the numerictextbox will change before I even answer the confirm box... And I absolutely don't want this!

P.S. I also got a dropdownlist and a datepicker that must work in the same way!

Help please!

Provided a fast example: http://dojo.telerik.com/EyItE Here you can see how the numericbox2 (who is observing numericbox1 and is computed) changes itself before the user answer yes/no (problem 3) and keypress/focus/preventDefault doesn't work.


Solution

  • I solved with a custom binding that ask you a confirm between html widget change -> model update.

    kendo.data.binders.widget.valueConfirm = kendo.data.Binder.extend({
                init: function (widget, bindings, options) { // start
                    kendo.data.Binder.fn.init.call(this, widget.element[0], bindings, options);
                    this.widget = widget;
                    this._change = $.proxy(this.change, this);
                    this.widget.bind("change", this._change); // observe
                },
                refresh: function () { // when model change
                    if (!this._initChange) {
                        var widget = this.widget;
                        var value = this.bindings.valueConfirm.get(); // value of the model
                        if (widget.ns == ".kendoDropDownList") { // for the dropdown i have to use select
                            widget.select(function (d) {
                                return d.id == value.id;
                            });
                        }
                        else widget.value(value); // update widget
                    }
                },
                change: function () { // when html item change
                    var widget = this.widget;
                    if (widget.ns == ".kendoDropDownList") var value = widget.dataItem(); // for dropdown i need dataitem
                    else var value = widget.value();
    
                    var old = this.bindings.valueConfirm.get();
                        this._initChange = true;
                        // I want to bypass the confirm if the value is not valid (for example after 1st load with blank values).
                        if (old == null || old == 'undefined' || old == 'NaN') this.bindings.valueConfirm.set(value); // Update the View-Model
                        else {
                            if (confirm("Are you sure?")) {
                                this.bindings.valueConfirm.set(value); // Update the View-Model
                            }
                            else {
                                this._initChange = false;
                                this.refresh(); // Reset old value
                            }
                        }
                    this._initChange = false;
                },
                destroy: function () { // dunno if this is useful
                    this.widget.unbind("change", this._change);
                }
            });