HTML table
<thead>
<tr>
<th class="text-center">1</th>
<th class="text-center">3</th>
<th class="text-center">2</th>
</tr>
</thead>
<tbody class="result_body">
</tbody>
data
var data = [
{
"0": "1",
"1": "20"
},
{
"0": "2",
"1": "30"
},
{
"0": "3",
"1": "5"
}
]
I create one table with th name 1,3,2, after that inside jquery I try to loop the data and append into the table. But it will follow the sequence with is 1,2,3. How can I append the data follow the table sequence with is 1,3,2?
Jquery Data output
<th>
<td>20</td>
<td>30</td>
<td>5</td>
<th>
Data correct should be
<th>
<td>20</td>
<td>5</td>
<td>30</td>
<th>
code here
https://jsfiddle.net/vwL0frhm/1/
Iterate your headers, and find the corresponding value (instead to iterate the array):
$('#opt_head th').each(function(dkey, dvalue) {
let textHeader = $(dvalue).text();
let value = data.find(o => o[0] === textHeader)[1];
html += "<td>"+ value +"</td>";
});
jsfiddle: https://jsfiddle.net/hansfelix50/Ltqvr3bm/
Related
I have the following table and want to convert it into JSON in a specific way
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
</tr>
<tr>
<td>B1</td>
<td>B2</td>
<td>B3</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
</tr>
</tbody>
</table>
My expected output would be like this as I need to compare the data over UI in html table and a json file having expected data (Note: there may be a varying number of rows):
{
"myrows" : [
{
"Column 1" : "A1",
"Column 2" : "A2",
"Column 3" : "A3"
},
{
"Column 1" : "B1",
"Column 2" : "B2",
"Column 3" : "B3"
},
{
"Column 1" : "C1",
"Column 2" : "C2",
"Column 3" : "C3"
}
]
}
How can this be accomplished?
It's fairly straight forward to loop over rows then cells in the row.
Use index values from each() command to give you access to the expected value in the JSON.
const expected = { "myrows" : [
... // as in the question, abreviated here
]}
it('check the table', () => {
cy.get('table tbody tr').each(($row, rowIndex) => {
cy.wrap($row).find('td').each(($cell, cellIndex) => {
const text = $cell.text()
expect(text).to.eq(expected.myrows[rowIndex][`Column ${cellIndex}`]
})
})
})
const rows = document.querySelectorAll("tbody tr");
const result = {
myrows: []
};
rows.forEach(r => {
const rData = {}
r.querySelectorAll("td").forEach((c, i) => {
rData[`column_${i + 1}`] = c.innerHTML;
})
result.myrows.push(rData)
})
console.log(result);
<table>
<thead>
<tr>
<th>Column 1</th>
<th>Column 2</th>
<th>Column 3</th>
</tr>
</thead>
<tbody>
<tr>
<td>A1</td>
<td>A2</td>
<td>A3</td>
</tr>
<tr>
<td>B1</td>
<td>B2</td>
<td>B3</td>
</tr>
<tr>
<td>C1</td>
<td>C2</td>
<td>C3</td>
</tr>
</tbody>
</table>
following approach I have followed, taking reference from answer given by "Genevieve OR" on my post, Thanks to #Genevieve OR
var headerList = []
cy.get('table thead tr th').each(($el)=>{
var headerName = $el.text()
headerList.push(headerName)// dynamically make a list of header
)}.then(()=>{
var jsonData = [];
cy.get('table tbody').find('tr').each(($row, rowIndex) => {
jsonData[rowIndex] = {};// creates object for each row
cy.wrap($row).find('td').each(($cell, cellIndex) => {
const text = $cell.text()
jsonData[rowIndex][headerList[cellIndex]] = text
const expected = { "myrows" :jsonData}
})
})
})
My output
{
"myrows": [
{
"column_1": "A1",
"column_2": "A2",
"column_3": "A3"
},
{
"column_1": "B1",
"column_2": "B2",
"column_3": "B3"
},
{
"column_1": "C1",
"column_2": "C2",
"column_3": "C3"
}
]
}
I am using table for showing the datas and for data I am using Api.
Api data looks like::
{
"data": [
{
"id": "1",
"name": "name1",
"label": "label1"
},
{
"id": "2",
"name": "name2",
"label": "label2"
},
{
"id": "3",
"name": "name3",
"label": "label3"
}
]
}
html code
<table class="table table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Label</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let data of sample;">
<td>{{data.id}}</td>
<td>{{data.name}}</td>
<td>{{data.label}}</td>
<tr>
<tbody>
<table>
I need the 10 table rows statically(fixed). The table data is from API. For exanple ,Api contains 2 data... Then UI table should be with 2 rows of data and balance with emply rows... but there should display 10 rows(Mandatory)
which means in UI i want 10 rows with data from Api and balance should be empty.
You can fix in view layer, ts layer or even backend API layer (Not really recommended).
In view layer if you loop over your data, you can calculate if your data's size goes over arbitrary threshold and if not loop again to display as many empty rows as possible.
In ts layer, when you receive data from api you can modify variable you pass to your view by adding to an array as many empty items as you need.
What's important if you use null, then you have to check for it with for example elvis operator.
I would advise agains adding to an array an object with all properties set to null, because then these are not so easily distinguishable from valid data from API and you can for instance make some rows interactive, even though they should not be.
const dataFromApi = [{ "id": "1", "name": "name1" }, { "id": "2", "name": "name2" }]
const minRowsNumber = 10;
const diff = minRowsNumber - dataFromApi.length;
const viewTableData = diff > 0 ? dataFromApi.concat(new Array(diff).fill(null)) : dataFromApi;
console.log(viewTableData)
Example in AngularJs (No Angular in SO Snippets, but it is the same principle)
angular.module('example', [])
.controller('ExampleController', function ExampleController() {
const dataFromApi = [{ "id": "1", "name": "name1" }, { "id": "2", "name": "name2" }]
const minRowsNumber = 10;
const diff = minRowsNumber - dataFromApi.length;
this.viewTableData = diff > 0 ? dataFromApi.concat(new Array(diff).fill(null)) : dataFromApi;
});
table {
border-collapse: collapse;
}
td, th {
border: 1px solid black
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="example" ng-controller="ExampleController as example">
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in example.viewTableData track by $index">
<td>{{row ? row.id : ' '}}</td>
<td>{{row ? row.name : ' '}}</td>
</tr>
</tbody>
</table>
</div>
My db is composed two tables User and Friends
An User have many Friends
I need to show the following table view
I queried both tables with an INNER JOIN as follows
SELECT usr.FirstName, usr.Phone, usr.Email, fri.FirstName AS friendName
FROM User AS usr
INNER JOIN Friends AS fri
WHERE fri.idUser = usr.idUser
Because many Friends have an User, Friends have the control how many results set will be returned.
Output:
{
"FirstName" : "jose", "Phone" : 123, "Email": "jose#jose.com", "friendName" : "Pedro",
"FirstName" : "jose", "Phone" : 123, "Email": "jose#jose.com", "friendName" : "Juan", // Same user, with another friend
}
The result set is correct, but i don't achieve figure out how to print it like the table view shown previously from Javascript or any language programming code that requested that query
Any idea how to solve this ?
To elaborate, with HTML you can just use unordered lists <ul> for Friends column
<table border="1">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Phone</th>
<th>E-Mail</th>
<th>Friends</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>Jose</td>
<td>123</td>
<td>jose#jose.com</td>
<td>
<ul>
<li>Pedro</li>
<li>Juan</li>
</ul>
</td>
</tr>
<tr>
<td>2</td>
<td>Felipe</td>
<td>456</td>
<td>felipe#felipe.com</td>
<td>
<ul>
<li>Carlos</li>
<li>Jose</li>
</ul>
</td>
</tr>
</tbody>
</table>
To use Javascript let's assume you have users array, you can loop on it and generate the <table> like this:
let users = [
{"userId": 1, "FirstName": "jose", "Phone": 123, "Email": "jose#jose.com", "friendName": "Pedro"},
{"userId": 1, "FirstName": "jose", "Phone": 123, "Email": "jose#jose.com", "friendName": "Juan"},
{"userId": 2, "FirstName": "felipe", "Phone": 456, "Email": "felipe#felipe.com", "friendName": "Carlos"},
{"userId": 2, "FirstName": "felipe", "Phone": 456, "Email": "felipe#felipe.com", "friendName": "Jose"}
];
// To combine friends of the same user in an array at property friendNames
let usersWithFriends = {};
for (let user of users) {
let index = 'user' + user.userId;
if (typeof usersWithFriends[index] === 'undefined') {
usersWithFriends[index] = user;
} else {
if (typeof usersWithFriends[index].friendNames === 'undefined') {
usersWithFriends[index].friendNames = [usersWithFriends[index].friendName];
delete usersWithFriends[index].friendName;
}
usersWithFriends[index].friendNames.push(user.friendName);
}
}
let tbodyHTML = '';
// For the # column
let no = 1;
for (let user in usersWithFriends) {
let userDetails;
if (usersWithFriends.hasOwnProperty(user)) {
userDetails = usersWithFriends[user];
}
tbodyHTML += '<tr>';
tbodyHTML += `<td>${no++}</td>`;
tbodyHTML += `<td>${userDetails.FirstName}</td>`;
tbodyHTML += `<td>${userDetails.Phone}</td>`;
tbodyHTML += `<td>${userDetails.Email}</td>`;
tbodyHTML += '<td><ul>';
for (let friendName of userDetails.friendNames) {
tbodyHTML += `<li>${friendName}</li>`;
}
tbodyHTML += '</td></ul>';
tbodyHTML += '</tr>';
}
document.getElementsByTagName('tbody')[0].innerHTML = tbodyHTML;
<table border="1">
<thead>
<tr>
<th>#</th>
<th>First Name</th>
<th>Phone</th>
<th>E-Mail</th>
<th>Friends</th>
</tr>
</thead>
<tbody></tbody>
</table>
OK,I see the tag you mark this question as mysql, so it is very simple to implete the html output when use mysql command with a --html config. just like below:
mysql -u username -p password -D database --html -e"select * from your_table_name limit 10" > data_result.html
when you open the above html file data_result.html by browser, you'd get the print style you want.
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/
I have a javascript object that I want to bind to a table using KnockoutJS
Here's my object:
var data = {
"Warnings": {
"numbers": 30,
"content": [
{
"number" : 3001,
"description" : "There may be a problem with the device you are using if you use the default profile"
},
{
"number" : 3002,
"description" : "There may be a problem with the device you are using if you don't use the default profile"
}
]
},
"Errors": {
"numbers": 20,
"content": [
{
"number": 1000,
"description": "No network is loaded"
},
{
"number": 1000,
"description": "No network is loaded"
}
]
}
};
ko.applyBindings(data);
Here's my html code:
<table class="table table-hover">
<thead>
<tr>
<th style="width:100px">Numero</th>
<th>Description</th>
</tr>
</thead>
<tbody data-bind="foreach: Warnings.content">
<tr data-bind="foreach: $data">
<td data-bind="text: $data.number"></td>
<td data-bind="text: $data.description"></td>
</tr>
</tbody>
</table>
Here's a JSFiddle: http://jsfiddle.net/etiennenoel/KmKEB/
I really need to use this format for my data Object.
I don't know why I'm not having the Warnings listed in a table since I'm not getting any errors...
You have an extra foreach that is not needed. Simply remove the foreach on your tr. The foreach on your tbody will assign a new value for $data for each tr that is rendered in the loop.