Reputation: 12897
I am new to knockout. I am trying to use observable arrays to track the changes from UI. The UI is loading with the initial data which is stored in the array. And i am trying to add new object into the array dynamically from another screen.
Now i am able to add new object into the array. But UI is not getting reflected with new changes in the array. Below is my html and javascript code.
Am i missing something.
<html>
<head>
<link rel="stylesheet" href="bootstrap.css" type="text/css" />
<link rel="stylesheet" href="bootstrap-theme.css " type="text/css" />
<script src="jquery.js" type="text/javascript"></script>
<link rel="stylesheet" href="prodconfig.css " type="text/css" />
<script src="jquery.mobile.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="cordys.min.css" type="text/css" />
<link rel="stylesheet" href="jquery.mobile.structure.min.css" type="text/css" />
<script src="knockout.js" type="text/javascript"></script>
<script src="prodconfig.js" type="text/javascript"></script>
</head>
<body>
<div data-role="page" id="productsPage" class="dataContainer">
<div id="productDetails">
<div data-role="content" id="productTable">
<table data-role="table" class="ui-responsive table">
<thead>
<tr>
<th data-priority="6">Product Name</th>
<th data-priority="1">Description</th>
<th data-priority="2">Parent?</th>
</tr>
</thead>
<tbody id="pBody" data-bind="foreach: products">
<tr class="success">
<td><span data-bind="text: name"></span></td>
<td><span data-bind="text: desc"></span></td>
<td></td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="prodButtons">
<button id="addProdProduct">Add Product</button>
<button id="addProdChar">Add Characteristics</button>
<button id="prodButton">Next</button>
</div>
</div>
<div id="addProductPage" data-role="page" >
<span><h3>Product Name</h3></span><input type="text" id="prodNameId"></input>
<span><h3>Product Desc</h3></span><input type="text" id="prodDescId"></input>
<span><h3>Is Parent</h3></span><input type="text" id="prodIsParentId"></input>
<button id="addProdButton">OK</button>
<div>
</body>
var configArray = new Array();
var products = [];
var services = new Array();
var chars = [];
var prd;
for(var i=0;i<2;i++){
var product = new Object();
product["name"] = "prod"+i+"Name";
product["desc"] = "prod"+i+"Desc";
product["isParent"] = "prme";
for(var j=0;j<2;j++){
var charr = new Object();
charr["name"] = "prod"+i+"char"+j;
charr["val"] = "prod"+i+"char"+j+"val";
chars[j] = charr;
}
product["chars"] = chars;
products[i] = product;
}
var ProductViewModel = function(items) {
this.items = ko.observableArray(items);
this.itemToAdd = ko.observable("");
this.addItem = function() {
if (this.itemToAdd() != "") {
this.items.push(this.itemToAdd());
this.itemToAdd("");
}
}.bind(this);
};
$(function(){
$('#addProdProduct').click(function() {
window.location.href = "#addProductPage";
});
$('#addProdButton').click(function() {
addProduct();
});
prd = new ProductViewModel(products);
ko.applyBindings(prd);
});
function addProduct(){
var product = new Object();
product["name"] = $('#prodNameId').val();
product["desc"] = $('#prodDescId').val();
product["isParent"] = $('#prodIsParentId').val();
prd.itemToAdd(product);
prd.addItem();
window.location.href = '#';
}
Upvotes: 0
Views: 413
Reputation: 626
The code below shown a sample procedure for inserting data using knockoutjs MVVM pattern. Here i using bootstrap Modal Popup for inserting Data.
HTML
<div class="row">
<button type="button" class="btn btn-primary pull-right" data-bind="click:add" data-toggle="modal" data-target="#myModal1">
<i class="fa fa-plus"></i> Add New Data
</button>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Action</th>
</tr>
</thead>
<tbody data-bind="template:{name:'item-view-template',foreach:products}"></tbody>
</table>
</div>
<script type="text/html" id="item-view-template">
<tr>
<td class="text-left" data-bind="text:ProductName"></td>
<br />
/tr>
</script>
<div class="modal fade" id="myModal1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Add Data</h4>
</div>
<div class="modal-body" data-bind="template:{name:'item-create-template',data:selectedData}">
<div class="row">
<div class="col-md-12"></div>
</div>
</div>
</div>
</div>
</div>
<script type="text/html" id="item-create-template">
<form>
<fieldset>
<div class="form-group col-md-6">
<label>Name</label>
<input type="text" class="form-control" data-bind="value:ProductName" />
</div>
<button class="btn btn-primary" data-bind="click:$parent.save">Save</button>
<button class="btn btn-default" data-dismiss="modal">Cancel</button>
</fieldset>
</form>
</script>
<script type="text/javascript">
var vm = new ProductViewModel();
ko.applyBindings(vm);
vm.init();
</script>
View Model Js File
function ProductViewModel() {
var self = {};
self.data = ko.observableArray();
self.products = ko.observableArray();
self.selectedData = ko.observable(Product({}));
self.init = function () {
$.get('/MyController/GetAll', function (data) {
$.each(data, function (key, value) {
self.products.push(Product(value));
});
});
};
self.add = function () {
self.selectedData(Product({}));
};
self.save = function() {
if (self.selectedData()) {
var jsonData = ko.toJS(self.selectedData);
$.post('/MyController/Create', jsonData, function(data) {
if (data.Status == true) {
$('#myModal1').modal('hide');
bootbox.alert("Product created successfully", function() {
self.Products.removeAll();
$.get('/MyController/GetAll', function (result) {
$.each(result.Products, function (key, value) {
self.Products.push(Product(value));
});
});
});
} else {
bootbox.alert("Duplicate values not allowed..!!");
}
});
} else {
bootbox.alert("Error!!");
}
};
return self;
}
And the Model
function Product(product) {
var self = {};
self.Id = ko.observable(product.Id || '');
self.ProductName = ko.protectedObservable(product.Name || '');
return self;
}
I think this will help you
Upvotes: 0
Reputation: 18832
You are binding to the products
variable instead of to the items
field on your viewmodel.
Change your binding to:
<tbody id="pBody" data-bind="foreach: items">
Upvotes: 3