Knockout foreach binding with Json Object - asp.net

I am trying to bind a table using a foreach binding of Knockout. However, my observable properties are reflecting changes, but the data is not able to bind with the table. Below is the code:
HTML
<div class="container-fluid ">
<table class="table table-Alternate table-condensed header" id="appTable">
<thead>
<tr>
<th></th>
<th style="font-weight: bold;">Market </th>
<th style="font-weight: bold;">Product Name</th>
<th style="font-weight: bold;">Company Name</th>
<th style="font-weight: bold;">Product Id</th>
<th style="font-weight: bold;">Publisher Name </th>
<%--<th><span style="font-weight: bold;" id="Span1">Action</span></th>--%>
</tr>
</thead>
<tbody id="appAnnieData" data-bind="foreach: CompanyInfo">
<%-- <tr>
<td><span data-bind="text:Market"></span></td>
<td><span data-bind="text: Product_Name"></span></td>
<td><span data-bind="text: Company_Name"></span></td>
<td><span data-bind="text: Product_id"></span></td>
<td><span data-bind="text: Unified_Product_Name"></span></td>
</tr>--%>
</tbody>
</table>
</div>
script
$(document).on('click', '#appAnnieSearch', function() {
mainModel = $(this);
var id = $(this).parents().find("#txtCompanyId").val();
if (id == "") {
toastr.info('Please enter Company ID');
return false;
}
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: "../../Services/AService.asmx/GetCompanyInformation",
data: {
id: JSON.stringify(id)
},
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function(res) {
if (res.d != null && res.d != undefined && res.d != "NotFound") {
var options = JSON.parse(res.d);
FillDetailsForCompany(options.app_list);
} else {
toastr.options.timeOut = 7000;
toastr.options.closeButton = true;
toastr.info('No information found for the selected Company Id. Please try another one.');
}
document.getElementById("loader_search").style.display = "none";
},
error: function(errormsg) {
$(".dropdown_SubDomainLoading").hide();
toastr.options.timeOut = 7000;
toastr.options.closeButton = true;
toastr.error('Something Went Wrong');
}
});
});
function FillForCompany(appanydata) {
var dataArray = [];
for (var i = 0; i < appanydata.length; i++) {
dataArray.push(new AppViewModel(appanydata[i].market, appanydata[i].product_name, appanydata[i].company_name, appanydata[i].product_id, appanydata[i].unified_product_name,
appanydata[i].product_franchise_id, appanydata[i].product_category, appanydata[i].unpublished, appanydata[i].company_id, appanydata[i].unified_product_id, appanydata[i].product_franchise_name, appanydata[i].publisher_id,
appanydata[i].publisher_name, appanydata[i].product_code));
}
DomainModule.dataContext.CompanyInfo(dataArray);
}
function AppViewModel(market, product_name, company_name, product_id, unified_product_name, product_franchise_id, product_category, unpublished, company_id,
unified_product_id, product_franchise_name, publisher_id, publisher_name, product_code) {
self = this;
self.Market = ko.observable(market);
self.Product_Name = ko.observable(product_name);
self.Company_Name = ko.observable(company_name);
self.Product_Id = ko.observable(product_id);
self.Unified_Product_Name = ko.observable(unified_product_name);
self.Product_Franchise_Id = ko.observable(product_franchise_id);
self.Product_Category = ko.observable(product_category);
self.Unpublished = ko.observable(unpublished);
self.Company_Id = ko.observable(company_id);
self.Unified_Product_Id = ko.observable(unified_product_id);
self.Product_Franchise_Name = ko.observable(product_franchise_name);
self.Publisher_Id = ko.observable(publisher_id);
self.Publisher_Name = ko.observable(publisher_name);
self.Product_Code = ko.observable(product_code);
}
The observable property is getting populated and when I inspect the object value DomainModule.dataContext.CompanyInfo has the respective data. However, I do not get the table populated.
I am trying to fetch the data on the click event of a button. Is there something I am missing?

Related

create button for lines in records and update field

i Have a table with orders,
i want to create a button per each line in the table that when clicked, will change the value of a field in that record (order status to cancelled) without redirect to any update page.
i created a link using HtmlAction but its not activating the function(see screen shot)
Here is the actionLink:
<td>
<div class="text-center">
<p>#Html.ActionLink("cancel", "CancelOrder", "Order",new { id = #order.Id })</p>
</div>
</td>
Thank you!
You get a 405 error because the "CancelOrder" method should be a get request instead of a post request.
Below is a work demo:
Index View:
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.IsCancle)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var order in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => order.Name)
</td>
<td>
#Html.DisplayFor(modelItem => order.IsCancle)
</td>
<td>
<p>#Html.ActionLink("cancel", "CancelOrder", "Orders", new { id = #order.Id })</p>
</td>
</tr>
}
</tbody>
</table>
Controller:
public async Task<IActionResult> Index()
{
return View(await _context.Orders.ToListAsync());
}
[HttpGet]
public IActionResult CancelOrder(int id)
{
var order = _context.Orders.Find(id);
order.IsCancle = true;
_context.Update(order);
_context.SaveChanges();
return RedirectToAction(nameof(Index));
}
Result:
By the way,if you don't want to refresh the entire page, I recommend you to use Ajax. Here is an example of using Ajax for partial refresh:
Index View:
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var order in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => order.Name)
</td>
<td>
<button id="Cancle">Cancle</button>
<input type="hidden" name="Id" value="#order.Id" />
</td>
</tr>
}
</tbody>
</table>
#section Scripts
{
<script>
$('#Cancle').on('click', function (e) {
var id = $('input[name=Id ]').val();
$.ajax({
url: 'Orders/CancelOrder',
type: 'post',
data: { "id": id } ,
dataType: 'json',
success: function (data) {
console.log(data)
}
})
});
</script>
}
Controller:
public async Task<IActionResult> Index()
{
return View(await _context.Orders.ToListAsync());
}
[HttpPost]
public IActionResult CancelOrder(int id)
{
var order = _context.Orders.Find(id);
order.IsCancle = true;
_context.Update(order);
_context.SaveChanges();
return Json(id);
}
Result:

Not getting data

am creating one project am using angularjs. I want to get the data from database.i had try this code but we are not getting the data also not getting any error in console. after put the debugger in javascript its successfully run
so please give your feedback.
in my controller am using the code
public JsonResult userList()
{
dBase dal = new dBase();
var userlist = dal.GetAllUsers("0");
return Json(userlist, JsonRequestBehavior.AllowGet);
}
<link href="~/css/custom.css" rel="stylesheet">
<script src="~/js/AngularJS.js"></script>
<script src="~/js/angular.min.js"></script>
<script src="~/js/Module.js"></script>
<script src="~/js/Service.js"></script>
<script src="~/js/WolskiDevJ.js"></script>
in module
var app = angular.module("myApp", []);
in Service.js
app.service("myService", function ($http) {
this.getAlluser = function () {
debugger;
try {
return $http.get("users/userList");
}
catch (err) {
return err;
}
};
});
in WolskiDevJ.js
app.controller("UserCntrl", function ($scope, myService) {
getalluserlist();
function getalluserlist() {
debugger;
var getuserdata = myService.getAlluser();
debugger;
getuserdata.then(function (usr) {
$scope.userlist = usr.data;
}, function () { alert('get error') });
};
});
in view am using the code like
<script src="~/js/AngularJS.js"></script>
<script src="~/js/angular.min.js"></script>
<script src="~/js/Module.js"></script>
<script src="~/js/Service.js"></script>
<script src="~/js/WolskiDevJ.js"></script>
<div class="static_pages home" ng-app="myApp" ng-controller="UserCntrl">
<table id="myTable" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th width="8%">Name</th>
<th width="20%">Email</th>
<th width="12%">Username</th>
<th width="14%">Access</th>
<th width="8%">Status</th>
<th width="6%">Edit</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="userlist in ulist">
<td>{{userlist.first_name}} </td>
</tr>
</table>
</div>
Instead of
<tr ng-repeat="userlist in ulist">
<td>{{userlist.first_name}} </td>
</tr>
type
<tr ng-repeat="myUser in userlist">
<td>{{myUser.first_name}} </td>
</tr>

How to update the table value using ajax with foreach jstl in spring

**This is ajax function**
$.ajax({
type : "Get",
url : url,
data:$("#client").serialize(),
dataType:'json',
success : function(response)
{
},
error : function(e)
{
alert('Error: ' + e);
}
});
This is my Controller
#RequestMapping(value = "/authenticate/ajaxObj", method = RequestMethod.GET)
public #ResponseBody ArrayList<String> ajax_Claims(Model model,
#ModelAttribute("CalculatorDO") CalculatorDO calculatorDO)
{
System.out.println("\nAjax Hit the Controller");
ArrayList<String> clist=new ArrayList<>();
ArrayList<String> namelist=new ArrayList<>();
ArrayList<String> classlist=new ArrayList<>();
ArrayList<String> address=new ArrayList<>();
namelist=calculatorDO.getNameList();
classlist=calculatorDO.getNameList();
address=calculatorDO.getNameList();
clist.add(namelist);
clist.add(classlist);
clist.add(address);
model.addAttribute("nameList", clist);
return clist;
}
My table
<table>
<thead>
<tr>
<th>Name</th>
<th>Class</th>
<th>address</th>
</tr>
</thead>
<tbody>
<c:forEach items="${nameList}" var="list">
<tr>
<td><c:out value="${list.namelist}"/></td>
<td><c:out value="${list.classlist}" /></td>
<td><c:out value="${list.address}"/></td>
</tr>
</c:forEach>
</tbody>
</table>
I want to reload the table.
Replace <tbody> with
<tbody id="ajax-tbody-results">
</tbody>
And use jQuery tmpl to fill the table with your data (jQuery tmpl )
<script id="table-template" type="text/x-jquery-tmpl">
<tr>
<td>${namelist}</td>
<td>${classlist}</td>
</tr>
</script>
$.ajax({
type : "Get",
url : url,
dataType:'json',
success : function(response)
{
jQuery("#table-template").tmpl(data).appendTo("#ajax-tbody-results");
},
error : function(e)
{
alert('Error: ' + e);
}
});

not updating entity in viewmodel after post request using ajax

I am new to knockout.js and i am using post method to update data into database . Here is my code
<%# Page Language="C#" AutoEventWireup="true" CodeFile="SProduct.aspx.cs" Inherits="SProduct" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js" type="text/javascript"></script>
</head>
<body>
<form id="form1" runat="server">
<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 data-bind="ifnot: Product()">
<div>
<h2>
Add New Product</h2>
</div>
<div>
<label for="name">
Name</label>
<input data-bind="value: $root.Name" type="text" title="Name" />
</div>
<div>
<label for="category">
Category</label>
<input data-bind="value: $root.Category" type="text" title="Category" />
</div>
<div>
<label for="price">
Price</label>
<input data-bind="value: $root.Price" type="text" title="Price" />
</div>
<br />
<div>
<button data-bind="click: $root.create">
Save</button>
<button data-bind="click: $root.reset">
Reset</button>
</div>
</div>
</div>
<script type="text/javascript">
function formatCurrency(value) {
return "$" + 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;
});
//Add New Item
self.create = function () {
Product.Id="333";
if (Product.Name() != "" && Product.Price() != "" && Product.Category() != "") {
$.ajax({
url: 'SProduct.aspx/Add',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data:"{item:" + ko.toJSON(Product) + "}",
success: function (data) {
self.Products.push(data.d);
self.Name("");
self.Price("");
self.Category("");
},
error:function(data)
{
alert("error");
console.log(data.d);
}
});
}
else {
alert('Please Enter All the Values !!');
}
}
//Delete product details
self.delete = function (Product) {
if (confirm('Are you sure to Delete "' + Product.Name + '" product ??')) {
var id = Product.Id;
$.ajax({
url: 'SProduct.aspx/Delete',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data:"{id:" + ko.toJSON(id) + "}",
success: function (data) {
self.Products.remove(Product);
},
error:function(data){
console.log(data.d);
alert('Error');
}
})
}
}
// 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) {
alert("success");
console.log(data.d);
// self.Products.removeAll();
// self.Products(data.d); //Put the response in ObservableArray
self.Product(null);
alert("Record Updated Successfully");
},
error: function (data) {
console.log(data);
}
})
}
// Reset product details
self.reset = function () {
self.Name("");
self.Price("");
self.Category("");
}
// Cancel product details
self.cancel = function () {
self.Product(null);
}
}
var viewModel = new ProductViewModel();
ko.applyBindings(viewModel);
</script>
</form>
</body>
</html>
Updated
Here is screen shot of my page . when i click on update ajax success function is called, but no change in above table field .
Why do you have to update the item back to the list? You're not doing anything to the properties of the object on the server side are you?
Your edit method should look something like this:
self.edit = function(item) {
self.Product(item);
};
and remove the following code nemesv said.
self.Products.removeAll();
self.Products(data.d); //Put the response in ObservableArray
My first post so be gentle ;)
Response to comment:
change your success to:
success: function (data) {
var product = ko.utils.arrayFirst(self.Products(), function(item) {
return (item.Id == data.d.Id);
}); // You could either update the product object with the new values from data.d or delete it and add a new product object.
for (var p in product ) {
product [p] = data.d[p];
}
self.Product(null);
alert("Record Updated Successfully");
},
Found a bug, it was replacing the observables with native values.
for (var p in product ) {
product [p](data.d[p]);
}
I took the liberty of simplifying the code and removing everything that hasn't anything to do with the update function. The following code example should work. ( I used knockout 2.3.0 and jQuery 1.9.1)
<script type="text/javascript">
function Product(id, name, price, category) {
var self = this;
self.Id = ko.observable(id);
self.Name = ko.observable(name);
self.Price = ko.observable(price);
self.Category = ko.observable(category);
}
function ProductViewModel() {
var self = this;
self.Product = ko.observable();
self.Products = ko.observableArray(); // Contains the list of products
$.ajax({
url: 'SProduct.aspx/GetAllProducts',
cache: false,
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: {},
success: function (data) {
$.each(data.d, function (index, prd) {
var p = new Product(prd.Id, prd.Name, prd.Price, prd.Category);
self.Products.push(p);
});
}
});
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;
});
self.edit = function(product) {
self.Product(product);
};
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) {
for (var p in product) {
product[p](data.d[p]);
}
self.Product(null);
alert("Record Updated Successfully");
},
error: function(data) {
console.log(data);
}
});
};
self.reset = function() {
self.Name("");
self.Price("");
self.Category("");
};
self.cancel = function() {
self.Product(null);
};
}
$(document).ready(function() {
var viewModel = new ProductViewModel();
ko.applyBindings(viewModel);
});
</script>

KnockoutJs mapping JSON to viewmodel

I'm having problem with binding JSON from ASP.net webform webapi to the viewmodel with KnockoutJs. There is no problem with wepapi and mapping to mappedQuickEntries.
Where did I get it wrong? Thanks.
Error:
Error: Unable to parse bindings.
Message: ReferenceError: ItemPartNumb is not defined;
Bindings value: value: ItemPartNumb
View:
<div>
<table border="1" cellpadding="0" cellspacing="0">
<tbody data-bind="foreach: quickEntries">
<tr>
<td data-bind="value: ItemPartNumb"></td>
<td data-bind="value: ItemDescription"></td>
</tr>
</tbody>
</table>
ViewModel:
<script type="text/javascript">
var QuickEntry = function(_itemPartNumb, _itemDescription) {
this.ItemPartNumber = ko.observable(_itemPartNumb);
this.ItemDescription = ko.observable(_itemDescription);
};
function QuickEntriesViewModel () {
var self = this;
self.quickEntries = ko.observableArray([]);
$.ajax({
url: '/DesktopModules/Blah/API/Data/GetTenQuickEntries',
type: 'GET',
dataType: 'json',
success: function (data) {
var mappedQuickEntries = $.map(data, function (item) {
return new QuickEntry(item.ItemPartNumb, item.ItemDescription);
});
self.quickEntries(mappedQuickEntries);
},
statusCode: {
404: function () {
alert('Failed');
}
}
});
};
ko.applyBindings(new QuickEntriesViewModel());
ItemPartNumb vs ItemPartNumber
And you are using the value-binding instead of the text-binding.
http://jsfiddle.net/MizardX/9sqvk/

Resources