Populate cells without knowing the data key - javascript

My data is an array of objects with key-value pairs. I'm trying to populate a table with the data in a polymer component. If I use the key explicitly, it works. Here is an example with "FacilityId":
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<template is="dom-repeat" items="{{columns}}">
<th>{{item}}</th>
</template>
</tr>
</thead>
<tbody>
<template is="dom-repeat" items="{{data}}">
<tr>
<td>{{item.FacilityId}}</td>
</tr>
</template>
</tbody>
</table>
However, as you can see from the dynamically generated columns, I don't always know what the keys will be named. I tried using {{item[0]}} but that doesn't work, and even if it did I won't know how many there will be. I also tried using a nested template but I couldn't figure it out.
Here is what my data looks like (again, the number and names of fields could vary though):

Based on the answer referenced by #David R, this works:
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<template is="dom-repeat" items="{{columns}}">
<th>{{item}}</th>
</template>
</tr>
</thead>
<tbody>
<template is="dom-repeat" items="{{data}}">
<tr>
<template is="dom-repeat" items="{{_toArray(item)}}">
<td>{{item.value}}</td>
</template>
</tr>
</template>
</tbody>
</table>
And the custom function from https://stackoverflow.com/a/30794220/736893:
Polymer({
is: 'widget-table',
properties: {
data: {
type: Array,
value: function() {return []}
}
},
_toArray: function(obj) {
return Object.keys(obj).map(function(key) {
return {
name: key,
value: obj[key]
};
});
}
});

Related

Get value from array data in Vue

I'm kinda new to Vue and i'm struggling to get one value from an array. I'm making an axios get request where I return an array of users containing the values (name, display_name, role, and few others fields). I'm able to get all these values and mount my table with the component below:
<template>
<div class="container">
<table class="mt-3 table roboto table-stripped table-hover table-sm">
<thead class="thead-light">
<th>Name</th>
<th>Username</th>
<th>Profile</th>
<th class="text-center">Is manager</th>
</thead>
<tbody v-for="user in users">
<td v-text="user.name"></td>
<td v-text="user.username"></td>
<td v-text="user.display_name"></td>
<td class="text-center">
<button
class="letter-shadow btn-sm font-500 grey-darkest roboto letter-spacing"
:class="showRole">Activate
</button>
</td>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
users: [],
}
},
computed: {
showRole() {
// wanted to diff button colors here
}
},
mounted() {
axios.get('/api/users').then(response => this.users = response.data);
},
}
</script>
So I wanted to modify that class showRole depending on the value of user.display_name, if the user.display_name is equal to "Manager" e.g. I would show a btn-danger. I just don't know how can I get this value to compare, if I try to use this.user.display_name on showRole method I get nothing (undefined). Thanks for any help.
I think you should use a method instead, as you can't pass parameters to computed properties.
Use this
...
methods : {
showRole(user){
//code that returns the button class
}
}
...
<button :class="showRole(user)">Activate

How can I retrieve data from an array which is inside another array and display it in the table?

Using Vue.js , I am able to retrieve and display id,description and location, but why in the tasks column I only have [object Object] in all the rows ?!
(tasks is an array inside jobs array)
<template>
<div>
...
<table class="table table-hover">
<thead>
<tr>
<th v-for="column in columns">
...
</th>
</tr>
</thead>
<tbody>
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="tasks in jobs" >{{work["tasks"]}}</td>
</tr>
</tbody>
</table>
<script>
export default{
data : function() {
return{
columns: ['id', 'description', 'location', 'tasks'],
jobs: '',
update: this.getData()
}
},
methods: {
//to get data from the backend API
getData() {
this.$http
.get('http://localhost:3001/api', (data) => {
this.jobs = data["jobs"]
})
}
}
</script>
You are iterating over jobs and not each task inside the job's tasks
You should do something like -
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks" >{{task["id"]}} -
{{task["description"]}} - {{task["location"]}}</td>
</tr>
Or however you want to display there. But the idea should be to iterate on the tasks array inside each work object
You'll need to explicitly extract the fields that you want to show from tasks. Also, the syntax for the nested v-for would be something like task in work.tasks, so that your task points to each task inside of your tasks array for each work:
<tr v-for="work in jobs">
<td>{{work["id"]}}</td>
<td>{{work["description"]}}</td>
<td>{{work["location"]}}</td>
<td v-for="task in work.tasks">
{{task["id"]}} <br>
{{task["description"]}} <br>
{{task["location"]}}
</td>
</tr>

Vue.js get unknown Json key for v-for

I built a code analysis tool and I want to set my json Data in a vue Table. However, I need the json Key, which is the Package/File name to the directory which data I want to show.
Here is the json Part (NULLY is the Package):
"folderStatistics": {
"NULLY": {
"Statistiken": {
"Werte": {
"Felder": "0",
"Konstruktoren": "0",
"Methoden": "8",
"Klassen": "1",
"Codezeilen": "191"
}
},
and this is my HTML:
<table class="table table-bordered">
<thead>
<tr>
<th></th>
<th>Felder</th>
<th>Konstruktoren</th>
<th>Methoden</th>
<th>Klassen</th>
<th>Codezeilen</th>
</tr>
</thead>
<tbody>
<tr v-for="value in folderStatistics.NULLY.Statistiken">
<td>{{$key}}</td>
<td>{{value.Felder}}</td>
<td>{{value.Konstruktoren}}</td>
<td>{{value.Methoden}}</td>
<td>{{value.Klassen}}</td>
<td>{{value.Codezeilen}}</td>
</tr>
</tbody>
With "NULLY", it works the Directory, but NULLY should be dynamic.
How can I make that? Does it even work?
documentation
You can have NULLY in a variable say package and use it in view like following:
<tbody>
<tr v-for="(value, key) in folderStatistics[package].Statistiken">
<td>{{key}}</td>
<td>{{value.Felder}}</td>
<td>{{value.Konstruktoren}}</td>
<td>{{value.Methoden}}</td>
<td>{{value.Klassen}}</td>
<td>{{value.Codezeilen}}</td>
</tr>
</tbody>
demo fiddle.

How to iterate over filtered rows in Angular datatable

Lets say, I have simple datatable
<table datatable="" dt-options="dtOptions" dt-column-defs="dtColumnDefs" class="row-border hover">
<thead>
<th>ID</th>
<th>Name</th>
</thead>
<tbody>
<tr ng-repeat"reservation in reservations">
<td>{{reservation.ID}}</td><td>{{reservation.name}}</td>
</tr>
</tbody>
</table>
When I put some string into search box datatable is being filtered. Now I want to iterate in Angular over filtered rows and read IDs to array. How to deal with it in Angular? I can use jquery but I do not want make a mess in code.
$scope.addressDTInstance = {};
var j = $scope.addressDTInstance.DataTable.rows();
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
This is something to get you on your way. Need an instance of dtInstance which you don't have. So add dt-instance='dtInstance' in the html table tag.
Then initiate it at the top of your controller, $scope.dtInstance = {};.
Perform a click or some action in your javascript that you can set a break point on and then examine your $scope.dtInstance to see what all properties and methods you have. As you see in my snippet I'm accessing DataTable.Rows of my dtInstance. If you need better example or help let leave me a comment and I'll revise.
UPDATE
Here is a method I found that works. I am ofcourse using the DTOptionsbuilder. This will get called twice, first when it is created and second when i populated the array variable that is populating my table. I just check to see if rows exist and that the first one isn't 'No results'.
$scope.addressdtOptions = DTOptionsBuilder.newOptions()
.withOption('bFilter', false)
.withOption('bInfo', false)
.withOption('paging', false)
.withOption('processing', true)
.withOption('aaSorting', [1, 'asc'])
.withOption('language', { zeroRecords: 'No results' })
.withOption('initComplete', function () {
var rows = $("#addressSelectionTable > tbody > tr");
if (rows.length > 0 && rows[0].innerText !== "No results") {
var x = 3;
}
});
Here i am setting that variable that is ng-repeat for table. You may not be doing it my way, but you should be able to figure it out for your way.
$.when($OfficerService.GetAddressSelections($scope.officer.EntityID, $scope.officer.EntityTypeID, $scope.officer.MemberID)).then(function (result) {
$scope.addresses = result.data;
$scope.$applyAsync();
});
<table id="addressSelectionTable" class="table table-condensed table-bordered" datatable="ng" dt-options="addressdtOptions" dt-column-defs="addressdtColumnDefs" dt-instance="addressDTInstance">
<thead>
<tr>
<th></th>
<th>Type</th>
<th>Address</th>
<th>City</th>
<th>State</th>
<th>Zip</th>
<th>Country</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="a in addresses">
<td class="centerColumn">
<input type="button" class="btn btn-primary" value="Select" ng-click="selectAddress(a.AddressID,a.AddressLocationCode,$event)" />
</td>
<td>
<span ng-if="a.AddressLocationCode == 'E'">Office</span>
<span ng-if="a.AddressLocationCode == 'M'">Member</span>
</td>
<td>
{{a.AddressLine1}}
<span ng-if="a.AddressLine2 != null"><br /> {{a.AddressLine2}}</span>
</td>
<td>{{a.City}}</td>
<td>{{a.StateCode}}</td>
<td>{{a.Zip}}</td>
<td>{{a.CountryCode}}</td>
<td>{{a.AddressID}}</td>
</tr>
</tbody>
</table>
For me it works: $scope.dtInstance.DataTable.rows( { search: 'applied' } ).data()

emberjs nested {{#each}} not working

i am very new to ember js.
i am trying to form a data grid in my page.
modal
{
"tableView":{
"columns":[{"name":"EmpName","datatype":"string"},{"name":"Age","datatype":"numeric"}],
"records":[{"EmpName":"Ramesh","Age":12},{"EmpName":"Mukesh","Age":31},{"EmpName":"Mahesh","Age":22}]
}
}
template
<script type="text/x-handlebars" data-template-name="grid">
<table>
<thead>
<tr>
{{#each tableView.columns}}
<th> {{name}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each record in tableView.records}}
<tr>
{{#each column in tableView.columns}}
<td>{{record[column.name]}}</td>
{{/each}}
</tr>
{{/each}}
</tbody>
</table>
</script>
In result, the table header with the columns is showing correctly.
but the data is not generated in the table and no error.
am i doing anything wrong in the inner {{#each}}??
To render the table with records you try something like,
http://emberjs.jsbin.com/nahanoje/1/edit
hbs
<table>
<thead>
<tr>
{{#each model.tableView.columns}}
<th> {{name}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each record in model.tableView.records}}
<tr>
<td>{{record.EmpName}}</td>
<td>{{record.Age}}</td>
</tr>
{{/each}}
</tbody>
</table>
In the original code posted the {{record[column.name]}} part will not work.
If you need to have a nested {{each}} helper to get dynamically the values of an arbitrary number of columns, then a registered helper for this specific task will really assist.
http://emberjs.jsbin.com/foqohibe/1/edit
js
App.IndexRoute = Ember.Route.extend({
model: function() {
var data = {
"tableView":{
"columns":[{"name":"EmpName","datatype":"string"},{"name":"Age","datatype":"numeric"}],
"records":[{"EmpName":"Ramesh","Age":12},{"EmpName":"Mukesh","Age":31},{"EmpName":"Mahesh","Age":22}]
}
};
return data;
}
});
Ember.Handlebars.helper('getRecord', function(value, options) {
var record = arguments[0];
var columnName = arguments[1];
return new Handlebars.SafeString(record[columnName]);
});
hbs
<table>
<thead>
<tr>
{{#each model.tableView.columns}}
<th> {{name}}</th>
{{/each}}
</tr>
</thead>
<tbody>
{{#each record in model.tableView.records}}
<tr>
{{#each column in model.tableView.columns}}
{{#with column}}
<td>{{getRecord record name}}</td>
{{/with}}
{{/each}}
</tr>
{{/each}}
</tbody>
</table>

Categories

Resources