Save Data with KnocloutJS viewmodel to server - json

I want to save my ViewModel to my SQL server. The standard knockout ko.toJSON(viewModel) keeps giving me an undefined error, so after some digging i found this Question, but still keeps giving me undefined.
Here is the code for my viewmodel, this is just a currency conversion table that gets the Conversion Rate between 2 currencies.
//ko Event Handler for datepicker.js
ko.bindingHandlers.datepicker = {
init: function (element, valueAccessor, allBindingsAccessor) {
//initialize datepicker with some optional options
var options = allBindingsAccessor().datepickerOptions || {};
$(element).datepicker(options).on("changeDate", function (ev) {
var observable = valueAccessor();
observable(ev.date);
});
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
$(element).datepicker("setValue", value);
}
};
//Currency Model Definition
var currency = function (data) {
var self = this;
self.DateCreated = ko.observable(formatJsonDate(data.DateCreated));
self.CurrencyFrom = ko.observable(data.CurrencyFrom);
self.CurrencyTo = ko.observable(data.CurrencyTo);
self.ConversionRate = ko.observable(data.ConversionRate);
//Yhoo Finance API
ko.computed(function () {
var from = self.CurrencyFrom(),
to = self.CurrencyTo();
if (!from || !to) {
self.ConversionRate("N/A");
return;
}
getRate(from, to).done(function (YahooData) {
console.log("got yahoo data for [" + from + "," + to + "]: ", YahooData);
self.ConversionRate(YahooData.query.results.row.rate);
});
});
}
var NewDate = new Date().getFullYear() + '-' + ("0" + (new Date().getMonth() + 1)).slice(-2) + '-' + new Date().getDate();
var CurrencyModel = function (Currencies) {
var self = this;
self.Currencies = ko.observableArray(Currencies);
self.AddCurrency = function () {
self.Currencies.push({
DateCreated: NewDate,
CurrencyFrom: "",
CurrencyTo: "",
ConversionRate: ""
});
};
self.RemoveCurrency = function (Currency) {
self.Currencies.remove(Currency);
};
self.Save = function () {
$.ajax({
url: "#",
contentType: 'application/json',
data: ko.mapping.toJSON(CurrencyModel),
type: "POST",
dataType: 'json',
success: function (data) {
//I get undefined....
alert(ko.mapping.toJSON(CurrencyModel));
},
error: function (data) { alert("error" + data); }
});
}
$.ajax({
url: "CurrencyConfiguration.aspx/GetConfiguredCurrencies",
data: '{}',
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "JSON",
timeout: 10000,
success: function (Result) {
// callback(Result);
var MappedCurrencies =
$.map(Result.d,
function (item) {
getRate(item.CurrencyFrom, item.CurrencyTo);
return new currency(item);
}
);
self.Currencies(MappedCurrencies);
},
error: function (xhr, status) {
alert(status + " - " + xhr.responseText);
}
});
};
function formatJsonDate(jsonDate) {
var FormatDate = new Date(parseInt(jsonDate.substr(6)));
var Output = FormatDate.getFullYear() + '-' + ("0" + (FormatDate.getMonth() + 1)).slice(-2) + '-' + FormatDate.getDate();
return (Output);
};
function getRate(from, to) {
return $.getJSON("http://query.yahooapis.com/v1/public/yql?q=select%20rate%2Cname%20from%20csv%20where%20url%3D'http%3A%2F%2Fdownload.finance.yahoo.com%2Fd%2Fquotes%3Fs%3D" + from + to + "%253DX%26f%3Dl1n'%20and%20columns%3D'rate%2Cname'&format=json&callback=?");
}
function callback(data) {
if (viewModel) {
// model was initialized, update it
ko.mapping.fromJS(data, viewModel);
} else {
// or initialize and bind
viewModel = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
}
}
$('#Date').datepicker();
$(document).ready(function () {
var VM = new CurrencyModel();
ko.applyBindings(VM);
})

data: ko.mapping.toJSON(CurrencyModel)
You are trying to JSONify the definition not the actual instance

Isn't the method that you want to use:
ko.toJSON
rather than off the mapping object?

Related

My site doesn't work after the update Chrome 83

So, I have website on ext.net 1.7 (last version), and after updates my site doesn't works. The Chrome-console shows no errors. It's just no worked. But it worked in previous versions of Chrome.
WebConsoleErrors
I read about change in Chrome but found nothing the problem.
Does anyone know what the problem is?
try this
(function () {
function isChromium() {
var isChromium = window.chrome;
var winNav = window.navigator;
var isIOSChrome = winNav.userAgent.match("CriOS");
if (isIOSChrome)
return true;
else if (isChromium !== null && typeof isChromium !== "undefined")
return true;
else
return false;
}
if (isChromium()) {
Ext.override(Ext.data.Connection, {
doFormUpload: function (o, ps, url) {
var me = this;
var doc = document;
var form = Ext.getDom(o.form);
var hiddens = [];
var hd;
Ext.iterate(Ext.urlDecode(ps, false), function (k, v) {
hd = doc.createElement('input');
Ext.fly(hd).set({
type: 'hidden',
value: v,
name: k
});
form.appendChild(hd);
hiddens.push(hd);
});
var formData = new FormData(form);
function successCallback(data) {
var r = {
responseText: '',
responseXML: null,
argument: o.argument
};
if (data) {
var match = /<textarea>(.+)<\/textarea>/i.exec(data);
if (match != null && match.length >= 2) {
r.responseText = match[1];
} else {
r.responseText = data;
}
r.responseXML = $.parseXML(data);
}
me.fireEvent("requestcomplete", me, r, o);
function runCallback(fn, scope, args) {
if (Ext.isFunction(fn)) {
fn.apply(scope, args);
}
}
runCallback(o.success, o.scope, [r, o]);
runCallback(o.callback, o.scope, [o, true, r]);
}
$.ajax({
type: 'POST',
url: url,
data: formData,
processData: false,
contentType: false,
success: successCallback,
error: function () {
console.log(arguments);
}
});
Ext.each(hiddens, function (h) {
Ext.removeNode(h);
});
}
})
}
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
You should insert current script in body for all pages after load extjs

Database mapping in Leaflet with (JSON, AJAX)

I get this JSON from DeviceNewController
public function index(Request $request)
{
$device_new = Device_new::with(['device']);
return Device_new::all()->toJson();
}
And when I wrote AJAX in view blade, it show me data from DB in console.
<script>
var newdev = new XMLHttpRequest();
newdev.open('GET', '/devices_new');
newdev.onload = function() {
console.log(newdev.responseText);
};
newdev.send();
</script>
But I need to pass it in Leaflet script and write all data on map (coordinates, markers, device info)
When I set all in one script, there is no data in console, I can not fix it.
var newdev = new XMLHttpRequest();
newdev.open('GET', '/devices_new');
newdev.onload = function() {
var coordinates = newdev.responseText;
for (var i=0; i < coordinates.length; i++) {
if(coordinates[i].x && coordinates[i].y){
var marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: "+coordinates[i].device_type+'<br>' + "Time: "+coordinates[i].datetime)
.addTo(map);
}
};
};
newdev.send();
Did i make a mistake somewhere, is this correct???
You miss understood Ajax. Ajax is a function from JQuery, a JS library.
The ajax() method is used to perform an AJAX (asynchronous HTTP) request.
You have to add the JQuery library to your source, then you can create a Ajax call.
https://www.w3schools.com/jquery/ajax_ajax.asp
$.ajax({url: "/devices_new", success: function(result){
//result = JSON.parse(result); // If your result is not a json Object.
var coordinates = result;
for (var i=0; i < coordinates.length; i++) {
if(coordinates[i].x && coordinates[i].y){
var marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: "+coordinates[i].device_type+'<br>' + "Time: "+coordinates[i].datetime)
.addTo(map);
}
}
},
error: function(xhr){
alert("An error occured: " + xhr.status + " " + xhr.statusText);
}});
});
I make it on this way, and its working.
<script>
$(document).ready(function() {
$.ajax({
/* the route pointing to the post function */
url: '/device_new',
type: 'GET',
data: {
message: $(".getinfo").val()
},
dataType: 'json',
/* remind that 'data' is the response of the AjaxController */
success: function(data) {
var coordinates = data;
for (var i = 0; i < coordinates.length; i++) {
if (coordinates[i].x && coordinates[i].y) {
var marker = L.marker([coordinates[i].x, coordinates[i].y])
.bindPopup("Device: " + coordinates[i].device_type + '<br>' + "Time: " + coordinates[i].datetime)
.addTo(map);
}
}
console.log(data);
},
error: function(data) {
console.log(data);
}
});
});
</script>

Calculate the json's value then show in html

I have a json array:
[{"value": "1"},{"value": "2"},{"value": "3"},{"value": "4"},{"value": "5"},{"value": "6"}]
My code is :
$.ajax({
url: "120.58.243.11:8080/needCal/myJson.json",
dataType: 'json',
success: function(data) {
var items = [];
$.each(data, function(key, value) {
items.push("<tr>");
items.push("<td id=''" + key + "''>" + value.value+ < /td>");
items.push("<td id=''" + key + "''>" + total of values + < /td>");
items.push("</tr>");
});
}
});
I want to calculate the values, how to do with that?
$.ajax({
url: "120.58.243.11:8080/needCal/myJson.json",
dataType:'json',
success: function(data){
var items = [];
var totalOfValue = 0;
$.each(data,function(key,value){
totalOfValue = totalOfValue + parseInt(value.value);
});
$.each(data,function(key,value){
items.push("<tr>");
items.push("<td id='" +key+ "'>" + value.value+</td>");
items.push("<td id='" +key+ "'>" + totalOfValue +</td>");
items.push("</tr>");
});
}
}
);
A simple way is to use the reduce method:
Something like this:
var total = arr.reduce(function(t, v) {
return t += Number(v.value);
}, 0);

How to maintain the dynamic generated textboxes after postback

I am generating dynamic html textboxes in my aspx page. I add a button for do some functionality. now whenever I click on my button it post back and all the dynamic generated textboxes go from my form for this I have to add it again. But I want to maintain these textboxes after postback. Here is the code how i am generating textboxes
<script type="text/javascript">
var textid = null;
var textid1 = null;
$(document).ready(function () {
setupAutoComplete(textid);
setupAutoComplete1(textid1);
var counter = 2;
$("#addButton").click(function () {
if (counter > 5) {
alert("Limit Exceeds");
return false;
}
var newTextBoxDiv = $(document.createElement('div'))
.attr("id", 'TextBoxDiv' + counter);
textid = "textbox" + counter;
textid1 = "textbox" + counter+1;
// newTextBoxDiv.after().html('<label>Textbox #' + counter + ' : </label>' +
// '<input type="text" name="textbox' + counter +
// '" id="textbox' + counter + '" value="" class="auto">');
newTextBoxDiv.after().html('<div class="fields-left"><label> Leaving from</label><input type="text" name="textbox' + counter + '" id="textbox' + counter + '" class="auto"/> </div><div class="fields-right"> <label> Going to</label> <input type="text" name="textbox' + counter + '" id="textbox' + counter + 1 + '" class="auto"/> </div>');
newTextBoxDiv.appendTo("#TextBoxesGroup");
setupAutoComplete(textid);
setupAutoComplete1(textid1);
counter++;
});
$("#removeButton").click(function () {
if (counter == 1) {
alert("No more textbox to remove");
return false;
}
counter--;
$("#TextBoxDiv" + counter).remove();
});
});
var setupAutoComplete= function SearchText2(textid) {
$('.auto').autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Home.aspx/GetAutoCompleteData",
data: "{'code':'" + document.getElementById(textid).value + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) {
alert("Error");
}
});
}
});
}
var setupAutoComplete1 = function SearchText3(textid1) {
$('.auto').autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Home.aspx/GetAutoCompleteData",
data: "{'code':'" + document.getElementById(textid1).value + "'}",
dataType: "json",
success: function (data) {
response(data.d);
},
error: function (result) {
alert("Error");
}
});
}
});
}
</script>
now in this code I am generating maximun 10 textboxes two in each row and after that I write some code for json autocomplete for each dynamic generated textbox. Now problem is this when i click on my button after that its postback and all the textboxes and its values goes away. I am unable to maintain these textboxes. Can anybody tell me how can we maintain the dymanic generated textboxes after postback?
Thanks

Unable to format JSON from WCF for HighCharts?

My WCF returns this JSON and i want to bind to HighCharts Pie
Original from WCF -[{"AllRecordsUrl":"http:\/\/EMS\/sites\/IST\/report.aspx","EMSCenterName":"IST","EMSCenterUrl":"http:\/\/EMS\/sites\/IST","Count":2},{"AllRecordsUrl":"http:\/\/EMS\/sites\/LSS\/report.aspx","EMSCenterName":"LSS","EMSCenterUrl":"http:\/\/EMS\/sites\/LSS","Count":17}]
If i hardCode it in cart series as data: [....] it works but the dynamic proccesed data does not..
After processing - [{name: 'IST' , url: 'http://EMS/sites/IST/report.aspx' , y: 2 },{name: 'LSS' , url: 'http://EMS/sites/LSS/report.aspx' , y: 16 }]
Even after processing it to what i showed above highcharts Pie won't work with my data..
I am not sure what is wrong here, would appreciate some guidance
Here's what is done so far ...
function getDataForHub(json) {
var realArray = $.makeArray(json);
//debugger;
//console.log(JSON.stringify(realArray));
var obj = $.parseJSON(JSON.stringify(realArray));
var chartData = [];
$.each(realArray, function (index, item) {
var final;
var element;
var sB = '';
var name = '';
var url = '';
var y = '';
var color = '';
for (element in item) {
if (element == 'EMSCenterName') {
name = 'name' + ": " + "'" + item[element] + "'";
}
if (element == 'AllRecordsUrl') {
url = 'url' + ": " + "'" + item[element] + "'";
}
if (element == 'Count') {
y = 'y' + ": " + item[element];
}
}
sB = name + ' , ' + url + ' , ' + y ;
//console.log(sB);
var elements = [];
//adding each to an array before being pushed to th final array,
elements.push(sB);
chartData.push(elements);
});
return chartData;
}
And here is my Pie
$(function () {
LoadSodByKey("sp.ui.dialog.js", null);
var stdWidth = 530;
var stdHeight = 200;
Highcharts.setOptions({
colors: ['#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4']
});
$('#containerpie').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: true,
height: stdHeight + 120,
width: stdWidth + stdHeight
},
title: {
text: 'Records per Program'
},
tooltip: {
pointFormat: '{point.name}: <b>{point.percentage:.1f}%</b>'
/*formatter: function () {
return '<b>' + this.point.name;
}*/
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %'
},
showInLegend: false
}
},
series: [{
type: 'pie',
size: stdHeight,
data:[{name: 'IST' , url: 'http://EMS/sites/IST/report.aspx' , y: 2 },{name: 'LSS' , url: 'http://EMS/sites/LSS/report.aspx' , y: 16 }],
point: {
events: {
click: function(e) {
//alert(e.point.url);
var options = {
url: e.point.url,
title: e.point.name,
allowMaximize: true,
showClose: true,
width: 1100,
height: 500,
dialogReturnValueCallback: function (result, returnValue) {
//location.reload(true);
}
}
SP.UI.ModalDialog.showModalDialog(options);
e.preventDefault();
}
}
}
}]
});
var data = GetData();});
function GetData(){
var chart = $('#containerpie').highcharts();
series = chart.series[0];
//Ajax call to WCF service
$.ajax({
type: 'GET',
contentType: 'application/json; charset=utf-8',
crossDomain: false,
url: 'http://EMS/_vti_bin/EMSDashboard.svc/GetEMSCenterDataForHub',
data: null,
dataType: 'json',
success: function (response) {
var dynamicData = getDataForHub(response);
//this doesnot work
//series.data = dynamicData;
//even this does not work
//series.data.push(dynamicData)
//Wrong, wrong, wrong
//series.data.push(eval('[' +dynamicData +']'));
//gives me count of two but the chart does not load wiht dynamic data
console.log(series.data.length);
},
error: function (message) {
alert(message.statusText);
}
});
}
Thanx
FIXED:
Here's how
mistake = I had set up a static chart and was trying to use the same with $AJAX call where the chart was already created without the "data" being created, instead now the "data" array is created first and then the chart is created using chart = new Highcharts.Chart({....})
Also removed all client side preprocessing of the JSON received from WCF i.e my server object has additional Properties for Highchart rendering such to get ..
[{"name":"IST","url":"http:\/\/<XXXX>\/sites\/IST\/ASASA.aspx","y":2},
{"name":"LASS","url":"http:\/\/<XXXX>\/sites\/LASS\/ASASA.aspx","y":17}]