56

I start with this:

<script src="/Scripts/jquery-1.6.2.min.js" ...
<script src="/Scripts/knockout-1.2.1.debug.js" ...
<script src="/Scripts/knockout.mapping-latest.js" ...
<script src="/Scripts/jquery.unobtrusive-knockout.min.js" ...

Then I pull a flat JSON object from the server and bind each property found to matching elements in the DOM:

$.ajax({
    url: '/GetRecord',
    type: 'POST',
    dataType: 'json',
    data: JSON.stringify(requestObject),
    contentType: 'application/json; charset=utf-8',
    success: function (data) {
        // Clear the current view model
        VM.Items.length = 0;

        // only one item coming from server
        VM.Items[0] = ko.mapping.fromJS(data.BlankItem);

        // for each property found, bind it to the matching DOM element
        $.each(VM.Items[0], function (indexInArray, valueOfElement) {
            var attrName = indexInArray;

            // skip over things not an accessor (get/set property function)
            if( typeof valueOfElement == "function")
            {
                var attrValue = valueOfElement();

                // if it's a checkbox, bind the checked attribute
                var a = $('input[name="' + attrName + '"][type="checkbox"]');
                if (a.length)
                    a.dataBind({ checked: attrName });

                // if it's a radio, bind all the found radio checked attributes
                var b = $('input[name^="' + attrName + '"][type="radio"]');
                if (b.length)
                    b.dataBind({ checked: attrName });

                // if it's a text, bind the text attribute
                var c = $('input[name="' + attrName + '"][type="text"]');
                if (c.length)
                    c.dataBind({ text: attrName });  // <--- Error (use value)
            }
        });

        // Then set knockout loose
        ko.applyBindings( VM.Items[0] );
    }
});

It results in an error:

Uncaught Error: NO_MODIFICATION_ALLOWED_ERR: DOM Exception 7
ko.bindingHandlers.updateknockout-1.2.1.debug.js:1577
invokeBindingHandlerknockout-1.2.1.debug.js:1231
ko.applyBindingsToNode.ko.dependentObservable.
disposeWhenNodeIsRemovedknockout-1.2.1.debug.js:1268
evaluateknockout-1.2.1.debug.js:927
ko.dependentObservableknockout-1.2.1.debug.js:965
ko.applyBindingsToNodeknockout-1.2.1.debug.js:1252
ko.applyBindingsknockout-1.2.1.debug.js:1284
ko.utils.arrayForEachknockout-1.2.1.debug.js:48
ko.applyBindingsknockout-1.2.1.debug.js:1283
$.ajax.successPropertyForm:266
f.extend._Deferred.e.resolveWithjquery-1.6.2.min.js:16
wjquery-1.6.2.min.js:18
f.support.ajax.f.ajaxTransport.send.d

I don't see it binding any items that it shouldn't. Also, there are no declarative knockout bindings in the html. What am I doing wrong?

Jeroen
  • 60,696
  • 40
  • 206
  • 339
Zachary Scott
  • 20,968
  • 35
  • 123
  • 205

3 Answers3

119

OMG. The answer was to use the right binding attribute. Instead of text, it was value for an input!

Zachary Scott
  • 20,968
  • 35
  • 123
  • 205
  • 1
    Heh, it looks like this is pretty common. Helped me out, thanks! – Allen Rice Jun 26 '12 at 07:43
  • I just wanted to add, i saw this error in chrome but in IE 9 no error is thrown. I was using IE9 to test/debug with and noticed everything worked but when you edited the values in the input field it was not updating the underlying data. Of course if bound to the text not the value how could it update correctly. – ethermal Oct 24 '12 at 13:56
  • Just saved me as well thnx ! – TimothyP Dec 18 '12 at 05:18
  • Geez, add me to the list. Thanks. – MojoFilter Apr 12 '13 at 19:37
1

In my case, the problem was that I data-bind to text instead of value.

bad: <input type="text" data-bind="text:id" maxlength="3" style="width:100%;" />

good: <input type="text" data-bind="value:id" maxlength="3" style="width:100%;" />

Patrice Calvé
  • 674
  • 6
  • 12
0

I also saw this error in Chrome when I was accidentally calling ko.applyBindings(viewModel) multiple times.

Homer
  • 7,594
  • 14
  • 69
  • 109