Displaying JavaScript Objects in an HTML Table Using WinJS - javascript

Currently I have my images and a title for them displaying like so in my Windows 8 App:
<table>
<tbody>
<tr>
<td>Image 1 Name</td>
<td>Image 2 Name</td>
<td>Image 3 Name</td>
</tr>
<tr>
<td>
<img src="/images/image1.jpg" width="125" height="125">
</td>
<td>
<img src="/images/image2.jpg" width="125" height="125">
</td>
<img src="/images/image3.jpg" width="125" height="125">
</td>
</tr>
</tbody>
</table>
However, I would like to be able to make an array of these items using JavaScript and display them via data binding with WinJS. Currently I have made the array of objects like so:
function initialize() {
var images = [
{ name: "Image 1", photo: "/images/Image1.jpg" },
{ name: "Image 2", photo: "/images/Image2.jpg" },
{ name: "Image 3", photo: "/images/Image2.jpg" },
];
var imagesList = new WinJS.Binding.List(images, { binding: true });
WinJS.Binding.processAll(null, imagesList);
};
document.addEventListener("DOMContentLoaded", initialize);
I tried altering the HTML by adding span tags within the td tags and data-win-bind to display the content, but I keep getting undefined.

Give an id to your table and then try to replace:
WinJS.Binding.processAll(null, imagesList);
with:
var myTable = document.getElementById("my-table"); //give this ID to your table
WinJS.Binding.processAll(myTable, imagesList);
this shuold attach your object to the table so that when you use a data-win-bind it knows what object to refer to.
Also I suggest you use a WinJS.UI.Repeater to create your table.
http://msdn.microsoft.com/en-us/library/windows/apps/dn301916.aspx

Related

Angular.JS Sub-Array access [& parsing a key]

It's my first time trying to build something with angular , and i find myself not able to retrieve some JSON data.
The data is retrieve from a SQL database in JSON form then passed to a template thanks to angular route :
.when('/tasks/:TaskID',{
templateUrl: 'template/task_data_template.html',
controller:"showTaskData",
controllerAs: 'STD'
})
The showTaskData is defined as follow :
angular.module('moonDive').controller('showTaskData',function($http,$routeParams){
var store = this;
store.tasks= [];
json_Url = 'api/tasks_data.php?TaskID=' + $routeParams.TaskID;
$http.get(json_Url).success(function(data){
store.tasks = data;
})});
My Data have this structure :
This is accessible from the template html by :
{{STD.tasks[1]}}
Which return the data in that "JSON" way :
{
"ActionID": "1",
"Taskref": "1",
"Ast1_1": "",
"Ast2_1": "Start EVA watch\nopen hatch\nAssist CDR",
"Ast3_1": "",
"Ast1_2": "Egress cabin to LM porch\nReceive & jetttison bag\nReceive ETB/LEC",
"Ast2_2": "Deploy CDR PLSS antenna\nHand jettison bag to CDR\nHand ETB/LEC to CDR",
"Ast3_2": "",
"Ast1_3": "Descend lander to top rung\nUnlock and deploy MESA\nLower ETB on LEC",
"Ast2_3": "Tape recorder -off\nVerify voice signals level and uitlity floo [......]"
}
So far so good, so my final purpose is to have a table with two column (ast1 , ast2) and X row for X task. I'm not really sure how to begin , but i've tried something like that :
<table class="bordered hoverable responsive-table">
<tbody>
<tr ng-repeat="boo in STD.tasks[1]">
<td style=" color: blue;" ng-if="$odd"> {{boo}}</td>
<td style="color:red" ng-if="$even"> {{boo}}</td>
</tr>
</tbody>
</table>
Well no luck it doesn't work at all, but one weird thing that prevent me to understand what's going on is that it displays all the information but in what seems to be a random order.
I'd like to delete rows with "1" ; usually i would do a ng-if="boo.NameOfTheRow" ; but here i don't really have access to this name do I ?
So my question is : How to delete the unnecessary data? And how can I arrange my data by Astr1 and 2 (for the columns) and task 1 to X (for the rows)
Thanks a lot !
PS :
The generated code should look like that :
<table>
<thead>
<td> task </td>
<td> Astr 1 </td>
<td> Astr 2 </td>
<td> Astr 3 </td>
</thead>
<tbody>
<tr>
<td> 1</td>
<td> {{STD.tasks[1].Ast1_1}} </td>
<td> {{STD.tasks[1].Ast2_1}}</td>
<td>{{STD.tasks[1].Ast3_1}} </td>
</tr>
<tr>
<td> 2</td>
<td> {{STD.tasks[1].Ast1_2}} </td>
<td> {{STD.tasks[1].Ast2_2}}</td>
<td>{{STD.tasks[1].Ast3_2}} </td>
</tr>
<tr>
<td> 3</td>
<td> {{STD.tasks[1].Ast1_3}} </td>
<td> {{STD.tasks[1].Ast2_3}}</td>
<td>{{STD.tasks[1].Ast3_3}} </td>
</tr>
....
<tr>
<td> 7</td>
<td> {{STD.tasks[1].Ast1_7}} </td>
<td> {{STD.tasks[1].Ast2_7}}</td>
<td>{{STD.tasks[1].Ast3_7}} </td>
</tr>
</tbody></table>
Thus the data should be displayed as :
If your STD.tasks is an array of entries, then you need to simply change your ng-repeat to ng-repeat="boo in STD.tasks".
You should be getting back JSON data in array form:
[
{"field":"value", "field2": "value"},
{"field":"value", "field2": "value"},
{"field":"value", "field2": "value"},
...
]
ng-repeat will want to iterate over each of those values in the array. Right now, you've pointed it to the very first item in the array, so it's repeating over each property in the object.

Is there a way to use jquery map text into json from a string?

First of all, I am asking this question is due to a broken API of petfinder. I am working on a rabbit rescue app (its web interface) and need some of petfinder's search results. Hopefully they fix the public API soon, but meanwhile I am using PHP to load their html content of search results and turn it into json for my front end to display.
The current method I use is to load the page into a invisible div tag and use jquery selector to map the content. But this is not efficient because it will also load up some of the original script and css files from petfinder. I would like to be able to manipulate the string directly.
Here are some of the examples:
Original code structure:
<html>
<head>
...
</head>
<body style="background:#ffffff">
<style type="text/css">
...
</style>
<body bgcolor="#FFFFFF" text="#000000" >
<table>
...
...
<tr class = "pfrow2">
<td><a href="//www.petfinder.com/petdetail/30773115" class="pflink" target="_blank">
Billie Bunny
</a>
</td>
<td>
Rabbit
</td>
<td>
Dutch
</td>
<td>
Adult
</td>
<td>
Small
</td>
<td class='legacy'>
<a href="//www.petfinder.com/petdetail/30773115" target="_blank">
<img src="//drpem3xzef3kf.cloudfront.net/photos/pets/30773115/1/?bust=1415669533&width=130" class="img pets" border="0">
</a>
</td>
</tr>
<tr class="pfrow1">
<td><a href="//www.petfinder.com/petdetail/30891970" class="pflink" target="_blank">
Barnabas Bunny
</a>
</td>
<td>
Rabbit
</td>
<td>
Himalayan, New Zealand
</td>
<td>
Young
</td>
<td>
Medium
</td>
<td class='legacy'>
<a href="//www.petfinder.com/petdetail/30891970" target="_blank">
<img src="//drpem3xzef3kf.cloudfront.net/photos/pets/30891970/3/?bust=1421966387&width=130" class="img pets" border="0">
</a>
</td>
</tr>
...
As you can see the information I really need is within tr class = "pfrow2" and tr class = "pfrow1". I wonder if there is a way I could do a similar grab $(".pfrow2").map(function(){}) if the class is actually within the string.
Alternatively, can I cut out the DOM before pfrow2 and after pfrow1?
BTW this is my current json output (note that I change width of the image because I want to use larger thumbnails).
[{
name: "Billie Bunny",
type: "Dutch",
age: "Adult",
size: "Small",
thumb: "//drpem3xzef3kf.cloudfront.net/photos/pets/30773115/1/?bust=1415669533&width=300",
link: "//www.petfinder.com/petdetail/30773115"
},{
name: "Barnabas Bunny",
type: "Himalayan, New Zealand",
age: "Young",
size: "Medium",
thumb: "//drpem3xzef3kf.cloudfront.net/photos/pets/30891970/3/?bust=1421966387&width=300",
link: "//www.petfinder.com/petdetail/30891970"
}]
I don't know how to make the string directly but I was able to cut the rows out for you. Assuming data is the result returned by your php.
var json = data.substring(data.indexOf('<tr class = "pfrow2">') - 21);
json = json.substring(0,json.lastIndexOf('</td>') + 5);
function widthChange() {
if (json.indexOf('&width=130') != -1) {
json = json.replace('&width=130','&width=300');
widthChange();
} else {
console.log(json);
// here you can inset json into your DOM
}
}
widthChange();

Populate HTML table with search value Angular

I have a json file, that will eventually be called from a server with an API. Currently am just calling from an object.
I am creating an HTML file with a table navigation, where each header element also has a search box and submit button.
I would like the table to be blank on start, and when one of the header values is searched (id, nickname, email, etc), the json value that contains at least part of that search will populate the table.
I am new to the Angular syntax and am trying to get an idea of how this would even work.
(function() {
var app = angular.module('tool', []);
app.controller('searchController', function() {
this.info = data.people;
this.findId = function(idInput) {
angular.forEach(that.id, function(value, key) {
if (value.contains(idInput)) {
// not sure what to put here.
}
});
};
});
var data = {
"people": [{
"id": "2245231",
"nickname": "heyyman",
"email": "info#gmail.net",
"lastIp": "127.0.0.1",
"regIp": "127.0.0.1",
}, {
"id": "2245232",
"nickname": "heyyman2",
"email": "info2#gmail.net",
"lastIp": "127.0.0.2",
"regIp": "127.0.0.2",
}
};
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<main>
<table ng-controller="searchController as search">
<thead>
<tr id="tableNavigation">
<td></td>
<td>ID
<input type="text" ng-model="idInput">
<input type="submit" ng-click="findId(idInput)">
</td>
<td>Nickname</td>
<td>Login / Email</td>
<td>Last IP</td>
<td>Registration IP</td>
</tr>
</thead>
<tbody id="tableCanvas">
<tr ng-repeat="people in search.info" ng-class-even="'even'">
<td></td>
<td>{{people.id}}</td>
<td>{{people.nickname}}</td>
<td>{{people.email}}</td>
<td>{{people.lastIp}}</td>
<td>{{people.regIp}}</td>
</tr>
</tbody>
</table>
</main>
So far, this is what I've done. Also, I've linked a JSFiddle.
http://jsfiddle.net/ho00cLkk/
Please let me know if what I am asking is confusing or not clear.
It seems to me that your question consists of two separate parts:
How do I filter the displayed items?
How do I hide all results until the first search is made?
As the second question seems uninteresting to me (many possible solutions, no general problem), I'll focus on the first one. You might want to read the documentation: https://docs.angularjs.org/api/ng/filter/filter . Then it's pretty simple and you don't even need any submit buttons:
<table>
<thead>
<tr>
<th>
Name
<input type="text" ng-model="searchProps.name">
</th>
...
</tr>
</thead>
<tbody>
<tr ng-repeat="person in people | filter:searchProps">
...
</tr>
</tbody>
</table>
(where people is your search.info). Table rows will be automatically filtered to contain only the items with properties partially matching the values in searchProps.
CodePen example: http://codepen.io/anon/pen/jEEZaa

How to bind data to attributes inside an array of objects using the Plates templating engine?

Using Plates, with their changing sintaxes (this doesn't work anymore) over the years and poor documentation,
I have this string:
<table id="group">
<tr>
<td class="name"></td>
<td>
<a class="surname"></a>
</td>
</tr>
</table>
And this data:
{
group: [{
name: 'Ludwig',
surname: 'von Mises',
url: 'http://mises.org/'
}, {
name: 'Friedrich',
surname: 'Hayek',
url: 'http://hayek.org/'
}],
}
What should I do to bind url to href, so I get
<table id="group">
<tr>
<td class="name">Ludwig</td>
<td>
<a class="surname" href="http://mises.org/">Mises</a>
</td>
</tr>
<tr>
<td class="name">Friedrich</td>
<td>
<a class="surname" href="http://hayek.org/">Hayek</a>
</td>
</tr>
</table>
?
Faced with a simple problem with others' libraries, I did what any programmer would do in this case: I wrote my own Plates-like (but not a fork of it) templating engine that (maybe) works.
Here it is: https://github.com/fiatjaf/tempreites
(Works with strings, semantic binding, just one file, no dependencies, a simple synchronous function named render and it is it.)
(I began writing it after I posted this question here, so it wasn't just for the propaganda.)

Populating a drop down box using javascript from server side files

I have a small site that has a dropdown box which I hope I can populate from a folder on a hosted server, each item in the dropdown box should represent the file name of each file in the folder.
This is then linked to a button which will call a function load selected data into a script to visualize.
I am currently unsure about loading the file list into the application.
so far I have:
drop down list (note: using jade):
select#dataSetChoice
the function to run a script based on the contents of the drop down box:
function loadDataSet(){
var dataSet = dataSetChoice.options[dataSetChoice.selectedIndex].text;
initialize(dataSet);
}
the button event:
button(onclick='loadDataSet()') Load data
all I need to do down is populate the drop box list based on the contents of this folder:
http://localhost/data/
Edit: html directory listing as requested
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<html>
<head>
<title>Index of /pje40</title>
</head>
<body>
<h1>Index of /pje40</h1>
<table>
<tr>
<th valign="top">
<img src="/icons/blank.gif" alt="[ICO]">
</th>
<th>
Name
</th>
<th>
Last modified
</th>
<th>
Size
</th>
<th>
Description
</th>
</tr>
<tr>
<th colspan="5"><hr></th>
</tr>
<tr>
<td valign="top">
<img src="/icons/back.gif" alt="[PARENTDIR]">
</td>
<td>
Parent Directory
</td>
<td> </td>
<td align="right"> - </td>
<td> </td>
</tr>
<tr>
<td valign="top">
<img src="/icons/unknown.gif" alt="[ ]">
</td>
<td>
week1
</td>
<td align="right">
2013-12-06 19:28
</td>
<td align="right">119K</td>
<td> </td>
</tr>
<tr>
<td valign="top">
<img src="/icons/unknown.gif" alt="[ ]">
</td>
<td>
week2
</td>
<td align="right">
2013-12-06 19:28
</td>
<td align="right">119K</td>
<td> </td>
</tr>
<tr>
<td valign="top">
<img src="/icons/unknown.gif" alt="[ ]">
</td>
<td>
week3
</td>
<td align="right">
2013-12-06 19:28
</td>
<td align="right">119K</td>
<td> </td>
</tr>
<tr>
<th colspan="5"><hr></th>
</tr>
</table>
<address>Apache/2.4.7 (Win32) OpenSSL/1.0.1e PHP/5.5.6 Server at localhost Port 80</address>
</body>
</html>
Should the jquery look similar to this:
script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js')
var returned_html = $.trim($('http://localhost/pje40/').html());
var trs = $(returned_html).find('tr');
trs.splice(0, 2);
trs.splice(trs.length - 1, 1);
var directory_list = [];
for(var i = 0; i < trs.length; i++)
{
var tds = $(trs[i]).find('td');
directory_list.push({
"icon": $(tds[0]).find('img').attr('src'),
"name": $(tds[1]).find('a').html(),
"href": $(tds[1]).find('a').attr('href'),
"last_modified": $(tds[2]).html(),
"size": $(tds[3]).html(),
"description": $(tds[4]).html()
});
}
alert(directory_list.length);
Well here is the sketch of what can be done with your problem. I have used jQuery to somehow ease DOM traversion
// Lets say `returned_html` it what came from server
var returned_html = $.trim($('#returned_html').html());
// We need to find all TRs and drop first two and the last one
var trs = $(returned_html).find('tr');
trs.splice(0, 2);
trs.splice(trs.length - 1, 1);
// Now we should have 4 lines (with to Parent Directory one).
// Lets create list
var directory_list = [];
for(var i = 0; i < trs.length; i++)
{
var tds = $(trs[i]).find('td');
directory_list.push({
"icon": $(tds[0]).find('img').attr('src'),
"name": $(tds[1]).find('a').html(),
"href": $(tds[1]).find('a').attr('href'),
"last_modified": $(tds[2]).html(),
"size": $(tds[3]).html(),
"description": $(tds[4]).html()
});
}
You'll get in directory_list:
[
{
description: " ",
href: "/",
icon: "/icons/back.gif",
last_modified: " ",
name: "Parent Directory",
size: " - "
},
{
description: " ",
href: "week1",
icon: "/icons/unknown.gif",
last_modified: "↵ 2013-12-06 19:28↵ ",
name: "week1",
size: "119K"
},
{
description: " ",
href: "week2",
icon: "/icons/unknown.gif",
last_modified: "↵ 2013-12-06 19:28↵ ",
name: "week2",
size: "119K"
},
{
description: " ",
href: "week3",
icon: "/icons/unknown.gif",
last_modified: "↵ 2013-12-06 19:28↵ ",
name: "week3",
size: "119K"
}
]
As you can see it still needs some post processing.
Fiddle to play with.
Update
You can get directory listing with
$.get('http://localhost/pje40/', function(html) {
process_listing(html);
});
You should proccess returned data in callback because $.get() is async by default.
But you can run into cross domain request problem here. Please read about CORS.
The other way would be to create hidden iframe and load http://localhost/pje40/. Then do some thing like I've done in my first fiddle.
Needless to say that process_listing() in this case is
function process_listing(returned_html)
{
// We need to find all TRs and drop first two and the last one
var trs = $(returned_html).find('tr');
trs.splice(0, 2);
trs.splice(trs.length - 1, 1);
// Now we should have 4 lines (with to Parent Directory one).
// Lets create list
var directory_list = [];
for(var i = 0; i < trs.length; i++)
{
var tds = $(trs[i]).find('td');
directory_list.push({
"icon": $(tds[0]).find('img').attr('src'),
"name": $(tds[1]).find('a').html(),
"href": $(tds[1]).find('a').attr('href'),
"last_modified": $(tds[2]).html(),
"size": $(tds[3]).html(),
"description": $(tds[4]).html()
});
}
}

Categories

Resources