different table rows per data in ng-repeat Angular - javascript

Okay, so I'm having hard time understanding how ng-repeat builds tables. What I'm trying to do is that per row, there is customer name and address. I can't get it to work. Here is my HTML code:
<table class="table table-striped" ng-controller="myController">
<thead>
<tr>
<th>Company Name</th>
<th>Address</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="company in fieldData" row-id="{{ company.name }}">
<td>{{ company.name }}</td><td>{{ company.address }}</td>
</tr>
</tbody>
</table>
and here is my script:
var companyName = [];
var companyAddress = [];
$scope.fieldData = [];
$(data).find('record').each(function () {
companyName.push($(this).record(6));
companyAddress.push($(this).record(47));
});
$scope.fieldData.push({
name: companyName,
address: companyAddress
})
So, in companyName and companyAddress arrays, there are name and addresses being stored. But I can't get one company & address per row. Any ideas?

You built an one element array with one object of two arrays, like:
fieldData: [
{
name: [
'name1', 'name2', 'etc'
],
address: [
'addr1', 'addr2', 'etc'
]
}
]
You want to have an array of objects with name and address fields:
fieldData: [
{
name: 'name1',
address: 'addr1'
},
{
name: 'name2',
address: 'addr2'
},
{
name: 'etc',
address: 'etc'
}
]
To achieve that, go with:
$scope.fieldData = [];
$(data).find('record').each(function (item) {
$scope.fieldData.push({
name: item.record(6),
address: item.record(47)
});
});

Related

How to load Json array into separate table rows?

I'm having trouble with displaying my json data correctly. I want to get each products and place them into it's own row.
The problem now is that it places all the data of for example the value "name" into one table row instead of multiple rows.
This is my json data
{
id: "FVFkkD7s8xNdDgh3zAyd",
name: "AlperKaffe",
products: [
{
id: "0cfBnXTijpJRu14DVfbI",
name: "Første Kaffe",
price: "1",
size: "small",
quantity: "20 ml"
},
{
id: "JQadhkpn0AJd0NRnnWUF",
name: "Anden Kaffe",
price: "2",
size: "Medium",
quantity: "25 ml"
},
{
id: "UwHHdH8bFxbVHkDryeGC",
name: "kaffeeen",
price: "300",
size: "Small",
quantity: "23 ml"
},
{
id: "WiX5h0wFMNkCux9cINYq",
name: "kaffe modal",
price: "230",
size: "Medium",
quantity: "39 ml"
},
this is my Js file which gets the json data. As you can see i'm only working with the "name" value for now
// Jquery getting our json order data from API
$.get("http://localhost:8888/products", (data) => {
let rows = data.map(item => {
let $clone = $('#frontpage_new_ordertable tfoot tr').clone();
let productsName = item.products.map(prod => `${prod.name}`);
$clone.find('.name').html(productsName);
return $clone;
});
// appends to our frontpage html
$("#frontpage_new_ordertable tbody").append(rows);
});
this is my html file
<body>
<table id="frontpage_new_ordertable">
<tbody>
<tr>
<th>Name</th>
<th>Price</th>
<th>Size</th>
<th>Quantity</th>
<th></th>
</tr>
</tbody>
<tfoot>
<tr>
<td class="name"></td>
<td class="price"></td>
<td class="size"></td>
<td class="quantity"></td>
<td class="buttons"></td>
</tr>
</tfoot>
</table>
<script src="./itemPage.js"></script>
</body>
you must replace
let rows = data.map(item => {
to
let rows = data.products.map(item => {
and
let productsName = item.products.map(prod => `${prod.name}`);
to
let productsName = item.name;
https://jsfiddle.net/ab7t1vmf/3/
The issue in your JS snippet seems to be let rows = data.map(item => { ...
From what you describe, the JSON data is comprised of 3 keys:
id
name
products
You cannot execute a map function directly on a Javascript Object, this function requires an array.
Looking a bit more at your code, I understand you need to display each product on its own row. Thus, you would need to use the map function on data.products which contains an array (of products).
let rows = data.products.map(item => {
// ...
$clone.find('.name').html(item.name);
// ...
// ...
});
Reference: https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/map

Javascript put data on <template> and append it on tbody after axios request

I have here a table in which a person's data will be displayed
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Username</th>
<th scope="col">Birthdate</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
this template is will be use on putting the data and append it on the tbody
<template id="persons">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</template>
this is the JavaScript code that I have
let oCRUD = {
init: function() {
this.setDOMElements();
this.getPersons();
},
// Setting DOM Elements
setDOMElements: function() {
this.oTemplate = document.querySelector('#persons'); //persons row
this.oTbody = document.querySelector("tbody");
this.oClone = document.importNode(oCRUD.oTemplate.content, true);
this.oTd = oCRUD.oClone.querySelectorAll("td");
},
getPersons: function() {
axios.get('selectAll.php')
.then(function (response) {
response.data.forEach((element,index) => {
oCRUD.oTd[0].textContent = element.name;
oCRUD.oTd[1].textContent = element.username;
oCRUD.oTd[2].textContent = element.birthdate;
oCRUD.oTd[3].textContent = element.age;
oCRUD.oTd[4].textContent = element.email;
oCRUD.oTbody.appendChild(oCRUD.oClone);
});
})
.catch(function (error) {
console.log(error);
});
}
}
// call the init function
oCRUD.init();
How can I use the template put the data there after the successful response of axios and append it on the tbody. This is my first time using DOM templating I have no idea how to start it.
This is the successful response after axios get request
[
{
id: "1",
name: "john",
username: "john doe",
birthdate: "1999-05-21",
age: "20",
email: "test#gmail.com",
},
{
id: "2",
name: "sally",
username: "sally mcsalad",
birthdate: "1999-03-27",
age: "20",
email: "try#gmail.com",
},
]
EDIT: I SUCCESSFULLY SHOW THE DATA HOWEVER I ONLY GOT THE SECOND SET OF DATA (sally mcsalad) NOT THE WHOLE DATA
Your main problem is you only clone the node, and select the tds once. This counts as a single object, which will just update the existing elements on each iteration. You need to refresh the clone and the selected tds on each iteration
var data = [
{
id: "1",
name: "john",
username: "john doe",
birthdate: "1999-05-21",
age: "20",
email: "test#gmail.com",
},
{
id: "2",
name: "sally",
username: "sally mcsalad",
birthdate: "1999-03-27",
age: "20",
email: "try#gmail.com",
},
];
let oCRUD = {
init: function() {
this.setDOMElements();
this.getPersons();
},
// Setting DOM Elements
setDOMElements: function() {
this.oTemplate = document.querySelector('#persons'); //persons row
this.oTbody = document.querySelector("tbody");
this.oClone = document.importNode(oCRUD.oTemplate.content, true);
this.oTd = oCRUD.oClone.querySelectorAll("td");
},
refreshClone: function() {
this.oClone = document.importNode(oCRUD.oTemplate.content, true);
this.oTd = oCRUD.oClone.querySelectorAll("td");
},
getPersons: function() {
/*axios.get('selectAll.php')
.then(function (response) {*/
data.forEach((element,index) => {
oCRUD.refreshClone();
oCRUD.oTd[0].textContent = element.name;
oCRUD.oTd[1].textContent = element.username;
oCRUD.oTd[2].textContent = element.birthdate;
oCRUD.oTd[3].textContent = element.age;
oCRUD.oTd[4].textContent = element.email;
oCRUD.oTbody.appendChild(oCRUD.oClone);
});
/*})
.catch(function (error) {
console.log(error);
});*/
}
}
// call the init function
oCRUD.init();
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Username</th>
<th scope="col">Birthdate</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
<template id="persons">
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</template>
add the function generateTable to your code and call it after success your request
function generateTable(persons){
let oTbody = document.querySelector("tbody");
if(!persons) return;
persons.forEach( person=>{
let tr =
`<tr id=${person.id}>
<td>${person.name}</td>
<td>${person.username}</td>
<td>${person.birthday}</td>
<td>${person.age}</td>
<td>${person.email}</td>
</tr>`
oTbody.insertAdjacentHTML('beforeend', tr);
})
}
let persons = [
{
id: "1",
name: "john",
username: "john doe",
birthdate: "1999-05-21",
age: "20",
email: "test#gmail.com",
},
{
id: "2",
name: "sally",
username: "sally mcsalad",
birthdate: "1999-03-27",
age: "20",
email: "try#gmail.com",
},
]
generateTable(persons)
<table class="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Username</th>
<th scope="col">Birthdate</th>
<th scope="col">Age</th>
<th scope="col">Email</th>
</tr>
</thead>
<tbody>
<!-- existing data could optionally be included here -->
</tbody>
</table>
Use template function in general, such as lodash.template or jQuery.tmpl, you can also implement a simple template function.
Step1: define a template function to transit each data object to html string.
# use ES2015 string template feature
function transitData(data){
return '<tr>' +
`<td class="record">${data.name}</td>` +
`<td>${data.email}</td>` +
'</tr>';
}
Step2: get Server response and render your data collection(such as array).
axios.get('selectAll.php').then(response => {
let html = response.data.map(transitData).join("\n");
oTbody.insertAdjacentHTML('beforeend', html);
});

How to remove default order of ng-repeat

How do I stop default sorting inside the ng-repeat for dynamic table data ?
Currently I am getting below order:
Addr | CustomerId | Name
but what I want is below ordering:
CustomerId | Name | Addr
Any Help would me much appreciated.
JS:
app.controller('MyController', function ($scope) {
$scope.Customers = [
{ CustomerId: 1, Name: "John Hammond", Addr:'India'
},
{
CustomerId: 2, Name: "Mudassar Khan", Addr:'India'
},
{
CustomerId: 3, Name: "Suzanne Mathews", Addr:'India'
},
{
CustomerId: 4, Name: "Robert Schidner", Addr: 'India'
}
];
});
HTML:
<table>
<tr >
<th ng-repeat="(key,value) in Customers[0]">{{key}}</th>
</tr>
<tbody ng-repeat="c in Customers">
<tr>
</tr>
</tbody>
</table>
Try this below way. I hope this below snippet result is showing what you want.
angular.module("aaa",[]).controller('MyController', function ($scope) {
$scope.Customers = [
{ CustomerId: 1, Name: "John Hammond", Addr:'India'
},
{
CustomerId: 2, Name: "Mudassar Khan", Addr:'India'
},
{
CustomerId: 3, Name: "Suzanne Mathews", Addr:'India'
},
{
CustomerId: 4, Name: "Robert Schidner", Addr: 'India'
}
];
$scope.keys = Object.keys($scope.Customers[0]);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="aaa" ng-controller="MyController">
<table>
<tr>
<th ng-repeat="key in keys">
{{key}}
</th>
</tr>
<tbody ng-repeat="c in Customers">
<tr>
<td ng-repeat="key in keys">{{c[key]}}</td>
</tr>
</tbody>
</table>
</div>
So objects in JS are inherently unordered. What you can do is just hard code the keys in the header if that will be fixed for that particular table and then print the values in the respective order.
Something like this:
<table>
<tr >
<th>CustomerId</th>
<th>Name</th>
<th>Addr</th>
</tr>
<tbody>
<tr ng-repeat="c in Customers">
<td>{{CustomerId}}</td>
<td>{{Name}}</td>
<td>{{c.Addr}}</td>
</tr>
</tbody>
</table>
Note: I put the ng-repeat on the tr which is probably what you need. I dont think you should put it on the tbody.
Do you mean the sort order of the data or the display order of the columns?
The accepted answer displays the data by the order of the columns as specified, but if you want the data itself sorted then just add a filter to the data like this:
<tbody ng-repeat="c in Customers|orderBy:['CustomerId','Name','Addr']">
This sorts the actual data in the list by the fields specified.

Display data in a table by grouping them horizontally

I have some data that has the following format:
[name:'Name1', speed:'Val1', color:'Val2']
[name:'Name2', speed:'Val4', color:'Val5']
[name:'Name3', speed:'Val6', color:'Val7']
That I want to display in a table like this:
|Name1|Name2|Name3|
______|_____|______
speed |Val1 |Val4 |Val6
color |Val2 |Val5 |Val7
What I tried to do is group my data like this in the controller:
$scope.data = {
speeds: [{
...
},{
...
},{
...
}],
colors: [{
...
},{
...
},{
...
}],
};
But I am not sure what to put inside the empty areas, because all values there represent the values of the 'val1' variable for all Names (Accounts), and my tests until now keep failing.
You can imagine this as some sort of a comparisons matrix, that is used in order to see the all the values of the same variable across different accounts.
How can I represent the data in my model in order for me to successfully display them in a table as explained?
Edit
My difficulty lies in the fact that you create a table by going from row to row, so my html looks something like this:
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
So as you can see I have a loop for each row, and a loop for each value of each row. This would be easier if I wanted to display the data horizontally, but I want the data vertically. So if we where talking about cars, we would have the car models as headers, and their respective characteristics(speed, color, etc) in each row.
If this is your basic structure:
var cols = [{name:'Name1', val1:'Val1', val2:'Val2'},
{name:'Name2', val1:'Val4', val2:'Val5'},
{name:'Name3', val1:'Val6', val2:'Val7'}];
This code
$scope.table = cols.reduce(function(rows, col) {
rows.headers.push({ value: col.name });
rows.data[0].push({ value: col.speed });
rows.data[1].push({ value: col.color });
return rows;
}, {headers:[], data:[[], []]});
will give you this structure for $scope.table:
$scope.table = {
headers : [{
value : "Name1"
}, {
value : "Name2"
}, {
value : "Name3"
}
],
data : [
[{
value : 'val1'
}, {
value : 'val4'
}, {
value : 'val6'
}
],
[{
value : 'val2'
}, {
value : 'val5'
}, {
value : 'val17'
}
]
]
};
<table md-data-table class="md-primary" md-progress="deferred">
<thead>
<tr>
<th ng-repeat="header in table.headers">
{{header.value}}
</th>
</tr>
</thead>
<tbody>
<tr md-auto-select ng-repeat="field in table.data">
<td ng-repeat="var in field">{{var.value}}</td>
</tr>
</tbody>
</table>
You could try this:
HTML
<table ng-app="myTable" ng-controller="myTableCtrl">
<thead>
<tr>
<th ng-repeat="car in cars">{{car.name}}</th>
</tr>
</thead>
<tbody>
<tr>
<td ng-repeat="car in cars">{{car.speed}}</td>
</tr>
<tr>
<td ng-repeat="car in cars">{{car.color}}</td>
</tr>
</tbody>
</table>
JS
angular.module("myTable",[])
.controller("myTableCtrl", function($scope) {
$scope.cars = [
{
name:'Name1',
speed:'Val1',
color:'Val2'
},
{
name:'Name2',
speed:'Val4',
color:'Val5'
},
{
name:'Name3',
speed:'Val6',
color:'Val7'
}
]
});
https://jsfiddle.net/ABr/ms91jezr/

Change array of json to a table in angularjs

My json looks like this :
[{"Name":["A","B","C","D","E","F"], "Age":["20","30","40","50","55","60"], "Gender":["M","M","F","M","Unknown","Unknown"]}]
I want a table in angularjs similar to this
Name Age Gender
A 20 M
B 30 M
C 40 F
I could see many example when my json is similar to this :
[
{Name: "A", Age: "20", Gender: "M"},
{Name: "Bag", Age: "30", Gender: "F"},
{Name: "Pen", Age: "40", Gender: "F"}
];
But I don't know how to proceed with my json. Could anyone help with this?
Assuming your property arrays all have the same number of elements (and are properly arranged) you could use the $index of ng-repeat.
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>Gender</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="name in obj.Name">
<td>{{name}}</td>
<td>{{obj.Age[$index]}}</td>
<td>{{obj.Gender[$index]}}</td>
</tr>
</tbody>
</table>
Alternatively (using the same assumption that the data is well-formed), you can just use javascript to consolidate the three separate lists into a single list of person objects. Then you can proceed like the other examples you've seen.
Javascript might look something like this:
$scope.people = [];
obj.Name.forEach(function(name, index) {
people.push(
{
Name: name,
Gender: obj.Gender[index],
Age: obj.Age[index]
});
});
Then a simple ng-repeat on the new people array will work.
...
<tbody>
<tr ng-repeat="person in people">
<td>{{person.Name}}</td>
<td>{{person.Age}}</td>
<td>{{person.Gender}}</td>
</tr>
</tbody>
Try something.
<div ng-repeat="user in users.Name">
Name : {{user}} Age : users.Age[$index] Gender : users.Gender[$index]
</div>
I assume your object is sequenced and arranged
Use lodash _.zip function to arrange them in array, and _.map to convert it to json objects using custom function:
var rows = _.zip(users.Name, users.Age, users.Gender); // [["A",20,"M"],...]
$scope.users =
_.map(rows, function(row) {
return {Name: row[0], Age: row[1], Gender: row[2]}
});
and then iterate them getting values:
<table ng-controller="UsersTableController">
<thead>
<th>NAME</th>
<th>AGE</th>
<th>GENDER</th>
</thead>
<tbody>
<tr ng-repeat="user in users">
<td>{{user.Name}}</td>
<td>{{user.Age}}</td>
<td>{{user.Gender}}</td>
</tr>
</tbody>
</table>
reference: https://lodash.com/docs#zip , https://lodash.com/docs#map

Categories