Question

I had run into deep troubles with knockout when running on IE9 with IE8 compatibility mode. Here's the issue:

I have an array of dynamically generated textboxes, and a change event is bound to these elements. When the change event is there, in IE8 compatibility mode, I need to press tab twice to move away from the control. This doesn't happen in Firefox, nor when there's no event bound.

I'm not sure whether it's an issue with my event so I'm posting the code here:

  <tbody data-bind="foreach: DailyItemList">
                            <tr>
                                <td>
                                 <span  data-bind="text:Day"></span>

                                </td>
                                <td><input id="Text2" data-bind="value: Required"/></td>
                                <td><input id="Text3" data-bind="value: Setup, event:{change: ValidateSetup}"/></td>
                                <td><input id="Text4" data-bind="value: Close, event:{change: ValidateClose}"/></td>
  </tr>
  </tbody>

Here's the view model with the change functions:

var DailyItem = function (data) {
this.Day = ko.observable(data.DayOfWeek);
this.Required = ko.observable(data.Required);
this.Setup = ko.observable(data.SetupTime);
this.Close = ko.observable(data.CloseTime);
this.ValidateSetup = function () {
    if (this.Setup() > 30) {
        alert('Invalid SetupTime');
    }
}
this.ValidateClose = function () {
    if (this.Close() > 30) {
         alert('Invalid SetupTime');
    }
}
}

function ViewModel(items) {
   this.DailyItemList = ko.observableArray([]);
   records = $.map(items, function (data) { return new DailyItem(data) });
   this.DailyItemList(records);
}
Was it helpful?

Solution

If you want to work around the IE8 compatibility, then you can return true from your Validate functions.

this.ValidateSetup = function () {
    if (this.Setup() > 30) {
        alert('Invalid SetupTime');
    }

    return true;
}

Here is a sample: http://jsfiddle.net/rniemeyer/FfNqv/ (jsFiddle has some issues itself in IE8 mode, so you can run http://jsfiddle.net/rniemeyer/FfNqv/show/)

A better approach though would likely be to use a manual subscription. This is a good option for executing code whenever a single observable changes. The same could be done in a computed as well, which allows you to depend on multiple observables.

With a manual subscription you would do:

<input id="Text3" data-bind="value: Setup"/>

In your view model, you would something like:

this.Close = ko.observable(data.CloseTime);
this.Close.subscribe(function(newValue) {
    if (newValue > 30) {
        alert('Invalid SetupTime');
    }

    //set other observables, or do whatever you like. "this" will be the this object.

}, this);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top