Knockout.js - passing parameters - javascript

There is a problem with passing parameter, when I press button, nothing is going and there are no errors in console
<tbody data-bind="foreach: hotels">
<tr>
<td data-bind="text: Id"></td>
<td data-bind="text: Name"></td>
<td data-bind="text: Address"></td>
<td>
<button data-bind="click: $root.eksportuj" > #Html.Text("Eksportuj") </button>
</td>
</tr>
and
self.eksportuj = function (obj, event) {
$.ajax({
ulr: "#Url.Action("eksport", "Controller")",
type: 'POST',
data: {'Id' : obj.Id},
success: function (result)
{
alert("True");
},
error: function()
{
alert("Error");
}
});
}

Maybe the problem is in non-enclosed button tag, or tbody tag
<button data-bind="click: $root.eksportuj" > #Html.Text("Eksportuj") </button>
Simle JSFiddle DEMO works as expected
JSFiddle DEMO code:
var viewModel = new function()
{
var self = this;
self.hotels = ko.observableArray([{
Id : "1",
Name : "N1",
Address : "A1"
},{
Id : "2",
Name : "N2",
Address : "A2"
}]);
self.eksportuj = function (obj, event) {
alert(obj.Id)
}
}
ko.applyBindings(viewModel)

Related

Mouseover event affect buttons in ALL rows in list and not just on the specific button

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.

Disabled Button when it Clicked in table

I want to disable button Assign when it clicked, bacause it should assign only once so i can achieve this, I have done the following code in HTML:
<table class="table details">
<thead>
<tr>
<th sort-by="firstName">User Name</th>
<th sort-by="lastName">Description</th>
<th sort-by="Budget" sort-init="desc">Bid Amount</th>
<th sort-by="lastName">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="issue in issues | filter:filter">
<td><strong><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.UserName }} </strong></td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{ issue.Description }}</td>
<td><a href="/ViewBid/Index?{{ issue.User_ID }}" />{{issue.Bid_amt}}</td>
<td>
<div ng-controller="ExampleCtrl_Assign">
<div ng-show="AsgHide">
<button type="button" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
</div>
</div>
<div ng-controller="ExampleCtrl_Delete">
<div ng-show="AsgHide" >
<button type="button" ng-click="DeleteRecord(issue.ID)">Delete</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>
And JavaScript Code is as following:
var app = angular.module('siTableExampleApp_Assign', []);
app.controller('ExampleCtrl_Assign', ['$scope','$http', function ($scope, $http) {
var user2 = window.localStorage.getItem('UserId');
var Basic = window.localStorage.getItem('Basic');
var Token = window.localStorage.getItem('Token');
$scope.FunctionDisable = function (i) {
$("#rbutton'+i+'").attr("disabled", "disabled");
}
$scope.AssignRecord = function (ID, Description, Bid_amt) {
var BidID = ID;
var date = new Date();
encodedString = {
"ID": 1,
"Travel_Info_ID": travel_info_id,
"Bid_ID": parseInt(BidID),
"Description": Description,
"Bid_amt": Bid_amt,
"Status": "InProcess",
"User_ID": user2,
"Entry_Date": date,
"Update_Date": date
}
$http({
method: 'POST',
url: 'http://saisoftwaresolutions.com/v1/Assigned_Bids/Assigned_Bid/Create',
data: encodedString,
headers: {
'Authorization': 'Basic ' + Basic,
'Token': Token
}
})
.success(function (data, status, headers, config) {
console.log(headers());
console.log(data);
if (status === 200) {
//window.location.href = 'http://localhost:22135/BDetail/Index';
} else {
$scope.errorMsg = "Login not correct";
}
})
.error(function (data, status, headers, config) {
$scope.errorMsg = 'Unable to submit form';
})
Use can always use ng-disabled directive provided by Angular to disabled html elements.
I have made one example based on your requirements and help it will solve your issue:
<div ng-app ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items">{{item.User_ID}}: {{item.User_Name}}
<button ng-click="handleClick($index)" ng-disabled="item.disabled">
{{item.User_Name}}
</button>
</li>
</ul>
</div>
function MyCtrl($scope) {
$scope.items = [
{
User_ID: '10',
disaled: false,
User_Name: 'ABC'
}, {
User_ID: '11',
disaled: false,
User_Name: 'XYZ'
}
];;
$scope.handleClick = function(index){
$scope.items[index].disabled = true;
}
}
Angular has a directive just for this: ng-disabled.
From their official documentation:
This directive sets the disabled attribute on the element if the
expression inside ngDisabled evaluates to truthy.
So you can set a boolean value in your code-behind to true and have that evaluate inside your button. For example:
<button type="button" ng-disabled="issue.IsDisabled" ng-click="AssignRecord(issue.ID,issue.Description,issue.Bid_amt)">Assign</button>
Also, check out the example in their documentation and this jsfiddle: https://jsfiddle.net/simpulton/q8r4e/.

How to update the edited item of knockout js observablearray in UI part?

How to update the knockout js observablearray in UI part..Initially Im editing a item and in update function i'm trying to update a particular item so im sending the current item object to service and getting the updated vales as response. Inside the response I need to update the observablearray as well the UI too.. I have tried some thing like this and its not working for me... please check in http://jsfiddle.net/up8rB/20/
<div data-bind="ifnot: Role()">
<label for="description">Description</label>
<input type="text" data-bind="value: Description" class="form-control" placeholder="Enter the description..." />
<button data-bind="click: $root.create"> Create</button>
</div>
<div data-bind="if: Role">
<label for="description">Description</label>
<input type="text" data-bind="value: Role().Description" class="form-control" placeholder="Enter the description..." />
<button data-bind="click: $root.update"> Save</button>
</div>
<table id="example1" class="table table-bordered table-striped" data-bind="visible: Roles().length > 0">
<thead>
<tr>
<th>RoleID</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody data-bind="foreach: Roles">
<tr>
<td data-bind="text: $data.RoleID"></td>
<td data-bind="text: $data.Description"></td>
<td>
<button data-bind="click: $root.edit" >Edit</button>
<button data-bind="click: $root.delete" >Delete</button>
</td>
</tr>
</tbody>
</table>
function RoleViewModel() {
var self = this;
self.RoleID = ko.observable("0");
self.Description = ko.observable().extend({
required: { message: 'Please supply description ..' }
});
var Role = {
RoleID: self.RoleID,
Description: self.Description
};
self.Role = ko.observable();
self.Roles = ko.observableArray();
$.ajax({
url: 'Service.svc/RoleCollection',
cache: false,
type: 'GET',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
self.Roles(data); //Put the response in ObservableArray
}
});
self.edit = function (Role) {
self.Role(Role);
}
self.update = function () {
var Role = self.Role();
$.ajax({
url: '..service.svc/UpdateRole',
cache: false,
type: 'PUT',
contentType: 'application/json; charset=utf-8',
data: ko.toJSON(Role),
success: function (data) {
for (var i = 0; i < self.Roles().length; i++) {
alert(self.Roles()[i].RoleID());
if (self.Roles()[i].RoleID() === data.RoleID) {
self.Role(self.Roles()[i]);
break;
}
}
}
})
}
var viewModel = new RoleViewModel();
ko.applyBindings(viewModel);
Your issue is that your are assigning items to your observable array that aren't themselves observable, so your UI is not updating when they change.
I did some renaming, as I found it confusing with so many things named 'Role', but the first change was your array setup:
var roles = [{
RoleID: ko.observable(1),
Description: ko.observable('First item')
}, {
RoleID: ko.observable(2),
Description: ko.observable('Second item')
}];
I also modified the update function:
self.update = function () {
var _Role = self.Role();
for (var i = 0; i < self.Roles().length; i++) {
if (self.Roles()[i].RoleID === _Role.RoleID) {
self.Roles()[i] = _Role();
break;
}
}
}
See the Updated Fiddle
Update:
Your json response should populate the observableArray correclty, but you may have an issue when setting it back after the update, try setting the properties rather than overwriting the element:
self.update = function () {
var _Role = self.Role();
for (var i = 0; i < self.Roles().length; i++) {
if (self.Roles()[i].RoleID === _Role.RoleID) {
self.Roles()[i].RoleID = _Role().RoleID;
self.Roles()[i].Description = _Role().Description;
break;
}
}
}
See the Updated Fiddle

Update UI after ajax response

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.

Binding Knockout.JS viewmodel to jQuery dialog

I have a jQuery modal dialog inside which I would like to pass data from a Knockout viewmodel. The dialog works fine as is - however, below code is broken.
Ideally, I would like to be able to click on the URI that triggers the modal dialog, and have the dialog load the data from the Knockout viewmodel. Any help would be greatly appreciated.
Markup:
List Names
<div id="listNames" data-bind="dataModel: { autoOpen: false, modal: true }">
<div>
<form action=''>
<p>You have added <span data-bind='text: name().length'> </span>
person(s)</p>
<table data-bind='visible: name().length > 0'>
<thead>
<tr><th>Select</th>
<th>Name</th>
<th>Age</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: metrics'>
<tr>
<td><input type="checkbox" /></td>
<td><span data-bind='text: name' > </span></td>
<td><span data-bind='text: age'> </span></td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
ViewModel:
var dataModel = function (edata) {
var self = this;
self.edata = ko.observableArray(edata);
self.addname = function () {
self.edata.push({
name: "",
age: ""
});
};
self.removename = function (name) {
self.edata.remove(name);
};
self.save = function (form) {
alert("Could now transmit to server: "
+ ko.utils.stringifyJson(self.edata));
// To actually transmit to server as a regular form post, write this:
// ko.utils.postJson($("form")[0], self.edata);
};
};
var viewModel = new dataModel([
{ name: "Jack", age: "41" },
{ name: "Jill", age: "33" }
]);
ko.applyBindings(new viewModel);
jQuery Dialog:
$("#listNames, ").dialog({
autoOpen: false,
width: 300,
modal: true,
buttons: {
"OK": function () {
$(this).dialog("destroy");
},
Cancel: function () {
$(this).dialog("close");
}
}
});
$("#openList")
.click(function () {
$("#listNames").dialog("open");
});
There are a few errors in the code you posted.
I have a working version here : http://jsfiddle.net/uFgz8/1/
Here is the HTML :
Open dialog //you had 2 elements with the same ID, I removed the ID on the link and bound it to a method in the view model
<div id="listNames"> <div>
<form action=''>
<p>You have added <span data-bind='text: name.length'> </span> person(s)</p> // name item is not observable, so you cannot use name().length
<table data-bind='visible: name.length > 0'> // same remark for name
<thead>
<tr>
<th>Select</th>
<th>Name</th>
<th>Age</th>
<th />
</tr>
</thead>
<tbody data-bind='foreach: edata'>
<tr>
<td>
<input type="checkbox" />
</td>
<td><span data-bind='text: name'> </span>
</td>
<td><span data-bind='text: age'> </span>
</td>
</tr>
</tbody>
</table>
</form>
</div>
</div>
The JS:
$("#listNames").dialog({
autoOpen: false,
width: 300,
modal: true,
buttons: {
"OK": function () {
// do something
$(this).dialog("close"); // I replaced destroy by close, so it can be opened after ok has been clicked
},
Cancel: function () {
$(this).dialog("close");
}
}
});
var dataModel = function (edata) {
var self = this;
self.edata = ko.observableArray(edata);
self.addname = function () {
self.edata.push({
name: "",
age: ""
});
};
self.openDialog = function () {
$("#listNames").dialog("open");
};
self.removename = function (name) {
self.edata.remove(name);
};
self.save = function (form) {
alert("Could now transmit to server: " + ko.utils.stringifyJson(self.edata));
// To actually transmit to server as a regular form post, write this: ko.utils.postJson($("form")[0], self.edata);
};
};
var viewModel = new dataModel([{
name: "Jack",
age: "41"
}, {
name: "Jill",
age: "33"
}]);
ko.applyBindings(viewModel); // you have created a variable viewModel with data, but you bound ko with a new object of type viewModel, you must either call ko with viewModel you created, or inline the creation of a new "dataModel"
edit : I added some comments to my changes
edit 2 : I updated the link to the jsfiddle to get to the correct version ;)

Categories

Resources