I am new to knockout.JS. I am binding a JSON collection to a table.
<tbody data-bind="foreach: Collection">
<tr>
<td>
<span data-bind="text: FirstName" ></span>
</td>
<td>
<span data-bind="text: LastName" ></span>
</td>
<td>
<input type="button" data-bind="click: function(){ obj.RemoveItem($data) }" value="Del" />
</td>
<td>
<input type="button" data-bind="click: function(){ obj.SaveItems($data.Id) }" value="Edit/Save" />
</td>
</tr>
</tbody>
function viewModel(collection) {
var self = this;
this.Collection = ko.observableArray(collection);
this.AddItem = function() {
this.Collection.push({FirstName:"", LastName:""});
};
this.RemoveItem = function(data) {
this.Collection.remove(data);
};
this.SaveItems = function(id) {
alert("New Collection: " + ko.utils.stringifyJson(self.Collection));
}
};
var obj = new viewModel([
{ Id: 1,FirstName: "John", LastName: "Saleth" },
{ Id: 2, FirstName: "John", LastName: "Kennedy" }
]);
ko.applyBindings(obj);
In eachrow, I kept a edit button which on click, inserts a textbox in all TD's with value of
span. And on save click, i am updating the values of span elements with the values of textbox.
The problem is new values of span element is not reflecting in JSON collection. How to update the JSON source with updated span values on click of save button?
You should make each property of the Collection array observable as well.
function ItemModel(item) {
this.Id = ko.observable(item.Id);
this.FirstName = ko.observable(item.FirstName);
this.LastName = ko.observable(item.LastName);
};
function viewModel(collection) {
var self = this;
this.Collection = ko.observableArray();
ko.utils.arrayForEach(collection, function (i) { self.Collection.push(new ItemModel(i)); });
this.AddItem = function() {
this.Collection.push(new ItemModel({
FirstName: "",
LastName: ""
}));
};
...
};
Related
I have a table (list) on my front end in html, and foreach row, I have a button:
...
<td>
<button data-bind="click: sendDataToApi">Test button</button>
</td>
...
and in the .js file I have something like this:
define(['viewmodels/shell', 'durandal/services/logger', 'plugins/dialog', 'viewmodels/shell', 'toastr', 'knockout', 'kovalidationconfig', 'plugins/router', 'typeahead.bundle'],
function (shell, logger, dialog, shell, toastr, ko, kvc, router, typeahead) {
var vm = {
activate: activate,
shell: shell,
data: ko.observableArray([]),
close: function () {
$(window).off('popstate', vm.goBack);
$(window).off('resize', adjustModalPosition);
dialog.close(vm, 'cancel');
},
goBack: function () {
$(window).off('popstate', vm.goBack);
$(window).off('resize', adjustModalPosition);
dialog.close(vm, 'back');
},
editPreregisteredChildren: function () {
router.navigate("#/function/" + this.id);
},
currentPage: ko.observable(1),
itemsPerPage: ko.observable(10),
hasNextPage: ko.observable(false),
previousPage: previousPage,
nextPage: nextPage,
sendDataToApi: function () {console.log("sdsdsds")},
searchCriteria: ko.observable(''),
applySearch: applySearch,
locations: ko.observableArray([]),
locationId: ko.observable(),
LocationName: ko.observable(),
exportHref: ko.observable("/spa/ExportSchedulings"),
bindingComplete: function (view) {
bindFindLocationEvent(view);
}
};
function sendDataToApi() {
console.log("hello.")
};
});
so, firstly, I want to get console.log("something") to work.
for now Im getting error in my console in chrome:
Uncaught ReferenceError: Unable to process binding "click: function(){return sendDataToApi }"
Message: sendDataToApi is not defined
I dont get it why?
after that I need to do an ajax call to my controller, and the end to call some api in that controller, and return the information if the api call was successfull or not.
I am going to assume that you are trying to display information in a table given the
<td>
<button data-bind="click: sendDataToApi">Test button</button>
</td>
I am also going to assume that that there is a ko:foreach at the table or table-body level. if that is the case then sendDataToApi is associated with the parent vm object and not the object that is currently being used to create the table rows.
If that is the case then you would need to use the $parent.sendDataToApi or $root.sendDataToApi
<td>
<button data-bind="click: $parent.sendDataToApi">Test button</button>
</td>
or
<td>
<button data-bind="click: $root.sendDataToApi">Test button</button>
</td>
EDIT
you just need to add a parameter to the receiving function because the knockout passes the current object.
var serverData = [{
id: 1,
name: 'Test 1'
},
{
id: 2,
name: 'Test 2'
},
{
id: 3,
name: 'Test 3'
},
];
function ViewModel() {
var self = this;
self.data = ko.observableArray([]);
self.checkServer = function checkServer(row) {
console.log(ko.toJS(row));
}
self.fillTable = function fillTable() {
var mappedData = serverData.map(r => new RowViewModel(r));
self.data(mappedData);
}
}
function RowViewModel(data) {
var self = this;
self.id = ko.observable(data.id || 0);
self.name = ko.observable(data.name || '');
}
ko.applyBindings(new ViewModel());
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button class="button" data-bind="click: fillTable">Fill Table</button>
<table class="table">
<tbody data-bind="foreach: data">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td>
<button data-bind="click: $parent.checkServer">Check Server</button>
</td>
</tr>
</tbody>
</table>
I have some collection with dropdown list with regular 'remove' next to each row.
I added an mouseover event to change the 'remove' button's text from "X" to "Remove".
The problem is that the text is changing for ALL buttons and not just for a specific button.
JSFiddle:
http://jsfiddle.net/z22m1798/27/
Javascript:
var CartLine = function(siblings) {
var self = this;
self.availableFilters = ko.computed(function() {
return filters.filter(function(filter) {
return !siblings()
.filter(function(cartLine) { return cartLine !== self })
.some(function(cartLine) {
var currentFilterValue = cartLine.filterValue();
return currentFilterValue &&
currentFilterValue.name === filter.name;
});
});
});
self.filterValue = ko.observable();
};
var Cart = function() {
// Stores an array of filters
var self = this;
self.btnRemoveTxt = ko.observable("X");
self.lines = ko.observableArray([]);
self.lines.push(new CartLine(self.lines))// Put one line in by default
self.sortedLines = ko.computed(function() {
return self.lines().sort(function(lineA, lineB) {
if (lineA.filterValue() && lineA.filterValue().name == "Text") return -1;
if (lineB.filterValue() && lineB.filterValue().name == "Text") return 1;
return 0;
});
});
// Operations
self.addFilter = function() {
self.lines.push(new CartLine(self.lines))
};
self.removeFilter = function(line) {
self.lines.remove(line)
};
self.btnRemoveOver = function() {
console.log("Yey");///////////////
self.btnRemoveTxt("Remove");
}
self.btnRemoveOut = function() {
console.log("Yey");///////////////
self.btnRemoveTxt("X");
}
};
// Some of the Knockout examples use this data
var filters = [{
"filterValues": [{"name": "", }, ], "name": "Text" }, {
"filterValues": [{"name": "Yes",}, {"name": "No", }, ],"name": "Choice1" }, {
"filterValues": [{"name": "Yes",}, {"name": "No", }, ], "name": "Choice2" }];
//Load initial data from server
var JSONdataFromServer = $("#JSONdataFromServer").val();
console.log(JSONdataFromServer);
var dataFromServer = ko.utils.parseJson(JSONdataFromServer);
ko.applyBindings(new Cart());
HTML:
<div class='liveExample'>
<input type="hidden" id="JSONdataFromServer" value='[{ "filterValues": [{"name": "Test"}], "name": "Text" }, { "filterValues": [{"name": "Yes"}, {"name": "No"}], "name": "Choice2" }]'/>
<table width='100%'>
<tbody data-bind='foreach: sortedLines'>
<tr>
<td>
Choose option:
</td>
<td>
<select data-bind='options: availableFilters, optionsText: "name", value: filterValue'> </select>
</td>
<td data-bind="with: filterValue">
<!-- ko if: name === "Text" -->
<input type="text">
<!-- /ko -->
<!-- ko ifnot: name === "Text" -->
<select data-bind='options: filterValues, optionsText: "name", value: "name"'> </select>
<!-- /ko -->
<td>
<button class="widthFull buttonInput" href='#' data-bind='click: $parent.removeFilter, visible: $parent.lines().length > 1, event: { mouseover: $parent.btnRemoveOver, mouseout: $parent.btnRemoveOut }'><span data-bind="text: $parent.btnRemoveTxt"></span></button>
</td>
</tr>
</tbody>
</table>
<button data-bind='click: addFilter'>Add Choice</button>
<br>
<input type="submit"Submit</>
</div>
Someone can assist me here?
I am new with Knockout.js.
Thanks in advance!
Your btnRemoveText is a shared property (it's in $parent). You need to add it to each CartLine if you want it to work as you intended.
However, I'd suggest simply using css for this feature:
.buttonInput::after {
content: "X";
}
.buttonInput:hover::after {
content: "remove";
}
With the much simpler html:
<button class="widthFull buttonInput" href='#' data-bind='
click: $parent.removeFilter,
visible: $parent.lines().length > 1'>
</button>
http://jsfiddle.net/8z3agfwc/
To be complete: If you do want to move the functionality to the CartLine viewmodel:
html:
<button class="widthFull buttonInput" href='#' data-bind='
click: $parent.removeFilter,
visible: $parent.lines().length > 1,
event: {
mouseover: btnRemoveOver,
mouseout: btnRemoveOut
}'>
<span data-bind="text: btnRemoveTxt"></span>
</button>
js:
var CartLine = function(siblings) {
var self = this;
self.btnRemoveTxt = ko.observable("X");
self.btnRemoveOver = function() {
self.btnRemoveTxt("Remove");
};
self.btnRemoveOut = function() {
self.btnRemoveTxt("X");
};
// etc.
};
http://jsfiddle.net/t4ys35st/
Every entry in your sortedline array basically binds to the same property. You are using
$parent.btnRemoveTxt as the text. Every sortedline should have it's own btnRemovetxt property
Add a btnRemoveTxt property to the sortedline entries and bind that one to the span.
For the click event you could still use a function on the parent level but then you should pass through the actual entry and change the text on that entry alone.
I'm trying to bind values from observabeArray to select element. This observable array is the part of view model that binding to table with foreach. Unfortunately it's not working - I got just two empty elements.
JavaScript/jQuery:
<script>
// heres what we are going to use for binding parameters
var Roles = function (name, id) {
this.Role = name;
this.id = id;
};
var Sexes = function (name, id) {
this.Sex = name;
this.id = id;
}
function UsersViewModel() {
//This is array values that I want to bind to select
rolex: ko.observableArray([
new Roles("Admin", 3),
new Roles("User", 1),
new Roles("Operator", 2)
]);
sexx: ko.observableArray([
new Sexes("Муж", 1),
new Sexes("Жен", 0)
]);
var self = this;
//self.Id = ko.observable();
//self.Login = ko.observable("");
//self.Password = ko.observable("");
//self.Role = ko.observable();
//self.Sex = ko.observable();
//var user = {
// Id: self.Id,
// Login: self.Login,
// Password: self.Password,
// Role: self.Role,
// Sex: self.Sex
//};
self.user = ko.observable();
self.users = ko.observableArray();
var baseUri = '/api/users';
$("#adduser").click(function () {
var json = '{"Login":"' + $("#login").val() + '", "Password":"' + $("#password").val() + '", Sex":' + $("#_sex option:selected").val() + ', "Role":' + $("#_role option:selected").val() + '}';
$.ajax({
url: baseUri,
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: json,
success: function (data) {
$("#notification").text("Пользователь успешно добавлен!");
$('#notification').removeClass("hidden");
self.users.push(data);
setTimeout(function () {
$('#notification').addClass("hidden");
}, 3000);
}
});
});
self.remove = function (user) {
$.ajax({ type: "DELETE", url: baseUri + '/' + user.Id })
.done(function () {
$("#notification").text("Пользователь успешно удален!");
$('#notification').removeClass("hidden");
self.users.remove(user);
setTimeout(function () {
$('#notification').addClass("hidden");
}, 3000);
});
}
self.update = function (user) {
$.ajax({ type: "PUT", url: baseUri + '/' + user.Id, data: user })
.done(function () {
$("#notification").text("Изменения сохранены!");
$('#notification').removeClass("hidden");
setTimeout(function () {
$('#notification').addClass("hidden");
}, 3000);
});
}
$.getJSON(baseUri, self.users);
}
$(document).ready(function () {
ko.applyBindings(new UsersViewModel());
})
</script>
And here is table that show all data including mentioned selects.
HTML:
<table class="pure-table">
<thead>
<tr>
<td></td>
<td>#</td>
<td>Логин</td>
<td>Пароль</td>
<td>Роль</td>
<td>Пол</td>
</tr>
</thead>
<tbody data-bind="foreach: users">
<tr>
<td>
<input type="button" value="Сохранить" data-bind="click: $root.update" class="pure-button" />
<input type="button" value="Удалить" data-bind="click: $root.remove" class="pure-button" />
</td>
<td data-bind="text: $data.ID"></td>
<td>
<input type="text" data-bind="value: $data.Login" />
</td>
<td>
<input type="text" data-bind="value: $data.Password" />
</td>
<td>
<select data-bind="options: rolex, optionsText: 'Role'">
</select>
</td>
<td>
<select id="sex" data-bind="options: sexx, optionsText: 'Sex'">
</select>
</td>
</tr>
</tbody>
</table>
There are several changes that need to be made. First, your html needs to use the $root:
<td>
<select data-bind="options: $root.rolex, optionsText: 'Role'"></select>
</td>
<td>
<select id="sex" data-bind="options: $root.sexx, optionsText: 'Sex'"></select>
</td>
The code below works (see comments with what was changed):
var Roles = function (name, id) {
this.Role = name;
this.id = id;
};
var Sexes = function (name, id) {
this.Sex = name;
this.id = id;
};
function UsersViewModel() {
//You should assign self on the first line and use it to assign all properties
var self = this;
self.rolex = ko.observableArray([
new Roles("Admin", 3),
new Roles("User", 1),
new Roles("Operator", 2)]);
self.sexx = ko.observableArray([
new Sexes("Муж", 1),
new Sexes("Жен", 0)]);
self.user = ko.observable();
self.users = ko.observableArray();
//You should not add call to $("#adduser").click(...) here, it seems it belongs outside of model
self.remove = function (user) {
//Did not test, but it probably works
};
self.update = function (user) {
//Did not test, but it probably works
};
return self;
}
// You can use such code to bind the values:
$(function(){
//Create the model
var model = new UsersViewModel();
//Apply bindings
ko.applyBindings(model);
//Push the value to the array
model.users.push({
Id: 1,
Login: "Login",
Password: "Psw",
Role: 3,
Sex: 1
});
});
I am new to knocokout.js so i have a table in which data is bind using ajax call.When user click on edit button row information is fill to a form which is on same page below the table.
after ajax call which update the data into database successfully , i am not able to show the changed value of particular object which is changed into table. If i refresh then its show new value .
Here is my html and js code .
<div id="body">
<h2>
Knockout CRUD Operations with ASP.Net Form App</h2>
<h3>
List of Products</h3>
<table id="products1">
<thead>
<tr>
<th>
ID
</th>
<th>
Name
</th>
<th>
Category
</th>
<th>
Price
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody data-bind="foreach: Products">
<tr>
<td data-bind="text: Id">
</td>
<td data-bind="text: Name">
</td>
<td data-bind="text: Category">
</td>
<td data-bind="text: formatCurrency(Price)">
</td>
<td>
<button data-bind="click: $root.edit">
Edit</button>
<button data-bind="click: $root.delete">
Delete</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td>
</td>
<td>
</td>
<td>
Total :
</td>
<td data-bind="text: formatCurrency($root.Total())">
</td>
<td>
</td>
</tr>
</tfoot>
</table>
<br />
<div style="border-top: solid 2px #282828; width: 430px; height: 10px">
</div>
<div data-bind="if: Product">
<div>
<h2>
Update Product</h2>
</div>
<div>
<label for="productId" data-bind="visible: false">
ID</label>
<label data-bind="text: Product().Id, visible: false">
</label>
</div>
<div>
<label for="name">
Name</label>
<input data-bind="value: Product().Name" type="text" title="Name" />
</div>
<div>
<label for="category">
Category</label>
<input data-bind="value: Product().Category" type="text" title="Category" />
</div>
<div>
<label for="price">
Price</label>
<input data-bind="value: Product().Price" type="text" title="Price" />
</div>
<br />
<div>
<button data-bind="click: $root.update">
Update</button>
<button data-bind="click: $root.cancel">
Cancel</button>
</div>
</div>
</div>
Code
function formatCurrency(value) {
return "$" + parseFloat(value).toFixed(2);
}
function ProductViewModel() {
//Make the self as 'this' reference
var self = this;
//Declare observable which will be bind with UI
self.Id = ko.observable("");
self.Name = ko.observable("");
self.Price = ko.observable("");
self.Category = ko.observable("");
var Product = {
Id: self.Id,
Name: self.Name,
Price: self.Price,
Category: self.Category
};
self.Product = ko.observable();
self.Products = ko.observableArray(); // Contains the list of products
// Initialize the view-model
$.ajax({
url: 'SProduct.aspx/GetAllProducts',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
// debugger;
$.each(data.d, function (index, prd) {
self.Products.push(prd);
})
//Put the response in ObservableArray
}
});
// Calculate Total of Price After Initialization
self.Total = ko.computed(function () {
var sum = 0;
var arr = self.Products();
for (var i = 0; i < arr.length; i++) {
sum += arr[i].Price;
}
return sum;
});
// Edit product details
self.edit = function (Product) {
self.Product(Product);
}
// Update product details
self.update = function () {
var Product = self.Product();
$.ajax({
url: 'SProduct.aspx/Update',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: "{Product:" + ko.toJSON(Product) + "}",
success: function (data) {
console.log(data.d);
self.Product(null);
alert("Record Updated Successfully");
},
error: function (data) {
console.log(data);
}
})
}
// Cancel product details
self.cancel = function () {
self.Product(null);
}
}
$(document).ready(function () {
var viewModel = new ProductViewModel();
ko.applyBindings(viewModel);
});
and my webmethod which called by ajax request is as follow :
// to update product
[WebMethod]
public static testModel.Product Update(testModel.Product Product)
{
testEntities db = new testEntities();
var obj = db.Products.First(o => o.Id == Product.Id);
obj.Name = Product.Name;
obj.Price = Product.Price;
obj.Category = Product.Category;
db.SaveChanges();
return obj;
}
and JSON response of ajax call as follow
{"d":{"__type":"testModel.Product","Id":31,"Name":"12","Category":"12","Price":1350,"EntityState":2,"EntityKey":
{"EntitySetName":"Products","EntityContainerName":"testEntities","EntityKeyValues":
[{"Key":"Id","Value":31}],"IsTemporary":false}}}
Here's what's happening. Here: self.Products.push(prd) prd is just a plain javascript object with plain property values, nothing is observable. You're pushing the raw object onto the Products observableArray, which updates the DOM because Products was changed and KO is watching it. When you click 'edit', you set self.Product to that plain object and the KO updates the DOM with this object and its values because Product was changed and KO is watching it. So now your Product form below displays, you see the information, and it looks like you can edit the properties but KO won't update those property changes because KO isn't watching them. They're not observable. Change:
$.each(data.d, function (index, prd) {
//self.Products.push(prd);
self.Products.push({
Id: ko.observable(prd.Id),
Name: ko.observable(prd.Name),
Price: ko.observable(prd.Price),
Category: ko.observable(prd.Category)
});
});
General helpful tips
<div data-bind="if: Product">
This only evaluates once when you bind the viewModel to the DOM with ko.applyBindings. Since self.Product has an initial value of null KO removes this altogether.*Note: I was thinking of #if for some reason.
This works like the visible binding except when the value is false, the element and its children are removed from the DOM. So there is more DOM manipulation going on than necessary. You probably just want to hide this <div>
I would recommend changing this to:
<div data-bind="visible: Product">
Instead of this:
<input type="text" data-bind="text: Product().Name" />
<input type="text" data-bind="text: Product().Category" />
<input type="text" data-bind="text: Product().Price" />
Try this instead:
<div data-bind="with: Product">
<input type="text" data-bind="text: Name" />
<input type="text" data-bind="text: Category" />
<input type="text" data-bind="text: Price" />
</div>
Consider renaming self.Product to self.SelectedProduct to make it more clear what it is for.
I'm not sure what this is doing in the ViewModel:
//Declare observable which will be bind with UI
self.Id = ko.observable("");
self.Name = ko.observable("");
self.Price = ko.observable("");
self.Category = ko.observable("");
var Product = {
Id: self.Id,
Name: self.Name,
Price: self.Price,
Category: self.Category
};
You don't use them in the DOM. You were kind of on the right path with this though. Instead, before the ProductViewModel, create this:
function ProductModel(data) {
var self = this;
data = data || {};
self.Id = ko.observable(data.Id);
self.Name = ko.observable(data.Name);
self.Price = ko.observable(data.Price);
self.Category = ko.observable(data.Category);
}
Now instead of:
$.each(data.d, function (index, prd) {
self.Products.push({
Id: ko.observable(prd.Id),
Name: ko.observable(prd.Name),
Price: ko.observable(prd.Price),
Category: ko.observable(prd.Category)
});
});
We can just do this:
$.each(data.d, function (index, prd) {
self.Products.push(new ProductModel(prd));
});
Hopefully that will get you headed in the right direction.
There is something to change:
Replace
$.each(data.d, function (index, prd) {
self.Products.push(prd);
})
With:
$.each(data.d, function (index, prd) {
self.Products.push({
Id: ko.observable(prd.Id),
Name: ko.observable(prd.Name),
Price: ko.observable(prd.Price),
Category: ko.observable(prd.Category)
});
})
Use ko.observable to make your properties notify the view of its changes so that the view can update accordingly. This should work but not perfect because this is 2 way binding, so whenever you update the values in your div, the view model object is updated immediately and even if your ajax fails to update the data in backend, making the data out of synch between client side and server side.
For better solution. You need to have a look at protectedObservable
$.each(data.d, function (index, prd) {
self.Products.push({
Id: ko.protectedObservable(prd.Id),
Name: ko.protectedObservable(prd.Name),
Price: ko.protectedObservable(prd.Price),
Category: ko.protectedObservable(prd.Category)
});
})
Inside your self.update ajax success function, trigger a change:
success: function (data) {
var product =self.Product();
product.Id.commit();
product.Name.commit();
product.Price.commit();
product.Category.commit();
self.Product(null);
alert("Record Updated Successfully");
}
And revert if there is error:
error: function (data) {
product.Id.reset();
product.Name.reset();
product.Price.reset();
product.Category.reset();
}
Update:
Remember to change all the places with Product.Property to Product.Property() to get its property value . For example: arr[i].Price should be changed to arr[i].Price()
Add self.Products.push(data.d); to the update() functions success handler.
success: function (data) {
console.log(data.d);
self.Product(null);
self.Products.push(data.d);
alert("Record Updated Successfully");
},
You need to update the array so that it reflects in bound html.
I have got a task to do knockout.js.But I can't create the textbox value as json object.
I have a model student with fields name and age.For creating new student i can't set the value as json object.
newlist.html.erb
<script>
$(document).ready(function() {
var viewModel = {
firstName: ko.observable(),
_age: ko.observable(),
validationMessage: ko.observable()
};
var self = this;
self.save = function() {
var dataToSave =firstName: ko.observable();
_age: ko.observable();
alert("Could now send this to server: " + JSON.stringify(viewModel));
}
viewModel.Age = ko.dependentObservable({
read: viewModel._age,
write: function (value) {
if (!isNaN(value)) {
this._age(value);
this.validationMessage("");
}
else {
this.validationMessage("Age must be a number!");
}
},
owner: viewModel
});
ko.applyBindings(viewModel);
});
</script>
<h1>Testing</h1>
Name: <input type="text" data-bind="
value: firstName,
valueUpdate : 'afterkeydown'
"/>
<br />
Age: <input type="text" data-bind="value: Age, valueUpdate : 'afterkeydown'" />
<Br />
<span data-bind="text: validationMessage" style="color:Red"></span>
<Br />
<button data-bind='click: save'>Submit</button>
<Br />
But it shows some error. How can I create a json object?
You can convert model to json in next way
var dataToSave = {
firstName: viewModel.firstName(),
_age: viewModel._age()
}
here you task is resolved: Solution