Vue.js get unknown Json key for v-for - javascript

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.

Related

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>

Internationalization of dynamic content in Angular?

Angular.io describes the i18n tag as follows:
The Angular i18n attribute marks translatable content. Place it on
every element tag whose fixed text is to be translated.
So my question is this. What if I have an element whose content is dynamic? Take for example this below table that shows a list of assets. The column, "Description" needs to be in some cases English, and in some cases some other language.
<table class="asset-table">
<thead>
<tr>
<th i18n="##alarm-list-timeon">Time On</th>
<th i18n="##alarm-list-timeoff">Time Off</th>
<th i18n="##alarm-list-asset">Asset</th>
<th i18n="##alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n>{{asset.description}}</td>
</tr>
</tbody>
</table>
I was thinking something like this:
<table class="asset-table">
<thead>
<tr>
<th i18n="##alarm-list-timeon">Time On</th>
<th i18n="##alarm-list-timeoff">Time Off</th>
<th i18n="##alarm-list-asset">Asset</th>
<th i18n="##alarm-list-description">Description</th>
</tr>
</thead>
<tbody *ngIf="showAssets">
<tr *ngFor="let asset of pageItems">
<td>{{asset.timeon}}</td>
<td>{{asset.timeoff}}</td>
<td>{{asset.assetlabel}}</td>
<td i18n="##{{asset.description}}">{{asset.description}}</td>
</tr>
</tbody>
</table>
...but I was mistaken. Any suggestions?
First, the i18n value is an ID, so it would always be static.
Second, as far as translating content that changes, the only success I have had is a workaround using NgSwitch in the template.
In this example, thingStatus is your variable, and its possible values are 'good', 'bad', and 'unknown'. All of these would each be a separate translation item, with its own i18n ID value.
Obviously, this would fail if thingStatus could have an unmanageable number of possibilities.
<div [ngSwitch]="thingStatus">
<p *ngSwitchCase="good" i18n="status_good>Good</p>
<p *ngSwitchCase="bad" i18n="status_bad>Bad</p>
<p *ngSwitchCase="unknown" i18n="status_unknown>Unknown</p>
</div>
Use this construction
<span
i18n="status text|Status text##statusText"
>{
asset.statusLangCode, select,
bad {Bad}
good {Good}
other {Unknown}
}</span>
And in translation file there will be generated a construct like this (target is added manually)
<source>{VAR_SELECT, select, good {Good} bad {Bad} other {Unknown}}</source>
<target>{VAR_SELECT, select, good {Хороший} bad {Плохой} other {Неизвестный}}</target>
For more info see https://angular.io/guide/i18n#translate-select
Assuming that your backend service returns known possible values, you can do the following:
const values = ['admin', 'teacher', 'librarian']
Add the translated values to sv_SE.json given the previous values as keys
role: {
"admin": "admin",
"teacher": "lärare",
"librarian": "Bibliotekarie"
}
Call the translation in your app.component.html
<div *ngFor="let value of values">
{{ ('role.' + value) | translate }}
</div>

How to get checkboxes to initialize based on model?

I am writing my first non-tutorial angular.js web app. I am using two smart-tables and checklist-model. Here is the first one that uses a st-safe-src of all_types that is an array of json objects that look like this ...
[
{
"_id": "56417a9603aba26400fcdb6a",
"type": "Beer",
"__v": 0
},
{
"_id": "56456140cb5c3e8f004f4c49",
"type": "Skiing",
"__v": 0
},
...
Here is the html for the table I use to display this data:
<table st-table="displayedCollection" st-safe-src="all_types" class="table table-striped">
<thead>
<tr>
<th st-sort="type">Types</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in displayedCollection">
<td><input type="checkbox" checklist-model="vendor.types" checklist-value="x.type">{{x.type}}</td>
</tr>
<tr><td>id ({{curid}}) {{vendor.types}}</td></tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
This table looks like this when I load data into it. The checkboxes get checked to match the data from my model.
But when I try to do the same thing in a second smart table with more complete json objects that look like this ...
[
{
"_id": "569f047dd90a7874025b344e",
"product_title": "Plugs",
"product_img_001": "p001.jpg",
"product_img_002": "p002.jpg",
"product_vid_001": "bp.mov",
"__v": 0,
"product_sizes": [
"Large",
"Med.",
"Small",
"10.5"
],
"product_types": [
"Running Shoe"
]
},
{
"_id": "569f3958b108a7d70201b89a",
"product_title": "Back Scratcher",
"product_img_001": "http://itchy.png",
"product_img_002": "http://relief-at-last.png",
"product_vid_001": "my-itch",
"__v": 0,
"product_sizes": [
"Large"
],
"product_types": [
"Rocks"
]
}
]
Here's the html I am using to display this data in a smart table:
<table st-table="prodCollection" st-safe-src="all_products" class="table table-striped">
<thead>
<tr>
<th st-sort="type">Products</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in prodCollection">
<td><input type="checkbox" checklist-model="vendor.products" checklist-value="x">{{x.product_title}}</td>
</tr>
<tr><td>{{vendor.products}}</td></tr>
</tbody>
<tfoot>
<tr>
<td colspan="5" class="text-center">
<div st-pagination="" st-items-by-page="itemsByPage" st-displayed-pages="7"></div>
</td>
</tr>
</tfoot>
</table>
This table looks like this when I load data into it:
I had hoped that the checkbox would be checked, but they do not get checked.
If make this change ...
<td><input type="checkbox" checklist-model="vendor.products" checklist-value="x.product_title">{{x.product_title}}</td>
... the correct checkboxes get checked but just the product's title will be posted. What do I need to do to get the checkboxs to display checked and be able to post the whole product data?
I have added a plunker example: http://plnkr.co/edit/aPCEBV5e9Pb5np9iaY2l
You can use as checklist-value the id instead of the Object as say section on doc Array of objects (pick id)
<input type="checkbox" checklist-model="vendor.products" checklist-value="x._id">
Or if you need use the Object as selected products (checklist-value="x") you need use checklist-comparator because in your plunker the selected array and full product list don't have the same references. The comparator must match the equal objects by _id. Try this
<input type="checkbox" checklist-comparator="._id" checklist-model="vendor.products" checklist-value="prod" />
There is an option called ng-true-value="1". This will check with the values of the ng-model. It will work like if(ng-model(Name) == 1). Try this out.
<input type="checkbox" name="checkbox_demo_4" id="checkbox_demo_4"
ng-model="temp.taxable_type"
ng-true-value="1"
/>
In this, 1 is the true value that I stored in the DB. So it is checking automatically if the ng-model value contains 1.
All the best.
After reading carefully your question, and supossing that you want the same behaviour as the first smart table, the problem I think you had can be solved by
setting the product_title as the checklist-value of the input field, something like this :
<input type="checkbox" checklist-model="vendor.products" checklist-value="prod.product_title" />
Here the plunkr associated
http://plnkr.co/edit/5an1Fx?p=preview

From DB they are sending HTML, how to render it in the DOM?

I am receiving an object like this
[
{
"BET": 57630343,
"CUSTOMER": 181645,
"SPORT": "MLB",
"XX_FILL OPEN": "<button class=\"btn\" onclick=\"fillOpen(57630343)\">Fill Open</button>",
"XX_VIEW": null,
"XX_CANCEL": "<input type=\"checkbox\" name=\"sports\" value=\"soccer\" onchange=\"fillOpen(57630343)\"/>"
},...]
I am rendering that object in the DOM, but for now, looks like in the picture below
here is the HTML part for the dynamic table
<table>
<thead>
<tr>
<th ng-repeat="column in cols" ng-init="isXX = column.indexOf('XX') === 0">
<span ng-if="isXX">{{column.substring(3).replace('_', ' ')}}</span>
<span ng-if="!isXX">{{column}}</span>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols">
<span>{{row[column]}}</span>
</td>
</tr>
</tbody>
</table>
and here is the Angular part
ReportsFactory.pendingBets(reportParam).then(function(data) {
if (data.length) {
gridInfo = _.forEach(data, function(item) {return item;});
$scope.rows = gridInfo;
$scope.cols = Object.keys($scope.rows[0]);
}
}
The Database guys are sending me that data as you see it in the json I pasted above.
what I need to know, is, what should I do in order to render those elements in the DOM ?
You can use ngBindHtml for that.
<tbody>
<tr ng-repeat="row in rows">
<td ng-repeat="column in cols" ng-bind-html="row[column]">
</td>
</tr>
</tbody>
Since you're getting the HTML from a $http call, you have to use $sce.trustAsHtml to correctly display this HTML on every single one of your row columns that require this:
$scope.rows.forEach(function(row) {
for (var key in row) {
if (key.indexOf('XX') === 0) {
var value = row[key];
if (value) {
row[key] = $sce.trustAsHtml(value);
}
}
}
});
Here's a working plunkr:http://plnkr.co/edit/7iFUhjg6Q0YIwRi47fDm?p=preview
You can do it by using ngSanitize.
Check it here. https://docs.angularjs.org/api/ngSanitize
Then, you can use ng-bind-html directive, which render HTML code to DOM element.
And, Javascript in the element can be applied with trustAsHtml method of $sce service.
I made an example here.
http://plnkr.co/edit/sTEUIWHwGXSAUSQ2rC8y?p=preview

delete all datatables using jQuery

so, I am using datatables along with jQuery, and am a bit stumped as to why this is not working. My HTML looks like this:
<table id="surnamePrimaryPartitionTable" border=1 class="display partitionDisplay">
<caption>Partitions</caption>
<thead>
<tr style="background-color: #afeeee;">
<th>Partition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
I have several tables, each of which follows a similar format, and each of which uses the partitionDisplay class (really just a class that I use so that I can select all the tables later using jQuery).
So, the problem arises when I try to destroy the datatables. Here is what I have:
function DeletePartitionInformation(data) {
jQuery(".partitionDisplay").each(function(){
jQuery(this).dataTable().fnDestroy();
});
jQuery("table tbody").each(function() {
jQuery(this).html("");
})
}
This code seems to work correctly for the first table, but throws an exception and doesn't work on any subsequent tables. The javascript error message I am getting is the following:
Uncaught TypeError: Cannot read property 'asSorting' of undefined
A quick Google search on this error says that it generally arises from having elements nested in a tag. This does not appear to be the problem, however. I will post the code for the other three tables to demonstrate this:
<table id="surnamePrimarySubpartitionTable" border=1 class="display partitionDisplay">
<caption>SubPartitions</caption>
<thead>
<tr style="background-color: #afeeee;">
<th>Partition</th>
<th>SubPartition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
<th>Begin</th>
<th>End</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table id="givenNullSurnamePartitionTable" border=1 class="display partitionDisplay">
<caption>Partitions</caption>
<thead>
<tr style="background-color: #98fb98;">
<th>Partition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<table id="givenNullSurnameSubpartitionTable" border=1 class="display partitionDisplay">
<caption>SubPartitions</caption>
<thead>
<tr style="background-color: #98fb98;">
<th>Partition</th>
<th>SubPartition</th>
<th>CPU %</th>
<th>Search Count</th>
<th>Person Count</th>
<th>Disk Space</th>
<th>Begin</th>
<th>End</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
One final note: I am actually able to get the behavior I want if I use the below code. Obviously I would prefer not to, however, since I'd really like to loop over the elements rather than hard-code the element id's in.
function DeletePartitionInformation(data) {
jQuery("#surnamePrimarySubpartitionTable").dataTable().fnDestroy();
jQuery("#surnamePrimaryPartitionTable").dataTable().fnDestroy();
jQuery("#givenNullSurnameSubpartitionTable").dataTable().fnDestroy();
jQuery("#givenNullSurnamePartitionTable").dataTable().fnDestroy();
jQuery("table tbody").each(function() {
jQuery(this).html("");
})
}
Uncaught TypeError: Cannot read property 'asSorting' of undefined
This seems to suggest it may be trying to destroy dataTables that weren't created.
The static fnTables should give you an Array of only the <table> elements with a dataTable:
var tables = $.fn.dataTable.fnTables(true);
$(tables).each(function () {
$(this).dataTable().fnDestroy();
});

Categories

Resources