Lets say we have a table like the one in the example below and i want to do those things in order :
Create a parent object
Assign the text of the header as the first key/value
Create an array as the second key/value
Create an object for every td in tbody with 4 key/values inside containing their values like this :
{
age: "33",
car: "Toyota",
job: "Plummer",
name: "Mark"
}
Push all the objects I created in the previous step in the array.
So the final parent object will become this (based on the example) :
{
head: "Whatever",
cells: [{
name: "Mark",
job: "Plummer",
age: "33",
car: "Toyota"
}, {
name: "John",
job: "Electrician",
age: "26",
car: "Fiat"
}, {
name: "Jane",
job: "Police Officer",
age: "45",
car: "Tesla"
}, {
name: "Chris",
job: "Engineer",
age: "31",
car: "Mercedes"
}]
}
I got as far as creating the parent object and the 2 keys inside, but I don't even know where to start for creating an object for every tr. Any ideas on what the steps I have to follow next?
My progress so far :
var parentObject = {};
parentObject.head = $("#mp").text()
parentObject.cells = []
console.log(parentObject)
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th colspan="4" id="mp">Whatever</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mark</td>
<td>Plummer</td>
<td>33</td>
<td>Toyota</td>
</tr>
<tr>
<td>John</td>
<td>Electrician</td>
<td>26</td>
<td>Fiat</td>
</tr>
<tr>
<td>Jane</td>
<td>Police Officer</td>
<td>45</td>
<td>Tesla</td>
</tr>
<tr>
<td>Chris</td>
<td>Engineer</td>
<td>31</td>
<td>Mercedes</td>
</tr>
</tbody>
</table>
To do what you require you can use map() to build an array of objects from the cells within the tbody, something like this:
const $table = $('table');
let serialisedTable = {
name: $table.find('thead th').text(),
cells: $table.find('tbody tr').map((i, row) => ({
name: row.cells[0].innerText.trim(),
job: row.cells[1].innerText.trim(),
age: row.cells[2].innerText.trim(),
car: row.cells[3].innerText.trim()
})).get()
}
console.log(serialisedTable);
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.1/dist/css/bootstrap.min.css" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th colspan="4" id="mp">Whatever</th>
</tr>
</thead>
<tbody>
<tr>
<td>Mark</td>
<td>Plummer</td>
<td>33</td>
<td>Toyota</td>
</tr>
<tr>
<td>John</td>
<td>Electrician</td>
<td>26</td>
<td>Fiat</td>
</tr>
<tr>
<td>Jane</td>
<td>Police Officer</td>
<td>45</td>
<td>Tesla</td>
</tr>
<tr>
<td>Chris</td>
<td>Engineer</td>
<td>31</td>
<td>Mercedes</td>
</tr>
</tbody>
</table>
Note that this can be made more dynamic by placing the 'cell' object's keys in the HTML of each row, if necessary.
Related
Hello everyone hope you having a great day,
I have setup a front end app on Vue Js linked with an express.js api which connects to a mysql database. I use axios for sending http requests. I am able to grab the data from my mysql database and console.log it into the front end system.
However I am struggling to extract the data from the array and display it into the table.
This is the table.
<table class="table">
<thead>
<tr>
<th scope="col">#ID</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">email</th>
<th scope="col">DOB</th>
<th scope="col">Country Of Residence</th>
<th scope="col">Phone Number</th>
<th scope="col">Contact_Via Phone</th>
<th scope="col">Contact Via Email</th>
<th scope="col">Contact Via Mail</th>
<th scope="col">Sign up date</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row" v-for="name in newData" :key="newData.id"></th>
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</table>
This is where I grab the data from the database when the page is created.
async created() {
try {
const getUserData = await axios.get('/api/getstudentdata', {})
.then(getUserData => getUserData.data)
{
this.newData = JSON.parse(JSON.stringify(getUserData))
for( let i = 0; i < this.newData.length; i++) {
console.log(this.newData[i].Name)
}
}
}catch(error) {
console.log(error)
}
},
Here I have added what my console logs and what the vue dev tools say.
https://imgur.com/a/eIHDq6u
console logs:
roxy {0: {…}, 1: {…}, 2: {…}}
[[Handler]]: Object
[[Target]]: Array(3)
0: {ID: 50, Name: 'Bob', Surname: 'Bobbob', Email: 'bob#gmail.com', DOB: '2000-07-15', …}
1: {ID: 51, Name: 'Tony', Surname: 'Scrub', Email: 'badatcoding#gmail.com', DOB: '2000-07-15', …}
2: {ID: 52, Name: 'Onemoreuser', Surname: 'te4st', Email: 'testoding#gmail.com', DOB: '2000-07-15', …}
length: 3
[[Prototype]]: Array(0)
[[IsRevoked]]: false
Dev tools:
newData:Array[3]
0:Reactive
ID:50
Name:"Bob"
Surname:"Bobbob"
Email:"bob#gmail.com"
DOB:"2000-07-15"
Country_of_residence:"London"
Phonenumber:"0749432423"
contact_phone:"true"
contact_email:"true"
sign_up_date:"2022-07-19T14:06:19.000Z"
Timezone:"GMT+1"
1:Reactive
2:Reactive
Update! I managed to display all the data to the table however I cant extract just the ID or the Name... here is photo of result.
https://imgur.com/a/3pqDrML
First of all, in a v-for loop, keys must be unique and newData.id is not a valid key, I guess you wanted to use something like:
v-for="item in newData" :key="item.id"
Secondly ,you're using v-for in the wrong place and you are not using vue mustaches to use dynamic variables. Try this one:
<tr v-for="item in newData" :key="item.id">
<td>{{item.ID}}</td>
<td>{{item.Name}}</td>
<td>{{item.Surname}}</td>
...
</tr>
Good day,
I want a straightforward way to loop through data and display it in a table.
If there's more data then it must create more rows etc.
Columns are fixed.. for now.
Example the code looks like the following
<table>
<thead>
<tr>
<th>Client Name</th>
<th>Client Representative</th>
<th>Client Representative Position</th>
<th>Client Representative Email</th>
<th>Date Created</th>
</tr>
</thead>
<tbody>
<tr>
<td id="client_name"></td>
<td id="client_representative"> </td>
<td id="client_representative_position"> </td>
<td id="client_representative_email"></td>
<td id="date_created"></td>
</tr>
</tbody>
</table>
<script>
var data = {
client_name: "Example Company",
client_representative: "John",
client_representative_position: "Engineer",
client_representative_email: "John#example.com",
date_created: "25/02/2021",
} **
document.getElementById("client_name").innerHTML = data.client_name;
document.getElementById("client_representative").innerHTML = data.client_representative;
document.getElementById("client_representative_position").innerHTML = data.client_representative_position;
document.getElementById("client_representative_email").innerHTML = data.client_representative_email;
document.getElementById("date_created").innerHTML = data.date_created; **
</script>
Basically, I want to avoid that piece surrounded by ** (javascript) bit by having it loop through the data.
Thanks in advance!
You Can use jQuery append()
Try this
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
</head>
<body>
<table >
<thead >
<tr>
<th>Client Name</th>
<th>Client Representative</th>
<th>Client Representative Position</th>
<th>Client Representative Email</th>
<th>Date Created</th>
</tr>
</thead>
<tbody id="table-body">
</tbody>
</table>
</body>
<script>
var data = [ {
client_name : "Example Company",
client_representative:"John",
client_representative_position:"Engineer",
client_representative_email:"John#example.com",
date_created:"25/02/2021",
},
{
client_name : "Example Company 2",
client_representative:"John 2",
client_representative_position:"Engineer 2",
client_representative_email:"John2#example.com",
date_created:"5/02/2021",
},
]
for (let index = 0; index < data.length; index++) {
var html = "<tr>";
html +="<td>"+data[index].client_name+"</td>";
html +="<td>"+data[index].client_representative+"</td>";
html +="<td>"+data[index].client_representative_position+"</td>";
html +="<td>"+data[index].client_representative_email+"</td>";
html +="<td>"+data[index].date_created+"</td>";
html += "</tr>";
$('#table-body').append(html);
}
</script>
</html>
To get the names of the keys in an object, you can use the in keyword.
This just loops through the keys as strings, allowing you to use in to set the elements in the table.
for (key in data)
document.getElementById(key).innerHTML = data[key]
I am receiving a data object of results that have been pivoted and I am unable to change the structure that is returned to me. My only option at this point is to manipulate the data to parse it how I need to.
Here is what my results look like:
// Object from service
let dataObj = [{
CostCenter: '12345',
HasLevel1Access: 'No',
HasLevel2Access: 'No',
HasLevel3Access: 'Yes',
FirstName: 'Bob',
LastName: 'Jones',
UID: '12345'
},
{
CostCenter: '555',
HasLevel1Access: 'Yes',
HasLevel2Access: 'No',
HasLevel3Access: 'Yes',
FirstName: 'Tommy',
LastName: 'C',
UID: '6789'
},
{
CostCenter: '51112',
HasLevel1Access: 'Yes',
HasLevel2Access: 'No',
HasLevel3Access: 'Yes',
FirstName: 'Smithson',
LastName: 'J',
UID: '8888'
}];
From this data, I need to make a table. The trick here is that I need to use some of the property names as the column headers but exclude others.
My table is very basic, it contains the persons name and then all of the dynamic column names:
<table class="table table-condensed" border="1">
<thead>
<tr>
<th>Employee Name</th>
<th *ngFor="let m of columnNames">{{ m }}</th>
</tr>
</thead>
<tbody>
<!-- Example Record 0 -->
<tr>
<td>Bob Jones</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
</tr>
<!-- Example Record 0 -->
</tbody>
</table>
The first thing I did in order to get the column names is create an array of the IgnoreColumns which is the property names I wan't to exclude from being its own column in the table.
// Hold all of the column names
private columnNames = [];
// Ignore these columns, they dont get printed as headers
private ignoreColumns = ['CostCenter', 'FirstName', 'LastName', 'UID'];
I then looped over the first record in the result set and pushed all of the property names to an array that are not in our ignoreColumns array. This leaves me with a unique array of the dynamic columns.
// Find all the keys in our first result
for (var p in dataObj[0]) {
// Get the key names
if (dataObj[0].hasOwnProperty(p)) {
// If this key name doesnt already exist in the array AND its not in our ignored list push them to our array
if (!_.includes(this.columnNames, p) && !_.includes(this.ignoreColumns, p)) {
this.columnNames.push(p);
}
}
}
I am stuck at this point. I was able to create the table structure with the headings in place but I don't know how I should proceed to get the data aligned under the correct columns in the table.
This is what I am going for in my final output:
<table class="table table-condensed" border="1">
<thead>
<tr>
<th>Individual</th>
<th>HasLevel1Access</th>
<th>HasLevel2Access</th>
<th>HasLevel3Access</th>
</tr>
</thead>
<tbody>
<tr>
<td>Bob Jones</td>
<td>No</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Tommy C</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
</tr>
<tr>
<td>Smithson J</td>
<td>Yes</td>
<td>No</td>
<td>Yes</td>
</tr>
</tbody>
</table>
Here is a plunkr of where I am at: http://plnkr.co/edit/9WygBXsQaDaxTMudb7ZB?p=preview
Any advice on how to approach this?
What about
<tr *ngFor="let item of dataObj">
<td>{{item.FirstName}} {{item.LastName}}</td>
<td *ngFor="let m of columnNames">{{item[m]}}</td>
</tr>
Working demo
You meant something like this?
<tr *ngFor="let data of dataObj">
<td>{{data.FirstName+" "+data.LastName}}</td>
<td>{{data.HasLevel1Access}}</td>
<td>{{data.HasLevel2Access}}</td>
<td>{{data.HasLevel3Access}}</td>
</tr>
http://plnkr.co/edit/EHsVFaiaK1UUcWrbm6zX?p=preview
I have the following bootstrap based table and I am trying to calculate the total MarketValue. Its reading an external json file. but for some reason its not adding the values.
the problem starts when i load an external json. file. How can i fix this?
$.getJSON("json/prep.json", function (jsonFromFile) {
$('#table1').bootstrapTable({
data: jsonFromFile.rows
})
var total1 = data.reduce(function(a, b){
return a + parseFloat(b.LongMarketValue);
}, 0);
document.querySelector('.total1').innerHTML = total1;
});
JSON - prep.json
{
"Name": "Julie Brown",
"Account": "C0010",
"LoanApproved": "12/5/2015",
"LastActivity": "4/1/2016",
"PledgedPortfolio": "1000",
"MaxApprovedLoanAmt": "10000",
"LoanBalance": "1849000",
"AvailableCredit": "2877.824375",
"Aging": "3",
"Brokerage": "My Broker",
"Contact": "oJohnson",
"ContactPhone": "-3614",
"RiskCategory": "Yellow",
"rows": [{
"Account": "086-1234",
"ClientName": "S Smth",
"AccountType": "tail",
"LongMarketValue": "$40000"
}, {
"Account": "086-1235",
"ClientName": "all Sth",
"AccountType": "REV Trust",
"LongMarketValue": "$55000"
},
{
"Account": "086-1236",
"ClientName": "Sly Smith",
"AccountType": "Reail",
"LongMarketValue": "$5500"
}]
}
HTML
<table id="table1">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="Account">Account #</th>
<th data-field="ClientName">Client</th>
<th data-field="AccountType">Account Type</th>
<th data-field="MarketValue"> Market Value</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<th></th>
<th> Total <span class="total1"></span></th>
</tr>
</tfoot>
</table>
data is undefined in your code, you have to retrieve data from table or from Json. Also your data returns a string with $ sign, so you have to remove it before parsing it.
Here is a working example.
// Code goes here
$(function () {
$.getJSON("https://api.myjson.com/bins/89vsf", function (jsonFromFile) {
$('#table1').bootstrapTable({
data: jsonFromFile.rows
})
var data = $('#table1').bootstrapTable('getData');
var total1 = data.reduce(function(a, b){
return a + parseFloat(b.LongMarketValue.replace('$',''));
}, 0);
document.querySelector('.total1').innerHTML = total1;
});
});
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table id="table1">
<thead>
<tr>
<th data-field="state" data-checkbox="true"></th>
<th data-field="Account">Account #</th>
<th data-field="ClientName">Client</th>
<th data-field="AccountType">Account Type</th>
<th data-field="LongMarketValue"> Market Value</th>
</tr>
</thead>
<tfoot>
<tr>
<td></td>
<td></td>
<td></td>
<th></th>
<th> Total <span class="total1"></span></th>
</tr>
</tfoot>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://rawgit.com/wenzhixin/bootstrap-table/master/src/bootstrap-table.js"></script>
<script src="script.js"></script>
</body>
</html>
Here is a working plunker of the code. http://plnkr.co/edit/PSCR5iS7DSWkuQb1jv5P?p=preview
Hope this helps.
Let us assume we have following data structure:
var data = [
{
name: "item name",
nestedData: [{
name: "nested name",
quantity: 1
},
{
name: "nested name 2",
quantity: 2
}
]
},
{
name: "item name 2",
nestedData: [{
name: "nested name 3",
quantity: 3
}
]
}
];
Standard behavior of ng-repeat directive will iterate over high level elements. If we run ng-repeat="item in data" it will produce two items.
Is it possible - without using custom directive - to iterate over first item ("item name") twice (multiply it by a length of nestedData array)?
The output I'd like to achieve is:
<table>
<thead>
<th>Name</th>
<th>Nested name</th>
<th>Nested quantity</th>
</thead>
<tbody>
<tr>
<td rowspan="2">item name</td>
<td>nested name</td>
<td>1</td>
</tr>
<tr>
<td ng-hide="true">item name</td>
<td>nested name 2</td>
<td>2</td>
</tr>
<tr>
<td>item name 2</td>
<td>nested name 3</td>
<td>3</td>
</tr>
</tbody>
</table>
Nested ng-repeat is not suitable in this situation because there's a need to iterate over <tr>'s.
You can use a nested ng-repeat to get your desired result as it's valid HTML to have multiple tbody elements.
Here is a JSFiddle for a working example
<table>
<thead>
<th>Name</th>
<th>Nested name</th>
<th>Nested quantity</th>
</thead>
<tbody ng-repeat="item in data">
<tr ng-repeat="nestedItem in item.nestedData">
<td rowspan="{{item.nestedData.length}}" ng-hide="$index == 1">{{item.name}}</td>
<td>{{nestedItem.name}}</td>
<td>{{nestedItem.quantity}}</td>
</tr>
</tbody>
</table>
It's a different approach to achieve expected output.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
var data = [
{
name: "item name",
nestedData: [
{
name: "nested name",
quantity: 1
},
{
name: "nested name 2",
quantity: 2
},
{
name: "nested name 3",
quantity: 3
}
]
},
{
name: "item name 2",
nestedData: [{
name: "nested name 3",
quantity: 3
}
]
}
];
var nestedData = [];
angular.forEach(data, function(item){
if(item.nestedData.length > 1){
angular.forEach(item.nestedData, function(nestedItem){
nestedData.push({
name : item.name,
nestedName: nestedItem.name,
nestedQty: nestedItem.quantity,
colspan: item.nestedData.length
});
});
} else {
nestedData.push({
name : item.name,
nestedName: item.nestedData[0].name,
nestedQty: item.nestedData[0].quantity
});
}
});
$scope.data = nestedData;
});
tr.multiple > td:first-child {
display: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<div class="container" ng-app="myApp" ng-controller="myCtrl">
<table class="table table-stripped">
<thead>
<th>Name</th>
<th>Nested name</th>
<th>Nested quantity</th>
</thead>
<tbody>
<tr ng-repeat="item in data" ng-class="{'multiple': item.colspan > '1' && !$first}">
<td rowspan="{{item.colspan ? item.colspan : '1'}}">{{item.name}}</td>
<td>{{item.nestedName}}</td>
<td>{{item.nestedQty}}</td>
</tr>
</tbody>
</table>
</div>