Table not updating (tableSorter with Knockout ) - c#

I writing code for updating table on every 5 sec.
I have used table sorter with knocknot....
the data is been loading perfect on first iteration after that the data is append to previous data..instead of updating..
Here is my code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<script src="scripts/jquery-1.7.1.min.js"></script>
<script src="scripts/knockout-3.4.0.js"></script>
<script src="scripts/knockout.mapping-latest.js"></script>
<link href="scripts/tableSorter/theme.blue.css" rel="stylesheet" />
<script src="scripts/tableSorter/jquery.tablesorter.js"></script>
<script src="https://cdn.jsdelivr.net/tablesorter/2.17.4/js/widgets/widget-scroller.js"></script>
<script src="scripts/tableSorter/jquery.tablesorter.widgets.js"></script>
<title>Dynamic Data from sqlData</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" data-bind="value: vm.AccountArray().length" />
<table border="1">
<thead>
<tr>
<th>accountNumber
</th>
<th>accountName
</th>
<th>account balance
</th>
</tr>
</thead>
<tbody data-bind="foreach: { data: AccountArray, as: 'Account' }">
<tr>
<td data-bind="text: Account.AccountNumber"></td>
<td data-bind="text: Account.AccountName"></td>
<td data-bind="text: Account.AccountBalance"></td>
</tr>
</tbody>
</table>
</div>
</form>
<script>
function Account(accountNumber, accountName, accountBalance) {
this.AccountNumber = ko.observable(accountNumber);
this.AccountName = ko.observable(accountName);
this.AccountBalance = ko.observable(accountBalance);
}
var viewModel;
var table;
var hg;
var vm = new function () {
this.amount = ko.observableArray();
this.AccountArray = ko.observableArray();
}
$(function () {
table = $("table").tablesorter({
theme: 'blue',
widthFixed: true,
widgets: ['zebra', 'stickyHeaders', 'filter', 'scroller', 'resizable'],
widgetOptions: {
reorder_axis: 'x', // 'x' or 'xy'
reorder_delay: 100,
reorder_helperClass: 'tablesorter-reorder-helper',
reorder_helperBar: 'tablesorter-reorder-helper-bar',
reorder_noReorder: 'reorder-false',
reorder_blocked: 'reorder-block-left reorder-block-end',
reorder_complete: completed,// callback
scroller_height: 300,
scroller_barWidth: 17
}
});
$('.tablesorter-scroller-table').css({
height: '',
'max-height': '300px'
});
function completed() {
}
function AutoReload() {
$.ajax({
type: "POST",
url: "Dynamic_Data_Creation.aspx/GetDataAjax",
contentType: "application/json; charset=utf-8",
data: {},
dataType: "json",
success: function (response) {
hg = $('.tablesorter-scroller-table').prop("scrollTop");
vm.AccountArray.removeAll();
vm.AccountArray().length = 0;
vm.AccountArray.valueHasMutated();
ko.mapping.fromJSON(response.d, null, vm.AccountArray); // updata response data
$("table").trigger("update");
$('.tablesorter-scroller-table').prop("scrollTop", hg); // updating the scroll position to table
$('.tablesorter-scroller-table').css("scrollTop", $('.tablesorter-scroller-table').prop("scrollTop"));
setTimeout(function () { AutoReload(); }, 5000); //reload on every 5 seconds.
},
failure: function (response) {
alert(response.d);
}
});
}
AutoReload();
});
ko.applyBindings(vm);
</script>
</body>
</html>

I don't think you're getting any benefit from Knockout. You're having to manipulate the DOM to synchronize it with your data. That's what Knockout is supposed to do.
A relatively simple custom binding handler will take care of this for you.
ko.bindingHandlers.sortable = {
init: function(el, va) {
var arg = ko.unwrap(va());
$(el).tablesorter(arg.options);
arg.data.subscribe(function() {
$(el).trigger('update');
});
}
};
The binding looks like
<table data-bind="sortable: {data: accountArray, options: tableOptions}" border="1">
Here's a fiddle that demonstrates adding elements, clearing the array, and setting the whole array at once.

Related

DataTable doesn't effect on the table

I am using DataTable library in MVC, but it doesn't work
this is the view Part
<table id="example" class="display" style="width:100%">
<thead>
<tr>
<th>Id</th>
<th>Phone</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</thead>
<tbody>
</tbody>
<tfoot>
<tr>
<th>Id</th>
<th>Phone</th>
<th>FirstName</th>
<th>LastName</th>
</tr>
</tfoot>
</table>
<script type="text/javascript">
//$(document).ready(function () {
// $('#example').DataTable();
//})
$(document).ready(function () {
GetEmployeeRecord();
})
var GetEmployeeRecord = function () {
$.ajax({
type: "Get",
url: "/BasicInfo/GetCustomers",
success: function (response) {
alert("success");
BindDataTable(response);
},
error: function () {
alert("error");
}
})
}
var BindDataTable = function (response) {
$("#example").DataTable({
"aaData": response,
"aoColumns": [
{ "mData": "Id" },
{ "mData": "Phone" },
{ "mData": "FirstName" },
{ "mData": "lastName" }
]
});
}
and this is Controller Part
public JsonResult GetCustomers()
{
SalonEntities db = new SalonEntities();
List<Customer> CustomerList = db.Customers.OrderByDescending(a => a.ID).ToList();
return Json(CustomerList , JsonRequestBehavior.AllowGet);
}
although the CustomerList in controller is loaded but it returns to the view it enters the error section of jquery
what could be the problram
The ajax call to your controller failed. To debug this, you can do two things:
Alert the error
Remove the (dobule quote) " to alert the actual error.
error: function () {
alert(error);
}
You will most probably be able to see it in developer tools in your console.
Check the network tab
In your network tab, you'll see the error (4XX, 5XX) or something like that with some extra information (if you are lucky).
If no more information is there and you have an error 500, you need to check the exception in your backend code.

get data from aspx.cs page in angularJS?

I am new to angularJS even this client side coding.Started for interest and exploring it happily.
I just tried to follow an example # Navigational Menu
Have tied to do it from binding the data from server side.its not working. need help ..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using System.Data;
namespace AngularJS
{
public partial class AngularJSTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static DataTable A()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "A");
table.Rows.Add("20/05/2012", "B");
table.Rows.Add("20/05/2012", "C");
return table;
}
[WebMethod]
public static DataTable B()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "P");
table.Rows.Add("20/05/2012", "Q");
table.Rows.Add("20/05/2012", "R");
return table;
}
[WebMethod]
public static DataTable C()
{
DataTable table = new DataTable();
table.Columns.Add("date", typeof(string));
table.Columns.Add("text", typeof(string));
table.Rows.Add("20/05/2012", "X");
table.Rows.Add("20/05/2012", "Y");
table.Rows.Add("20/05/2012", "Z");
return table;
}
}
}
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="AngularJSTest.aspx.cs"
Inherits="AngularJS.AngularJSTest" %>
<!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>
<link href="Styles/style.css" rel="stylesheet" type="text/css" />
<link href="Styles/css.css" rel="stylesheet" type="text/css" />
<script src="Scripts/angular.min.js" type="text/javascript"></script>
<script>
myApp.factory('getProductService', function ($http, $q) {
function getProduct(url) {
var deferred = $q.defer();
$http({ method: 'GET', url: url })
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
console.error('Error occurred trying to get the products: ', error);
deferred.reject(error);
});
return deferred.promise;
}
return {
purchases: function () {
var url = 'AngularJSTest.aspx/A'
return getProduct(url);
},
sale30Days: function () {
var url = 'AngularJSTest.aspx/B'
return getProduct(url);
},
saleProducts: function () {
var url = 'AngularJSTest.aspx/C'
return getProduct(url);
}
};
});
myApp.controller('ProductsController', function ($scope, getProductService) {
$scope.purchase = getProductsService.purchases();
$scope.sale30Day = getProductsService.sale30Days();
$scope.saleProduct = getProductsService.saleProducts();
});
</script>
<style>
body
{
font: 12px arial, helvetica, sans-serif;
}
h2
{
font-size: 16px;
}
table
{
margin: 20px 0;
border-collapse: collapse;
}
th, td
{
border: 1px solid #ccc;
padding: 2px;
}
a.active
{
color: red;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div ng-app="myApp">
<nav class="{{active}}" ng-init="active='home'">
Purchases
Products on sale
Last 30 days sales
</nav>
<div id="tab1" class="tabContent selected" ng-controller="PurchasesCtrl" ng:show="active == 'home'">
<h2>
Purchases:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="purchase in purchases.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{purchase.date}}
</td>
<td>
{{purchase.text}}
</td>
</tr>
</table>
</div>
<div id="tab2" class="tabContent selected" ng-controller="SaleProductsCtrl" ng:show="active == 'projects'">
<h2>
Sale products:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="saleProduct in saleProducts.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{saleProduct.date}}
</td>
<td>
{{saleProduct.text}}
</td>
</tr>
</table>
</div>
<div id="tab3" class="tabContent selected" ng-controller="Sale30DaysCtrl" ng:show="active == 'services'">
<h2>
Sale 30 days:</h2>
<table cellspacing="0">
<tr class="first">
<th class="first">
Date
</th>
<th>
Description
</th>
</tr>
<tr ng-repeat="sale30Day in sale30Days.data" ng-class-odd="'odd'" ng-class-even="'even'"
ng-class="{'last':$last}">
<td class="first">
{{sale30Day.date}}
</td>
<td>
{{sale30Day.text}}
</td>
</tr>
</table>
</div>
</div>
</form>
</body>
</html>
Focusing strictly on the front end I would recommend making a single service for getting Purchases, SalesProducts, Sale30Days for ex:
myApp.factory('getProductService', function ($http, $q) {
function getProduct(url) {
var deferred = $q.defer();
$http({method: 'GET', url: url})
.success(function (data) {
deferred.resolve(data);
})
.error(function (error) {
console.error('Error occurred trying to get the products: ', error);
deferred.reject(error);
});
return deferred.promise;
}
return {
purchases: function () {
var url = 'yourURLPurchases'
return getProduct(url);
},
sale30Days: function () {
var url = 'yourURLSale30Days'
return getProduct(url);
},
saleProducts: function () {
var url = 'yourURLSaleProducts'
return getProduct(url);
}
};
});
Now you can use Dependancy Injection to inject this service into whatever controller needs to get data.
For example your purchases controller:
myApp.controller('PurchasesController', function($scope, getProductService) {
$scope.purchases = getProductsService.purchases();
});
Sale30Days:
myApp.controller('Sale30Days', function($scope, getProductService) {
$scope.sale30Days = getProductsService.sale30Days();
});
However looking at an even higher level of functionality all three of these controllers are doing a similar function - serving products.
So i would recommend refactoring to an even higher level just having a single ProductsController:
myApp.controller('ProductsController', function($scope, getProductService) {
$scope.purchases = getProductsService.purchases();
$scope.sale30Days = getProductsService.sale30Days();
$scope.saleProducts = getProductsService.saleProducts();
});
In this way you can share the potential functions you will need to calculate attributes of the products - prices, tax, amounts - all within one single controller.
Now you can bind the data properly.

Issues rendering DataTables.net in MVC partial view after adding JSON calls

I'm trying to use datatables and jeditable for my project to render an editable table on the screen. This is displayed in a partial view that is called by the index. However, when I try to load it, it loads shows the html of the page on the screen instead of rendering it. Can someone tell me what I'm doing wrong to fix this?
Here is my partial view:
<script type="text/javascript" src="../../Scripts/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../../Scripts/FixedColumns.min.js"></script>
<script type="text/javascript" src="../../Scripts/jquery.dataTables.js"></script>
<script type ="text/javascript" src="../../Scripts/jquery.jeditable.mini.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function () {
var oTable1 = $('#myDataTable').dataTable({
"bServerSide": true,
"sAjaxSource": '/Home/PartialView',
"fnDrawCallback": function () {
$('#myDataTable tbody td:nth-child(2)').editable('/Home/Write/', {
"callback": function (sValue, y) {
oTable1.fnDraw();
},
});
}
});
})
</script>
<table id ="myDataTable" class="display">
<thead>
<tr>
<th>Analysis ID</th>
<th>Name</th>
<th>Time</th>
<th>Sample Type</th>
<th>Grade</th>
<th>Product ID</th>
</thead>
<tbody>
</tbody>
</table>
Call to the partial view in my index:
#if(ViewBag.SearchKey != null)
{
#Html.Action("PartialAnalysis", "Home", (string)ViewBag.SearchKey)
{Html.RenderAction("PartialView", "Home", (string)ViewBag.SearchKey);}
}
My Controller:
public ActionResult PartialView(jQueryDataTableParamModel param, string Search)
{
PartialModel D = new PartialModel();
IEnumerable<PartialModel> model = D.SlagList;
D.ViewDataPull(Search);
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = D.List.Count(),
iTotalDisplayRecords = D.List.Count(),
aaData = D.List
},
JsonRequestBehavior.AllowGet);
}

Jquery Post not reaching MVC Controller

Apologies if this i trivial, i have read many other comments and still cannot see what is wrong. I have done a few tutorials and they seem to work ok, so I am really missing something simple.
I have a basic 'remove' link that i want to do a JQuery Post back to the controller to remove an item from the database and then update the view.
My View / Javascript:
<script type="text/javascript">
$(function () {
$(".RemoveLink").click(function () {
var id = $(this).attr("data-id");
if (id != '') {
$.post("#Url.Content("~/Agent/Remove")", { "id": id }, function (data) { alert('Here i am'); });
}
});
});
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<a href="#" class="RemoveLink" data-id="#item.ID" >Remove</a>
</td>
</tr>
}
My Controller:
[HttpPost]
public ActionResult Remove(int id)
{
return Json(new { Data = "true" });
}
Any assistance will be great.
Use #Url.Action("Remove", "Agent") instead.
#Url.Content("...") is used to locate any static content of the site.
Cheers
Below code works well.
#foreach (var item in Model.Object) {
<tr id="row-#item.ID">
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<input type="button" class="RemoveLink" id="#item.ID" Value="Remove" />
</td>
</tr>
}
<script type="text/javascript" language="javascript">
$(document).ready(function () {
$('.RemoveLink').live("click", function () {
Remove($(this));
});
});
function Remove(_this) {
var Id= $(_this).attr('id');
$.ajax({
type: 'POST',
url: '#Url.Action("Remove", "Agent")',
data: "{id: '" + Id + "'}",
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
//do something here......
},
error: function () {
}
});
}
</script>

Jquery datepicker - only every second click event fires

I have a page with a jqueryui datepicker control.
On each day selection, I post with ajax to a web method to do some server side data population to fill the drop down box which is beneath the calendar control.
I used this code for two pages already, first works perfect, but am having issues with this one.
The first time I select a date, the event fires fine, second time nothing happens, then the next click works fine again. So the event only fires on every second click, be it the same date or a different date.
I added an input control to capture date selection, which works fine on each select.
What bugs me now is, If I add an alert inside my select jquery function, it fires every time, take it out and I have this issue again.
Thanks
Markup:
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="Site.Master" CodeBehind="calendartest.aspx.cs" Inherits="Test.calendartest" EnableEventValidation="false" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">
$(function() {
$('#datepicker').datepicker({
onSelect: function(dateStr, inst) {
document.getElementById('<%= hSelectedDate.ClientID %>').value = dateStr;
var hubid = 2;
$('#<%=ddlAvailableTimes.ClientID %>').empty().append('<option selected="selected" value="0">Loading...</option>');
$.ajax
({
type: "POST",
url: "UserCP.aspx/PopulateAvailableTimeSlots",
data: ("{date:'" + dateStr + "', hubid:'" + hubid + "'}"),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnTimeSlotsPopulated
});
$("#datepicker_value").val(dateStr);
}
});
});
function OnTimeSlotsPopulated(response) {
PopulateControl(response.d, $("#<%=ddlAvailableTimes.ClientID %>"));
}
function PopulateControl(list, control) {
if (list.length > 0) {
control.removeAttr("disabled");
control.empty().append('<option selected="selected" value="0">--Select Time Slot--</option>');
$.each(list, function() {
control.append($("<option></option>").val(this['Value']).html(this['Text']));
});
}
else {
$("#<%=ddlAvailableTimes.ClientID%>").attr("disabled", "disabled");
control.empty().append('<option selected="selected" value="0">--No Slots Available--<option>');
}
}
</script>
<input id="hSelectedDate" type="hidden" value="" runat="server" />
<input id="hfHub" type="hidden" value="" runat="server" />
<table style="width: 290px" cellpadding="0" cellspacing="0"
align="center">
<tr>
<td align="center">
<div id="datepicker">
</div>
<asp:DropDownList ID="ddlAvailableTimes" runat="server" Width="192px" Enabled="false">
<asp:ListItem Text="--Select Time Slot--" Value="0"></asp:ListItem>
</asp:DropDownList>
<input id="datepicker_value" />
</td>
</tr>
</table>
</asp:Content>
Server Side:
public partial class calendartest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
[WebMethod]
public static ArrayList PopulateAvailableTimeSlots(string date, string hubid)
{
ArrayList list = new ArrayList();
//Do stuff here
return list;
}
}
HTML Output:
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
<link href="css/master.css" rel="stylesheet" type="text/css" />
<link href="themes/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<link href="themes/jquery-ui-1.8.20.custom.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/Scripts/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery-ui-1.8.20.custom.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.core.js"></script>
<script type="text/javascript" src="/Scripts/jquery.ui.datepicker.js"></script>
<title>Test</title>
</head>
<body>
<form name="aspnetForm" method="post" action="calendartest.aspx" id="aspnetForm">
<script type="text/javascript">
$(function() {
$('#datepicker').datepicker({
onSelect: function(dateStr, inst) {
document.getElementById('ctl00_MainContent_hSelectedDate').value = dateStr;
var hubid = 2;
$('#ctl00_MainContent_ddlAvailableTimes').empty().append('<option selected="selected" value="0">Loading...</option>');
$.ajax
({
type: "POST",
url: "UserCP.aspx/PopulateAvailableTimeSlots",
data: ("{date:'" + dateStr + "', hubid:'" + hubid + "'}"),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnTimeSlotsPopulated
});
$("#datepicker_value").val(dateStr);
}
});
});
function OnTimeSlotsPopulated(response) {
PopulateControl(response.d, $("#ctl00_MainContent_ddlAvailableTimes"));
}
function PopulateControl(list, control) {
if (list.length > 0) {
control.removeAttr("disabled");
control.empty().append('<option selected="selected" value="0">--Select Time Slot--</option>');
$.each(list, function() {
control.append($("<option></option>").val(this['Value']).html(this['Text']));
});
}
else {
$("#ctl00_MainContent_ddlAvailableTimes").attr("disabled", "disabled");
control.empty().append('<option selected="selected" value="0">--No Slots Available--<option>');
}
}
</script>
<input name="ctl00$MainContent$hSelectedDate" type="hidden" id="ctl00_MainContent_hSelectedDate" />
<input name="ctl00$MainContent$hfHub" type="hidden" id="ctl00_MainContent_hfHub" />
<table style="width: 290px" cellpadding="0" cellspacing="0" align="center">
<tr>
<td align="center">
<div id="datepicker">
</div>
<select name="ctl00$MainContent$ddlAvailableTimes" id="ctl00_MainContent_ddlAvailableTimes" disabled="disabled" style="width:192px;">
<option selected="selected" value="0">--Select Time Slot--</option>
</select>
<input id="datepicker_value" />
</td>
</tr>
</table>
</form>
</body>
</html>

Categories