How to call a javascript method with knockout - javascript

I am using knockout for binding, and the issue I have is can't seem to know how to call the remove method. I have two class convocation, and vague.
class Convocation {
constructor(sessionId, description)
{
var self = this;
this.ConvocationID = ko.observable(sessionId);
this.ConvDesc = ko.observable(description);
this.Vagues = ko.observableArray();
addVague(start, end) {
this.Vagues.push(new Vague(start, end));
}
removeVague() {
self.Vagues.remove(this)
}
}
class Vague {
constructor(start, end) {
this.startDate = ko.observable(start);
this.endDate = ko.observable(end);
}
}
I initialize my knockout using this viewModel, witch works.
function ViewModel() {
var self = this;
this.Convocations = ko.observableArray();
// Get information
this.Initialize = function () {
$.ajax({
url: "/Convocations/GetConvocationList",
dataType: 'json',
//data: { id: id },
success: function (data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
});
}
}
This is my jquery calling the viewModel once ready.
(function ($) {
// we can now rely on $ within the safety of our "bodyguard" function
$(document).ready(function () {
var vm = new ViewModel();
ko.applyBindings(vm);
vm.Initialize();
});
})(jQuery);
But when it comes to delete a vague, I can't seem to know how to call it this is a snip of my view
<tbody data-bind="foreach: Convocations">
<tr>
<td><Input data-bind="value: $data.ConvocationID"></td>
<td><Input data-bind="value: $data.ConvDesc"></td>
</tr>
<tr>
<td colspan="3">
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: $data.Vagues">
<tr>
<td><span type="date" data-bind="text: $data.startDate"></span></td>
<td><span type="date" data-bind="text: $data.endDate"></span></td>
<td><a href='#' data-bind='click: $parent.removeVague'>Delete</a></td>
</tr>
</tbody>
</table>
If i conver addRemove() to something like this, it use to work, but i can't define this in a class.
this.remove = function () {
self.Vagues.remove(this);
}

I suspect that there may be some confusion around what $data and $parent represents in the html bindings.
for the nested foreach knockout bindings like you have its generally a good idea to give each level its own object name rather than just using $data.
Personally I am still learning the javascript syntax around classes etc, so there is probably a better way of doing the javascript than what I have done.
var data = [{
sessionCode: 1,
desc: 'Convocation 1',
vagues: [{
start: '2020-07-01',
end: '2020-07-30'
}]
}, {
sessionCode: 2,
desc: 'Convocation 2',
vagues: [{
start: '2020-07-02',
end: '2020-07-29'
}]
}];
class Convocation {
constructor(sessionId, description) {
var self = this;
self.ConvocationID = ko.observable(sessionId);
self.ConvDesc = ko.observable(description);
self.Vagues = ko.observableArray();
self.addVague = function addVague(start, end) {
self.Vagues.push(new Vague(start, end));
}
self.removeVague = function removeVague(item) {
self.Vagues.remove(item);
}
}
}
class Vague {
constructor(start, end) {
this.startDate = ko.observable(start);
this.endDate = ko.observable(end);
}
}
function ViewModel() {
var self = this;
self.Convocations = ko.observableArray();
//helper function that mimics the success function of the ajax call to allow loading data
self.processData = function(data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
// Get information
self.Initialize = function() {
$.ajax({
url: "/Convocations/GetConvocationList",
dataType: 'json',
//data: { id: id },
success: function(data) {
for (var i = 0; i < data.length; i++) {
self.Convocations.push(new Convocation(data[i].sessionCode, data[i].desc));
for (var j = 0; j < data[i].vagues.length; j++) {
self.Convocations()[i].addVague(data[i].vagues[j].start, data[i].vagues[j].end);
}
}
}
});
}
}
var vm = new ViewModel();
ko.applyBindings(vm);
//vm.Initialize();
vm.processData(data);
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<table class="table">
<tbody data-bind="foreach: {data: Convocations, as: 'convocation'}">
<tr>
<td>
<input data-bind="value: convocation.ConvocationID" />
</td>
<td>
<input data-bind="value: convocation.ConvDesc" />
</td>
</tr>
<tr>
<td colspan="3">
<div class="panel-body">
<table class="table">
<thead>
<tr>
<th>Start Date</th>
<th>End Date</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach:{data: convocation.Vagues, as: 'vague'}">
<tr>
<td><span type="date" data-bind="text: vague.startDate"></span></td>
<td><span type="date" data-bind="text: vague.endDate"></span></td>
<td><a href='#' data-bind='click: convocation.removeVague'>Delete</a></td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</table>

Related

Javascript calling API array handling with HTML

I am calling a BUS ETA api which it will return a json with ETA and route information. Example as below. I manage to get the first array to show in HTML but without success for the second [1] and third[2]. I manage to see all three ETA with console.log but won't show in HTML.
Any idea?
UPDATE : Created a jsFiddle example.
https://jsfiddle.net/21tk38b9/
BUS ETA API SAMPLE DATA
{
"type": "ETA",
"version": "1.0",
"generated_timestamp": "2021-06-29T16:02:53+08:00",
"data": [
{
"co": "KMB",
"route": "978",
"dir": "I",
"service_type": 1,
"seq": 7,
"dest_tc": "粉嶺(華明)",
"dest_sc": "粉岭(华明)",
"dest_en": "FANLING (WAH MING)",
"eta_seq": 1,
"eta": "2021-06-29T16:11:24+08:00",
"rmk_tc": "",
"rmk_sc": "",
"rmk_en": "",
"data_timestamp": "2021-06-29T16:02:41+08:00"
},
{
"co": "KMB",
"route": "978",
"dir": "I",
"service_type": 1,
"seq": 7,
"dest_tc": "粉嶺(華明)",
"dest_sc": "粉岭(华明)",
"dest_en": "FANLING (WAH MING)",
"eta_seq": 2,
"eta": "2021-06-29T16:28:15+08:00",
"rmk_tc": "原定班次",
"rmk_sc": "原定班次",
"rmk_en": "Scheduled Bus",
"data_timestamp": "2021-06-29T16:02:41+08:00"
},
{
"co": "KMB",
"route": "978",
"dir": "I",
"service_type": 1,
"seq": 7,
"dest_tc": "粉嶺(華明)",
"dest_sc": "粉岭(华明)",
"dest_en": "FANLING (WAH MING)",
"eta_seq": 3,
"eta": "2021-06-29T16:43:15+08:00",
"rmk_tc": "原定班次",
"rmk_sc": "原定班次",
"rmk_en": "Scheduled Bus",
"data_timestamp": "2021-06-29T16:02:41+08:00"
}
]
}
HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Mining Status</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="/src/js/Untitled-4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js" integrity="sha512-qTXRIMyZIFb8iQcfjXWCO8+M5Tbc38Qi5WzdPOYZHIlZpzBHG3L3by84BBBOiRGiEb7KKtAOAs5qYdUiZiQNNQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="/src/css/main.css">
<link rel="stylesheet" href="/src/css/15.css">
<style type="text/css">
.fullscreen {
position: fixed;
overflow-y:fixed;
width: 100%;
}
</style>
</head>
<div id="wrap">
<body>
<div style="
font-size: 100px;
text-align: center;">
<div id="rmk"></div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Route</th>
<th scope="col">ETA</th>
<th scope="col">Remark</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td><div id="route"></div></td>
<td><div id="but"></div>
</td>
<td></td>
</tr>
<tr>
<th scope="row">2</th>
<td></td>
<td><div id="but"></div>
<td></td>
</tr>
<tr>
<th scope="row">3</th>
<td></td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
</body>
</div>
</html>
Javascript
function repeat57() {
$(function() {
$.ajax({
type: "GET",
url: "https://data.etabus.gov.hk/v1/transport/kmb/eta/83B717529F9794BC/978/1",
dataType: "json",
success: function (data) {
console.log(typeof data); // -- Object
var json = data;
for (var i = 0; i < json.data.length; i++) {
var str = json.data[i].eta
if (str !== null ) {
str = str.split("T").pop();
str2 = str.split("+",1).pop();
str3 = str2.replace(/:/g,'');
d = new Date();
datetext = d.toTimeString();
datetext = datetext.split(' ')[0];
datetext = datetext.replace(/:/g,'');
console.log(datetext)
var eta = str3 - datetext;
console.log(eta)
var eta2 = "[ " + eta.toString().slice(0, -2) +" mins,]";
} else {
var remark = json.data[i].rmk_tc
eta2 = remark;
}
console.log(typeof str)
$('#but').html(eta2);
$('#rmk').html(remark);
}
}
});
});
setTimeout(repeat57, 19000);
}
repeat57();
function repeat58() {
$(function() {
$.ajax({
type: "GET",
url: "https://data.etabus.gov.hk/v1/transport/kmb/eta/83B717529F9794BC/978/1",
dataType: "json",
success: function (data) {
var json = data;
console.log(typeof .json)
for (var i = 0; i < json.data.length; i++) {
var str = JSON.parse(json.data[i].route)
if (str !== null ) {
} else {
var remark = json.data[i].rmk_tc
str = remark;
}
console.log(typeof str)
$('#route').html(str);
}
}
});
});
setTimeout(repeat58, 19000);
}
repeat58();
Do you want to be dynamic or are there always only 3 entries?
If there are three entries you could do:
HTML Code:
<head>
<meta charset="utf-8">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<div id="rmk"></div>
<table class="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Route</th>
<th scope="col">ETA</th>
<th scope="col">Remark</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>
<div class="route"></div>
</td>
<td>
<div class="but"></div>
</td>
<td></td>
</tr>
<tr>
<th scope="row">2</th>
<td>
<div class="route"></div>
</td>
<td>
<div class="but"></div>
</td>
<td></td>
</tr>
<tr>
<th scope="row">3</th>
<td>
<div class="route"></div>
</td>
<td>
<div class="but"></div>
</td>
<td></td>
</tr>
</tbody>
</table>
</body>
JavaScript:
function repeat57() {
$(function() {
$.ajax({
type: "GET",
url: "https://data.etabus.gov.hk/v1/transport/kmb/eta/83B717529F9794BC/978/1",
dataType: "json",
success: function(data) {
console.log(data); // -- Object
var json = data;
const buts = $('.but');
for (var i = 0; i < json.data.length; i++) {
var str = json.data[i].eta
if (str !== null) {
str = str.split("T").pop();
str2 = str.split("+", 1).pop();
str3 = str2.replace(/:/g, '');
d = new Date();
datetext = d.toTimeString();
datetext = datetext.split(' ')[0];
datetext = datetext.replace(/:/g, '');
console.log(datetext)
var eta = str3 - datetext;
var eta2 = eta.toString().slice(0, -2) + " mins";
} else {
var remark = json.data[i].rmk_tc
eta2 = remark;
}
$(buts[i]).html(eta2);
}
}
});
});
setTimeout(repeat57, 19000);
}
repeat57();
function repeat58() {
$(function() {
$.ajax({
type: "GET",
url: "https://data.etabus.gov.hk/v1/transport/kmb/eta/83B717529F9794BC/978/1",
dataType: "json",
success: function(data) {
var json = data;
console.log(json)
const routeElements = $('.route');
for (var i = 0; i < json.data.length; i++) {
var str = JSON.parse(json.data[i].route)
if (str !== null) {
} else {
var remark = json.data[i].rmk_tc
str = remark;
}
$(routeElements[i]).html(str);
}
}
});
});
setTimeout(repeat58, 19000);
}
repeat58();
Make sure to change the ids to classes (but, route, etc) and add it to all the rows where it is needed.
And when iterating through the result you pick the correct element via the index.
See the updated jsFiddle: https://jsfiddle.net/sgjx05qf/
This would be a solution if you always know the count of the result.

Deleting Empty Rows/Nodes

I am trying to delete the empty rows in a table. I traversed to those empty rows. But I don't know how to delete that particular node. I tried to traverse to the parent node and delete, but somehow it seems to show error.
empr[e].removeChild(empr[e].rows[et]) I used this inside the for loop
function emptyrows() {
var count = 0;
var empr = document.getElementsByClassName("tide");
var emlen = document.getElementsByClassName("tide").length;
alert(emlen);
for (var e = 0; e < emlen; e++) {
var emtab = empr[e].rows.length;
for (var et = 0; et < emtab; et++) {
if (empr[e].rows[et].innerHTML == "") {
} else {
console.log("Nothing Empty");
}
}
}
}
<table>
<tbody>
<tr>
<td>1</td>
<td>Barry</td>
<td>
<table class="tide">
<tr>50</tr>
<tr>10</tr>
<tr>200</tr>
</table>
</td>
</tr>
<tr>
<td>2</td>
<td>Allen</td>
<td>
<table class="tide">
<tr>50</tr>
<tr></tr>
<tr></tr>
</table>
</td>
</tr>
<tr>
<td>3</td>
<td>Mary</td>
<td>
<table class="tide">
<tr>50</tr>
<tr>20</tr>
<tr></tr>
</table>
</td>
</tr>
</tbody>
</table>
Try the below code, however you need to correct your HTML to be semantic (include inside ). But the code below should give you the general idea on how to proceed:
function emptyrows() {
var tables = document.getElementsByClassName("tide");
for (var i = 0; i < tables.length; i++) {
for (var j = 0; j < tables[i].childNodes.length; j++) {
if (tables[i].childNodes[j].innerHTML === '') {
tables[i].removeChild(tables[i].childNodes[j]);
}
}
}
}
emptyrows();

How do I use themes with jsPDF-AutoTable?

I don't get how I use the themes for jsPDF-AutoTable. . .
This is my Code to generate the PDF:
function tbl1ToPDF(){
var table = tableToJson($('#tbl1').get(0));
var doc = new jsPDF('l','pt','letter',true);
$.each(table, function(i, row){
$.each(row, function(j,cell){
if(i == 0)
{
doc.cell(10,10,150,50,cell,i, 'center');
}
else
{
doc.cell(10,10,150,120,cell,i,'center');
}
});
});
doc.save('Sofort.pdf');
}
And this is my tableToJson function:
function tableToJson(table) {
var data = [];
var headers = [];
for (var i = 0; i < table.rows[0].cells.length; i++) {
headers[i] = table.rows[0].cells[i].innerHTML.toLowerCase().replace(/ /gi, '');
}
data.push(headers);
// go through cells
for (var i = 1; i < table.rows.length; i++) {
var tableRow = table.rows[i];
var rowData = {};
for (var j = 0; j < tableRow.cells.length; j++) {
rowData[headers[j]] = tableRow.cells[j].innerHTML;
}
data.push(rowData);
}
return data;
}
My Table is dynamic. I generate it after pressing a Button but the struct of the Table looks like this:
<h3>Header</h3>
<table id="tbl1">
<thead>
<tr>
<th>Nr</th>
<th>Name</th>
<th>Unit</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>test</td>
<td>test</td>
</tr>
<tr>
<td>2</td>
<td>test</td>
<td>test</td>
</tr>
</tbody>
</table>
<input type="button" onclick="tbl1ToPDF" value="download">
Can you please help me applying a theme to my PDF? I never did this before and I really need help!
Thanks you!
In order to use jsPDF-Autotable plugin you need to call it inside the code like so:
var doc = new jsPDF();
doc.autoTable();
Once you called autoTable, you can apply some option to it like "theme" this way:
doc.autoTable({theme: 'grid'});
For example, I have an HTML table (3 columns) with id = "table-report-p2p"
I get the data from it with autoTableHtmlToJson() and then I applied some options.
This is the code that works for me:
var elem = document.getElementById("table-report-p2p");
var res = doc.autoTableHtmlToJson(elem);
doc.autoTable(res.columns, res.data, {
theme: 'grid',
startY: 150,
margin: {horizontal: 10},
pageBreak: 'auto',
rowPageBreak: 'avoid',
columnStyles: {0: {cellWidth: 35, minCellHeight: 53},1: {cellWidth: 70},2: {cellWidth: 84}}
});

Argument given to addRows must be either a number or an array - Google Charts

**Controller Code : **
$http({method: 'GET',
url: '/proj_prof_table',
params: {id: id}
}).success(function(response)
{
$scope.data = response;
$scope.emp_id = [];
$scope.emp_name = [];
$scope.billing_status = [];
$scope.mgr = [];
$scope.mgr_id = [];
$scope.stdt = [];
for(i in $scope.data)
{
$scope.emp_id.push($scope.data[i].Emp_ID);
$scope.emp_name.push($scope.data[i].Emp_Name);
$scope.billing_status.push($scope.data[i].Billing_Status);
$scope.mgr.push($scope.data[i].Manager);
$scope.mgr_id.push($scope.data[i].Mgr_ID);
$scope.stdt.push($scope.data[i].Start_Date);
}
});
// Get client timeline
// Prepare Data
$http({method: 'GET',
url: '/proj_prof_client_timeline',
params: {id: clid}
}).success(function(response)
{
$scope.data = response;
alert($scope.data);
$scope.project = [];
$scope.stdt = [];
$scope.endt = [];
$scope.x = [];
for(i in $scope.data)
{
$scope.x[i] = [];
$scope.x[i].push($scope.data[i].Proj_Name);
$scope.x[i].push($scope.data[i].Start_Date);
$scope.x[i].push($scope.data[i].End_Date);
}
alert($scope.x[0]);
});
drawChart($scope.x);
}
//time line chart
google.charts.load('current', {'packages':['timeline']});
google.charts.setOnLoadCallback(drawChart);
function drawChart(param) {
//Chart code
var container = document.getElementById('timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Projects' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows(param);
chart.draw(dataTable);
}
the code above throws "Argument given to addRows must be either a number or an array"
besides $scope.x being an 2D array
Is there anyother way in which i could define $scope.x as a [[ele,ele,ele],[ele,ele,ele],[ele,ele,ele]] array to pass it as an parameter to addrows()
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope) {
$scope.emplist = [
{empname:'samudrala',empsalary:'4.5 - pam',empid:'Emp - 450'},
{empname:'soujanya',empsalary:'4.5 - pam',empid:'Emp - 451'},
{empname:'jai',empsalary:'4.5 - pam',empid:'Emp - 455'},
{empname:'Raamu',empsalary:'4.5 - pam',empid:'Emp - 459'}
];
$scope.addItem = function(){
$scope.emplist.push({'empname':$scope.empname,'empsalary':$scope.empsalary,'empid':$scope.empid});
$scope.empname = '';
$scope.empsalary = '';
$scope.empid = '';
}
$scope.remItem = function(item){
$scope.emplist.splice(item,1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table style="width:100%;">
<tr height="25" style=" background: #99ff00;">
<th width="5%"></th>
<th width="40%">EMP Name</th>
<th width="30%">EMP Salary</th>
<th width="">EMP ID</th>
<th width=""></th>
</tr>
<tr height="25" ng-repeat="x in emplist">
<td style="text-align: center;">{{$index}}</td>
<td style="text-align: center; ">{{x.empname}}</td>
<td style="text-align: center;">{{x.empsalary}}</td>
<td style="text-align: center;">{{x.empid}}</td>
<td style="text-align: center;"><button ng-click="remItem($index);" style="background:#00ffff; border:0px;">× Remove</button></td>
</tr>
<tr height="25">
<td><button ng-click="addItem();" style="background: #00ffff; border:0px; width:100%; height:100%;">Add</button></td>
<td style="padding:2px;"><input type="text" ng-model="empname" style="width:100%;" ></td>
<td style="padding:2px;"><input type="text" ng-model="empsalary" style="width:100%;" ></td>
<td style="padding:2px;"><input type="text" ng-model="empid" style="width:100%;" ></td>
</tr>
</table>
</div>

Knockout.js - Sum table, add row and fill the table with AJAX

Im using this table to add materials and using Knockoutjs-3.4.0.js to add row and to sum it. My problem is when i try to edit the code i want to populate the table with a AJAX request. The problem is that i don't know how to fill the table with the AJAX response.
If i use the code below i get this error:
ReferenceError: Unable to process binding "click: function (){return
addMaterial }" Message: Can't find variable: addMaterial
<table class="table table-bordered">
<thead>
<tr>
<th>Moment</th>
<th>Antal </th>
<th>Kostnad</th>
<th>Totalt</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: materials">
<tr>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: quantity" /></td>
<td><input data-bind="value: rate" /></td>
<td data-bind="text: formattedTotal"></td>
<td></td>
</tr>
<tfoot>
<tr>
<th colspan="2"><button class="fa fa-plus btn-success" data-bind="click: addMaterial, enable: materials().length < 20"> Lägg till rad</button></th>
<th class="text-right">Totalt</th>
<th class="text-center"><span data-bind="text: totalSurcharge().toFixed(0)"></span></th>
<th> </th>
</tr>
<tr id="momsRow" class="hidden">
<th colspan="3" class="text-right">Moms</th>
<th class="text-center"><span data-bind="text: totalVat().toFixed(1)"></span></th>
<th> </th>
</tr>
<tr id="byggmomsRow" class="hidden">
<th colspan="3" class="">Omvänd byggmoms</th>
<th class="text-center"></th>
<th> </th>
</tr>
<tr>
<th colspan="3" class="text-right">Totalt:</th>
<th class="text-center"><span data-bind="text: totalPlusVat().toFixed(2)"></span></th>
<th> </th>
</tr>
</tfoot>
</tbody>
</table>
The knockout.js code:
/*------------- Load rows ------------- */
function LoadRows() {
var self = this;
self.materials = ko.observableArray([]);
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
self.materials(data);
})
}
//ko.applyBindings(new dealModel());
ko.applyBindings(new LoadRows());
/*------------- Sum table ------------- */
function addMaterial() {
this.name = ko.observable("");
this.quantity = ko.observable("");
this.rate = ko.observable(0);
this.formattedTotal = ko.computed(function() {
return this.rate() * this.quantity();
}, this);
}
function documentViewModel(){
var self = this;
//create a materials array
self.materials = ko.observableArray([
new addMaterial()
]);
// Computed data
self.totalSurcharge = ko.computed(function() {
var total = 0;
for (var i = 0; i < self.materials().length; i++)
total += self.materials()[i].formattedTotal();
return total;
});
// add VAT(moms 25%) data
self.totalVat = ko.computed(function() {
var totalWithVat = 0;
for (var i = 0; i < self.materials().length; i++)
totalWithVat += self.materials()[i].formattedTotal();
totalWithVat = totalWithVat*0.25;
return totalWithVat;
});
// Totalt with VAT(moms 25%) data
self.totalPlusVat = ko.computed(function() {
var totalWithVat = 0;
for (var i = 0; i < self.materials().length; i++)
totalWithVat += self.materials()[i].formattedTotal();
totalWithVat = totalWithVat*1.25;
return totalWithVat;
});
// Operations
self.addMaterial = function() {
self.materials.push(new addMaterial());
}
self.removeMaterial = function(material) { self.materials.remove(material) }
}
ko.applyBindings(new documentViewModel());
/*------------- Sum table END ------------- */
There is a correct json format on the AJAX request.
[{"name":"Moment 1","quantity":"1","rate":"10","formattedTotal":"10"},{"name":"Moment 2","quantity":"2","rate":"20","formattedTotal":"40"}]
$.ajax({
url: "/json/tender_offer_edit_moment_json.asp",
type: "GET",
dataType: "json",
success: function (data) {
console.log(data);
alert(data);
//new addMaterial(data);
new addMaterial(data);
}
});
JsFiddle
First of all, you call ko.applyBindings() twice and to whole page,
it is not suitable in your situation:
To load the initial data you can do smth like this:
var vm = new documentViewModel();
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
vm.materials(data);
})
ko.applyBindings(vm);
and delete this lines:
function LoadRows() {
var self = this;
self.materials = ko.observableArray([]);
$.getJSON("/json/tender_offer_edit_moment_json.asp", function(data) {
self.materials(data);
})
}
//ko.applyBindings(new dealModel());
ko.applyBindings(new LoadRows());

Categories

Resources