Knockout Foreach binding to html table not working - javascript

I have been working on this issue for a while. I am new to Knockout.
I have an html page with a table that I want displayed using Knockout. If I hardcode the JSON array, it works! When I use the $.getJSON function, it does not work.
A little background: I cannot use any server-side languages for this project- a CMS is being used that will not allow server-side stuff.
I get the JSON from a table of data I download, then pass it to this to make displaying, styling, etc. automated so that all the user has to do is upload the file with the html table and the rest is taken care of.
If there is an easier way, I am definitely open to suggestions. My question is: how do I make the foreach data display?
Here is my fiddle with some test data:
https://jsfiddle.net/xtw3nf8q/
HTML
<table>
<tbody data-bind="foreach: teststuff">
<tr>
<td data-bind="text: $data.testone"></td>
<td data-bind="text: $data.testtwo"></td>
<td data-bind="text: $data.testthree"></td>
<td data-bind="text: $data.testfour"></td>
<td data-bind="text: $data.testfive"></td>
<td data-bind="text: $data.testsix"></td>
<td data-bind="text: $data.testseven"></td>
</tr>
</tbody>
jQuery/Knockout
$.getJSON( "/echo/json/jsonfile.txt", function( data ) {
ko.applyBindings({
teststuff: data
});
});
Here is the jsonfile.txt contents:
[{"testone":"Number","testtwo":"49","testthree":"49","testfour":"49","testfive":"49","testsix":"49","testseven":""},{"testone":"Reporting","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"0.0 %"},{"testone":"Area","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":""},{"testone":"K. BACA","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"D. GRAY","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"J. ISA","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"Number","testtwo":"49","testthree":"49","testfour":"49","testfive":"49","testsix":"49","testseven":""},{"testone":"Reporting","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"0.0 %"},{"testone":"Area","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":""},{"testone":"T. BARK","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"H. LAND","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"F. JONES","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"},{"testone":"D. KNOWLES","testtwo":"0","testthree":"0","testfour":"0","testfive":"0","testsix":"0","testseven":"N/A"}]
I downloaded the KnockoutJS plugin/extension for Chrome to help debug and that got me to this point. There are now no errors in the developer console; when I console.log "data", it shows my data. I am at a loss!

You've asked the server for text! It's given you a string
$.getJSON( "/echo/json/jsonfile.txt", ....
You need to turn that string into a valid object (an array in this case):
$.getJSON( "/echo/json/jsonfile.txt", function( data ) {
ko.applyBindings({
teststuff: JSON.parse(data)
});
});
Live example (using string data): https://jsfiddle.net/xtw3nf8q/4/

Related

Show several tags with JSON structure in Siemens s7 webserver

I am using a Siemens S7-1200 PLC with integrated webserver.
I want to show multiple analog values from the PLC in the webpage using javascript. With one tag it works great, but how do I add and present multiple tags using JSON structure?
I have done the following:
- Updated the javascript with a suggested code
- Updated the htm file that the script reads from
But I do not know if i have done this correct and how do I then call
for the different variables.
THIS IS THE TABLE I WANT TO DISPKLAY THE DATA IN:
<table>
<tr>
<td class="static_field">Nivå [m]:</td>
<td class="output_field"><label id="HMI_skalert">0</label></td>
</tr>
<tr>
<td class="static_field">Masse [tonn]:</td>
<td class="output_field"><label id="Tank1_masse">0</label></td>
</tr>
</table>
SCRIPT:
<script type="text/Javascript">
$(document).ready(function(){
$.ajaxSetup({ cache: false });
setInterval(function() {
$.getJSON("IOwebserver.htm", function(result){
HMI_skalert= result.HMI_skalert
Tank1_masse=result.Tank1_masse
});
},1000);
});
</script>
FILE:
IOwebserver.htm
{
":="webdata".HMI_skalert:",
":="webdata".Tank1_masse:"
}
Thank you so much.
I think you should look on this article... https://api.jquery.com/jquery.getjson/
You haven´t a return key in JSON in IOwebserver.htm file.
":="webdata".HMI_skalert:" -> value of JSON object which use AWP command in this case..
:="Name_of_DataBlock".variable: -> Symbols (:=) and (:) are boundaries of AWP command used in Simatic WebServer
So try to remake this file like this:
{
"HMI_skalert":":='webdata'.HMI_skalert:",
"Tank1_masse":":='webdata'.Tank1_masse:"
}
If this will not work try to swap apostrophes dobule quotes (") by one (').
For example I use a interval loading XML file to load 57 variables for Simatic S7-S1200 WebServer. For more information contact me..

How to sort data bind to table using knockoutjs mapping plugin?

I am able to bind data to a table and sort using the column headers.
However, I need to be able to edit the data so that it is updated and reflected in the corresponding table cell. To do this I need to make the data object an observable.
Instead of binding like this, using text binding:
<tbody data-bind="foreach: countries">
<tr>
<td data-bind="text: name"></td>
<td data-bind="text: capital"></td>
<td data-bind="text: population"></td>
</tr>
</tbody>
I need to bind using the value or textInput binding. Like so:
<tbody data-bind="foreach: countries">
<tr>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: capital" /></td>
<td><input data-bind="value: population" /></td>
</tr>
</tbody>
And instead of doing this:
$.getJSON('https://restcountries.eu/rest/v1/all', function(data){
self.countries(data);
});
I do this:
$.getJSON('https://restcountries.eu/rest/v1/all', function(data){
var mappedData = ko.mapping.fromJS(data);
var array = mappedData();
self.countries(array);
});
If I attempt to mapped the data using the plugin, the sort does not work.
How do I mapped the data as observables and still have the capability to sort them?
Here is a working JSFiddle example: Note: I removed the mapping since it breaks the code.
I checked the fiddle, the mapping plugin that you linked is wrong. The one in github is not supposed to be a cdn.
Remove the mapping plugin link you added and change it to this link.
I also forked the fiddle with the correct url and added the lines that you removed.
var mappedData = ko.mapping.fromJS(data);
var array = mappedData();
EDIT:
To fix the sorting, you need to change your sorting functions to call the observable values and not the observable function. Like from:
Excerpt from stringSort function:
var countryA = a[column.property].toLowerCase(), countryB = b[column.property].toLowerCase();
to:
var countryA = a[column.property]().toLowerCase(), countryB = b[column.property]().toLowerCase();
You also need to modify the numberSort, dateSort, and deepGet (which is used in objectSort) for other sorts to work. Please check updated fiddle for the sample changes.
JSFiddle link.

display nested arrays in knockout.js

I have a json object returned via jquery ajax from an asmx service. When I attempt to display it in a table, nothing displays. What might I be doing wrong?
Thanks in advance.
The returned json is ...
[{\"id\":1488,\"name\":\"Baby Books\",
\"categories\":
[{\"id\":152,\"name\":\"Activity Books\",\"value\":\"Ignore\"},
{\"id\":167,\"name\":\"Bedtime and Dreams\",\"value\":\"Ignore\"}]},
{\"id\":1489,\"name\":\"Story Books\",
\"categories\":
[{\"id\":1506,\"name\":\"Games - Floor Puzzles\",\"value\":\"Ignore\"}]}]
the js display code is (where gorupJson is returned from the call) ...
var viewModel = {
groups: ko.observableArray([]),
};
viewModel.groups(groupJson)
ko.applyBindings(viewModel);
the page content is ...
<table width="100%" >
<tbody data-bind="foreach: groups" style="width:100%">
<tr>
<td data-bind="text: name"></td>
<td>
<ul data-bind="foreach: categories">
<li>
<a><span data-bind="text: name"></span></a>
</li>
</ul>
</tbody>
</table>
Your json is not automatically converted into ko collection.
So you need to apply a mapping to this conversion, probably like this ko.mapping.fromJS(data). When you do it, your fields id, name, value will become in ko.observable
If you want to know more about mapping plugin in knockout, take a look at http://knockoutjs.com/documentation/plugins-mapping.html
First, your JSON is invalid.
Check out the fiddle: http://jsfiddle.net/YNdmh/
var groupJson = [{"id":1488,"name":"Baby Books","categories":
[{"id":152,"name":"Activity Books","value":"Ignore"},
{"id":167,"name":"Bedtime and Dreams","value":"Ignore"}]},
{"id":1489,"name":"Story Books","categories":
[{"id":1506,"name":"Games - Floor Puzzles","value":"Ignore"}]}]
You're missing closing tags for <td> and <tr>
The slashes in json have to go aswell.
http://jsfiddle.net/yhBvr/

How to simply convert parsed json data from URL to wordpress widget html table

Hello I've been searching the internet for about a couple of days now but I only get lost in the deepness of the subject.
What my aim is to get the json data from this URL: https://www.btcturk.com/api/ticker which is something like this;
{"high":1565.01,"last":1536.90,"timestamp":1388632896.0,"bid":1540.0,"volume":50.76,"low":1534.00,"ask":1552.00}
And I want to print / display / visualize some of the values in html table format, something like this;
<table border="1">
<tr>
<td>Alış (Bid): </td>
<td>bid value from json</td>
</tr>
<tr>
<td>Satış (Ask): </td>
<td>ask value from json</td>
</tr>
</table>
Please notice that the column1 is custom text and column2 is the related jason data.
That's it, I just want to insert the needed code into the HTML (Text ) Widget in Wordpress.
I'm not even sure if I need a plugin to do this, or if I need to download jquery.js file to my server can read it externally...
Any help, suggestion, guidance or any kind of reply is greatly appreciated.
I thank you all in advance.
if your current page where you want to put the widget is in the same domain, you can use the below snippet as text/html widget "assuming your page in the same domain https://www.btcturck.com"
<div class="result"></div>
<script type="text/javascript">
window.onload = function() {
jQuery.ajax( {
url: "https://www.btcturk.com/api/ticker",
}). done(
function( data ) {
var data = JSON.parse(data);
html = '<table><tr><td>BID</td><td>'+data.bid+'</td></table>';
$('.result').html(html);
});
};
</script>
I have used window onload because I don't know when your jquery library will be loaded.

Adding Operations to Knockout Mapping Object

I am struggling with adding operations to my Knockout Mapping object.
Here is where I am at right now - and I am attempting to follow the Knockout: Mapping API information.
This is the HTML first:
+ Add Contact
<div id="ContactList">
<table>
<thead>
<tr>
<th>ID</th><th>Name</th><th></th>
</tr>
</thead>
<tbody data-bind="foreach: $root">
<tr>
<td data-bind="text: ContactID"></td>
<td data-bind="text: DisplayName"></td>
<td></td>
</tr>
</tbody>
</table>
</div>
And this is my first attempt at wiring up Knockout:
var baseModel = {
addContact: function() {
alert('Woo!');
}
};
contacts = ko.mapping.fromJS('[{"ContactID":6,"DisplayName":"Doe, John"},{"ContactID":7,"DisplayName":"Rogers, Mister"}]', { }, baseModel);
ko.applyBindings(contacts);
Now, if I remove the additional arguments ({} and baseModel) from the ko.mapping.fromJS, all my data is displayed in the table correctly. However (and as to be expected), I get a binding error with the "Add Contact" link. If I add baseModel back in, clicking the "Add Contact" link works, but no data displays. I get no errors one way or another, so I'm a bit stumped on what's going on there.
I'm new to KO, so I feel like I'm missing something pretty simple. I've searched across StackOverflow, but, at this point, I'm just plugging code in to see what works and not actually understanding what is happening here. Can someone provide some additional explanation and point me in the right direction? Thanks.
You're using ko.mapping.fromJS but you're passing a string, not an object/array. Either use fromJSON or pass in a real array.
Also, you should applyBindings on baseModel, and contacts should be a field of the VM. Then you can use foreach: contacts instead of your weird foreach: $root.
See fiddle with those changes: http://jsfiddle.net/antishok/kR4jc/3/
EDIT - Updating your answer with your code so the question can stand on its own.
JavaScript
var baseModel = {
addContact: function() {
alert('Woo!');
}
};
baseModel.contacts = ko.mapping.fromJSON('[{"ContactID":6,"DisplayName":"Doe, John"},{"ContactID":7,"DisplayName":"Rogers, Mister"}]');
ko.applyBindings(baseModel);​
HTML
+ Add Contact
<div id="ContactList">
<table>
<thead>
<tr>
<th>ID</th><th>Name</th><th></th>
</tr>
</thead>
<tbody data-bind="foreach: contacts">
<tr>
<td data-bind="text: ContactID"></td>
<td data-bind="text: DisplayName"></td>
<td></td>
</tr>
</tbody>
</table>
</div>​

Categories

Resources