0

I have a JSON object that I used to create a form. This JSON object is parsed by KnockoutJS.

Now, when I modify the form, I want the JSON object to be updated according to the modifications made in the form. The thing is that I don't know in advance how the form will be like but I know in the JSON Object which fields need to be updated.

I really don't know what is the best way to procede. I know that I could reconstruct the JSON Object each time something has changed but this seems like a bad idea and a tedious process.

Is there a simple way to map each JSON Object field to form items in KnockoutJS ?

Here's a JSFiddle of what I'm currently doing:http://goo.gl/ZBaV7

Update :

I realized something interesting with this line:

<input type="text" data-bind="value: $data.value, attr : { disabled: $data.disabled }" />

I'm accessing the value directly from the array via ($data.value). Is there a way in the html to say to knockout to bind to this particular attribute in the array. I know that if the array would get reordered everything would get messed up but since I know that the only thing that can changed is this property I'm ready to take this risk ?

In other words, is there a way to manually say that when this value changes to change it in the array such as

data-bind="onChange: $data.value = this.value"
j08691
  • 204,283
  • 31
  • 260
  • 272
Etienne Noël
  • 5,988
  • 6
  • 48
  • 75
  • Having a JSFiddle is always good plus but it should not be your only source of code. You don't have anyway too much code in your fiddle so please update your post with the code. (Then you don't have turn a line of text to code, just to enter the fiddle link) – nemesv Jun 20 '13 at 18:16
  • yeah, the thing is the code is not really relevant it just helps seeing what I'm trying to say. I shortened the url instead. – Etienne Noël Jun 20 '13 at 18:17
  • possible duplicate of [bind JSON properties to a form](http://stackoverflow.com/questions/7347580/bind-json-properties-to-a-form) – davidbuzatto Jun 20 '13 at 18:40
  • @davidbuzatto Not really, since I don't want to rebuild my JSON object but I just want knockout to update it. The question you provided does not use knockoutJs. – Etienne Noël Jun 20 '13 at 18:42
  • 1
    [There is no such thing as a "JSON object"](http://benalman.com/news/2010/03/theres-no-such-thing-as-a-json/). – Felix Kling Jun 20 '13 at 18:49
  • @FelixKling I think you get what I mean ;) – Etienne Noël Jun 20 '13 at 18:51

3 Answers3

1

If your Knockout ViewModel matches your form, you could just use the built in ks.toJSON()

http://knockoutjs.com/documentation/json-data.html

A better option, especially if your form is large or complex, is to use either the mapping or viewmodel plug-ins

http://knockoutjs.com/documentation/plugins-mapping.html http://coderenaissance.github.io/knockout.viewmodel/

ShaneBlake
  • 11,056
  • 2
  • 26
  • 43
1

Is there a simple way to map each JSON Object field to form items in KnockoutJS ?

Yes, If I understand what you want to do correctly. As of now, the values in your view model are not observables and won't be updated automatically as the form values change. There is a plugin to handle this mapping.

http://knockoutjs.com/documentation/plugins-mapping.html

Example: Using ko.mapping

To create a view model via the mapping plugin, replace the creation of viewModel in the code above with the ko.mapping.fromJS function:

var viewModel = ko.mapping.fromJS(data);

This automatically creates observable properties for each of the properties on data. Then, every time you receive new data from the server, you can update all the properties on viewModel in one step by calling the ko.mapping.fromJS function again:

ko.mapping.fromJS(data, viewModel);

Hopefully this helps.

bfuoco
  • 715
  • 4
  • 12
  • It says here: "every time you receive new data from the server, you can update all the properties on viewModel". Is it possible that when I modify the form, the value in the array gets updated ? More like the opposite of what it says such to update when client side gets modified ? – Etienne Noël Jun 20 '13 at 19:09
  • 1
    When you use the value binding, if you bind to an observable property, the observable property's value will be updated in the view model when the form value changes. The problem you have right now is that you're not using observables. Using the mapping plugin to create the initial view model will wrap all of the properties as ko.observable/ko.observableArray, so the values in the view model should be updated as the form values change. – bfuoco Jun 20 '13 at 19:16
  • "Whenever the user edits the value in the associated form control, KO will update the property on your view model." http://knockoutjs.com/documentation/value-binding.html – bfuoco Jun 20 '13 at 19:17
  • I transform my code using bindings, however I'm not getting the wished html representation http://jsfiddle.net/etiennenoel/wG9SZ/3/ – Etienne Noël Jun 20 '13 at 19:52
  • You need to assign the result of ko.mapping to a view model and then apply the bindings. – bfuoco Jun 20 '13 at 20:24
  • Here's an updated fiddle: http://jsfiddle.net/wG9SZ/16/ A couple other things. If you use a function as a binding, such `if formType() == TextBox`, you must use call the observable as a function. Also, Knockout doesn't like undefined properties, so I added appendLabel: false to where it was needed. – bfuoco Jun 20 '13 at 20:32
0

The simplest way to turn your json model into a usable knockout model is with the mapping plugin.

Alternatively, you can manually copy fields from your json model into ko.observable members of your view model, which give you more control and lets you choose to skip read-only properties.

Matt Burland
  • 44,552
  • 18
  • 99
  • 171