Little by little I'm learning this...
In my C#/MVC4 demo build I've created a controller to send data to my view through JSON. In my view I am able to parse the response and populate a drop down list.
I'm using knockout similar to a cart to create additional lines (colors) for posting to the controller.
code:
MVC ViewModel:
function Color(data) {
this.ID = ko.observable(data.ID);
this.ColorName = ko.observable(data.ColorName);
this.Duration = ko.observable(data.Duration);
this.bNotPermanent = ko.observable(1);
}
function ViewModel() {
self = this;
self.CurrentColors = ko.observableArray([]);
self.AddColors = ko.observableArray([]);
self.AllColors = ko.observableArray([]);
$.ajax({
type: "POST",
url: '@Url.Action("GetUsersColors", "EditUser")',
data: { szUserRecID: RecID },
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
self.CurrentColors(colors);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
})
$.ajax({
type: "POST",
url: '@Url.Action("GetVisibleColors", "EditColor")',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: {},
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
self.AllColors(colors);
},
error: function (err) {
alert(err.status + " - " + err.statusText);
}
})
self.removeLine = function (color) { self.AddColors.remove(color);
};
self.addColor = function (color) {
self.AddColors.push(new Color({ ColorName: "", ID: "", Duration: "Permanent" }))
};
self.save = function ()
{
// I've also tried data: ko.mapping.toJSON(this)
// based on my issues I've seen, I'm almost positive this is where my issue is
// I think the mapping is having an issue but I don't know what it should look like
// with an array of objects
$.ajax({
url: '@Url.Action("PostColors", "EditColor")',
type: "POST",
data: ko.mapping.toJSON(this.AddColors()),
async: true,
contentType: "application/json"
}).success(function (data) {
});
};
this does work...
View
<table>
<thead>
<tr data-bind =" visible: $root.AddColors().length > 0">
<th padding: 10px; >Color</th>
<!--<th padding: 10px; >Duration</th>-->
</tr>
</thead>
<tbody data-bind="foreach: AddColors">
<tr>
<!-- This works, it displays all the colors provided by the controller -->
<td><select data-bind="options: $root.AllColors, optionsText: 'ColorName', value: ID, optionsCaption: 'Select Color...'"></select></td>
<td>
<a href='#' data-bind='click: $parent.removeLine'>Remove</a>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: addColor'>Add Color</button>
<button data-bind='click: save'>Submit Colors</button>
controller:
[HttpPost]
public void PostColors(List<ViewModels.ColorList> AddColors)
{
int t = 0; // to set a break point only
}
C# ViewModel
public class ColorList
{
public int? ID { get; set; }
public string ColorName { get; set; }
public string Duration{ get; set; }
public bool bNotPermanent { get; set; }
}
when I inspect AddColors in the above function, the Duration is set but the ColorName is null but I do have the correct number of elements coming through.
I can add lines(colors) over and over on the form and selecting them on the list. But why are they not showing in "AddColors" object list?
I did find another article on here referring to get; set; in the viewmodel and I did add that. Up until that point everything coming through was null.
Fiddler is showing this (and it doesn't look quite right...?)
[{"ID": {"ID":11,"ColorName":"Green","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1},{"ID": {"ID":17,"ColorName":"Red","Duration":null,"bNotPermanent":1},"ColorName":"","Duration":"Permanent","bNotPermanent":1}]
I really think my issue is with the data conversion / ajax post. Question is, what should it look like?