I'm trying to add an image to a specific row. I have numerous of images that I'm trying to add to a table and this Google image keeps popping up in every row instead of just one. I have a snippet of the code where I'm adding the image and the parameters for each row. I was trying to add the image by doing {{link.img}} like the website, URL, and description but that didn't work either. Below is a snippet of the code that has a screenshot of what's printing out. I would like to get {{link.img}} working if possible so I can be consistent with all the other parameters, but if that's not feasible that's fine. Any assistance will be greatly appreciated. Thanks
image of table
LINKS = [
{
'id': uuid.uuid4().hex,
'img': "../assets/ipts.png",
},
{
'id': uuid.uuid4().hex,
'img': "../assets/express.png",
}
]
<table class="table table-hover">
<thead>
<tr>
<th scope="col"></th>
<th scope="col">Website</th>
<th scope="col">URL</th>
<th scope="col">Description</th>
<th></th>
</tr>
</thead>
<tbody>
<tr v-for="(link, index) in links" :key="index">
<!--<td>{{ link.img }}</td>-->
<td>
<img v-bind:src="link.img" width="21" height="21">
<img src = "../assets/google-logo.png" width="21" height="21">
</td>
<!--<td>{{ link.website }} </td>-->
<td>{{ link.website }}</td>
<td>{{ link.URL }}</td>
<td>{{ link.description }}</td>
<td></td>
</tr>
</tbody>
</table>
Use the object data keys without qoute sign as follows :
'id'=> id and ........
links = [
{
id: uuid.uuid4().hex,
img: "../assets/ipts.png",
},
{
id: uuid.uuid4().hex,
img: "../assets/express.png",
}
]
Related
Can I use an ngFor instead of repeating <table> two times?
NB: I thought to combine all the items into objects as items of a single array of mapping(each object contains a variable, label and value) but it does not work for me)
....
this.maxValueTable.push(selectedData.res.maxValue);
this.minValueTable.push(selectedData.res.minValue);
...
<div style="display: flex;">
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let maxValue of maxValueTable">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
<table style="width:100%;">
<thead>
<tr>
<th>Min</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let maxValue of minValueTable">
<td> {{ MinValue| numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
</div>
Another way:
<!--create an array directly in the .html: you can also use
a variable in your .ts-->
<table *ngFor="let table of [{head:'Max',data:maxValueTable},
{head:'Max',data:maxValueTable}]
style="width:100%;">
<thead>
<tr>
<!--use table.head-->
<th>{{table.head}}</th>
</tr>
</thead>
<tbody>
<!--see how iterate over table.data-->
<tr *ngFor="let maxValue of table.data">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
</tr>
</tbody>
</table>
If your arrays has the same length and only want a table, iterate over one array ans use the index to get the value of the another one
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
<th>Min</th>
</tr>
</thead>
<tbody>
<!--see the "let i=index"-->
<tr *ngFor="let maxValue of maxValueTable;let i=index">
<td> {{ maxValue | numberFormatter: (getUnit() | async)}}</td>
<!--use the "index" "i" to get the element of the another array-->
<td>
{{ minValueTable[i] | numberFormatter: (getUnit() | async)}}
</td>
</tr>
</tbody>
</table>
in this case you can also use map to create a new Array
minMax=this.minValueTable.map((x,index)=>({
min:x,
max:this.maxValueTable[index]
}))
And use {{value.min}} and {{value.max}}
You can create a function that will combine min and max values into an array like that:
mergeIntoArray(maxValue: Array<number>, minValue: Array<number>): IMergedObj[] {
let mergedArray = [];
maxValue.forEach((value, index) => {
let tempObj = {};
tempObj['maxValue'] = value;
tempObj['minValue'] = minValue[index];
mergedArray.push(tempObj);
});
return mergedArray;
}
and call this function like that:
let minAndMax = [];
this.minAndMax = this.mergeIntoArray(this.maxValueTable, this.minValueTable);
after that, use this variable (minAndMax) in your HTML template. This way you do not need to use ngFor twice.
<table style="width:100%;">
<thead>
<tr>
<th>Max</th>
<th>Min</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let item of minAndMax">
<td>{{ item.maxValue }}</td>
<td>{{ item.minValue }}</td>
</tr>
</tbody>
</table>
Here is the stackblitz link created for you. Hope that might help you.
You can use *ngTemplateOutlet for this case:
<div style="display: flex;">
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: maxValueTable, header: 'Max'}"></ng-container>
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: minValueTable, header: 'Min'}"></ng-container>
</div>
<ng-template #tableTemplate let-values, let-header="header">
<table style="width:100%;">
<thead>
<tr>
<th>{{ header }}</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let value of values">
<td> {{ value | numberFormatter: (getUnit() | async) }}</td>
</tr>
</tbody>
</table>
</ng-template>
And you will get the same table rendered twice - for Max and Min values.
As you can see, the arguments are passed as a second argument inside ngTemplateOutlet:
context: {$implicit: valuesArgument, header: headerArgument}
Later you could use this template to create infinite amount of tables:
<div *ngFor="let table of tables">
<ng-container *ngTemplateOutlet="tableTemplate; context: {$implicit: table.values, header: table.header}"></ng-container>
</div>
Assuming your tables property will look like
export class C {
tables: Table[] = [{header: 'Min', values: [1, 2, 3]}, {header: 'Max', values: [4, 5, 6]}, {header: 'Other', values: [0, -1, -2]}]
}
I have a problem with laravel and vue about displaying the result from database table find method. What I don't quite understand is why the v-for directive parsing the json result incorrectly.
Here is the Vue code :
<template>
<table class="table table-hover">
<thead>
<tr>
<th>Class</th>
<th>Amount of Students</th>
<th>Teacher</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="classroom in classrooms" :key="classroom.id">
<td>{{ classroom.class_no }}•{{ classroom.field }}•{{ classroom.room_no }}</td>
<td>{{ classroom.amount_students }}</td>
<td>{{ classroom.teacher }}</td>
<td>
<a href="#">
<i class="fa fa-edit blue"></i>
</a>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
data () {
return {
classrooms : {
"success": true,
"data": { "id": 1, "class_no": 1, "field": "Architecture", "room_no": 4, "amount_students": 40, "teacher": "Bobby Fisher" },
"message": "Find Classroom Detail"
}
}
}
}
</script>
The json classrooms itself is actually the result from the controller :
public function show($level)
{
$classrooms = ClassRoom::where('class_no', $level)->firstOrFail();
return $this->sendResponse($classrooms , 'Find Classroom Detail');
}
And here is screenshot of the wrong result :
The result should be only a single row
Please help me to solve this problem.
Actually, as you are iterating over the classrooms which is an object having three keys, so the for loop is iterating over each key once.
If you only want to iterate over the data key then just return the data from the backend.
You can use a v-if condition to check whether the current key contains a class_no and if yes then display the row otherwise not.
<tr v-for="classroom in classrooms" :key="classroom.id" v-if="classroom.class_no">
<td>{{ classroom.class_no }}•{{ classroom.field }}•{{ classroom.room_no }}</td>
<td>{{ classroom.amount_students }}</td>
<td>{{ classroom.teacher }}</td>
<td>
<a href="#">
<i class="fa fa-edit blue"></i>
</a>
</td>
</tr>
Looking at your Vue data attribute, you want to use v-for="classroom in classrooms.data".
And if you are getting the data from API then you don't want to assign the full response to your classroom data attribute but assign response.data to classroom, so you can do
v-for="classroom in classrooms".
This will work unless your API returns data in a different format.
you can check on JsFiddle
https://jsfiddle.net/JManish/9qjvdy8n/2/
Make some changes in your classroom's data attribute.
<table class="table">
<thead>
<tr>
<th>Class</th>
<th>Amount of Students</th>
<th>Teacher</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr v-for="(classroom, index) in classrooms.data" :key="index">
<td>{{ classroom.class_no }}•{{ classroom.field }}•{{ classroom.room_no }}</td>
<td>{{ classroom.amount_students }}</td>
<td>{{ classroom.teacher }}</td>
<td>
<a href="#">
<i class="fa fa-edit blue"></i>
</a>
</td>
</tr>
</tbody>
</table>
new Vue({
el: '#app',
data() {
return {
classrooms: {
"success": true,
"data":[
{
"id": 1,
"class_no": 1,
"field": "Architecture",
"room_no": 4,
"amount_students": 40,
"teacher": "Bobby Fisher"
}
],
"message": "Find Classroom Detail"
}
}
}
})
Hope this will resolve your parsing issue.
I'm getting some errors while passing data to the frontend, but when I return this $order then it shows a JSON data like this
[
{
"id": 1,
"customer_id": 3446467182106354,
"products": {
"1": {
"'name'": "Soap",
"'quantity'": "1"
},
"2": {
"'name'": "Shampoo",
"'quantity'": "1"
}
},
"total_amount": 798,
"status": "pending",
"created_at": "2020-10-21T08:51:15.000000Z",
"updated_at": "2020-10-21T08:51:15.000000Z"
}
]
But when I pass It to the front end it says like this
Property [products] does not exist on this collection instance. (View: C:\xampp\htdocs\blog\resources\views\customer\orders.blade.php)
by the way I've a json data in my database
looking at the json data u have mentioned in the question, Products is array of products and its in side main array.
you can access products this way...
make another foreach loop for products
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Products</th>
<th scope="col">Total</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
#foreach ($orders as $order)
<tr>
#foreach{{$order->products as $product}}
<th>{{ $product->name }}</th>
#endforeach
<td>{{ $order->total }}</td>
<td>{{ $order->status }}</td>
</tr>
#endforeach
</tbody>
you need to loop over you cannot print collcetion so you need to update your controller and blade file like this
Controller
public function customerOrders($id)
{
$orders = Order::where('customer_id', $id)->get();
return view('customer.orders', compact('orders'));
}
blade
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Products</th>
<th scope="col">Total</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
#foreach ($orders as $order)
<tr>
<th>
#foreach ($order->products as $product)
{{ $product['name'] }}
#endforeach
</th>
<td>{{ $order->total }}</td>
<td>{{ $order->status }}</td>
</tr>
#endforeach
</tbody>
</table>
like this you will get all the data
Before using this data you should use json_decode() function
How can I get v-for to display table data in the same form as the following html:
<tr>
<th scope="col">Name</th>
<th scope="col">Price</th>
<th scope="col">Product ID</th>
<th></th>
</tr>
Currently I am using the following vue v-for code(below) but it is adding the table header(th) one below another. I would like the table header to display side by side.
<tr v-for="(column, index) in schema" :key="index">
<th scope="col">{{column}}</th>
</tr>
You just need to place v-for on the element you want to repeat, not it's parent.
For loop should be put on <th></th>
<tr>
<th v-for="(column, index) in schema" :key="index">{{column}}</th>
</tr>
Here is the official vue doc for list rendering: https://v2.vuejs.org/v2/guide/list.html
bind grid header and data separately.
<template>
<table>
<thead>
<tr>
<th v-for="(header,index) in gridHeader" :key="index">
{{header.displayName}}
</th>
</tr>
</thead>
<tbody>
<tr v-for="(data, index) in gridData" :key="index" >
<td>
{{data.name}}
</td>
<td>{{data.age}}
</td>
<td>{{data.place}}
</td>
</tr>
</tbody>
</table>
</template>
<script lang="ts">
import Vue from 'vue';
export default class HelloWorld extends Vue {
private gridHeader: object[] = [
{name: 'Name', displayName: 'Name'},
{name: 'Age', displayName: 'Age'},
{name: 'Place', displayName: 'Place'}
];
private gridData: any =[{name:'Tony',age:'31',place:'India'},
{name:'Linju',age:'26',place:'India'},
{name:'Nysa',age:'12',place:'India'}];
};
</script>
<style scoped>
</style>
I'm trying to iterate over lists with sublists, and printing them as <tr> without much success.
This code illustrates what i want to accomplish:
<table>
<tr>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
<span ng-repeat='x in [["a1","a2"],["b1","b2"],["c1","c2"]]'>
<tr>{{x.length}}<tr>
<span ng-repeat='y in x'>
<tr>{{y}}<tr>
</span>
</span>
</table>
I would expect this to show:
<table>
<tr>3</tr>
<tr>a1</tr>
<tr>a2</tr>
<tr>b1</tr>
// and so on..
</table>
what should i do to make this work? I want to be able to repeat without the need to put in spans..
Only table tags (td, th, tr, tbody...) inside of <table> tag are shown, you should add ng-repeat to <tr>
If you use angular1.2 or higher you can use ng-repeat-start and ng-repeat-end tags:
html:
<table ng-controller="apiCtrl">
<tr ng-repeat-start="item in foo" ng-init="first=item[0]">
<td>first: {{ first }}</td>
</tr>
<tr ng-repeat-end ng-init="last = item[1]">
<td>last: {{ last }}</td>
</tr>
</table>
js:
function apiCtrl($scope) {
$scope.foo = [
['one', 'uno'],
['two', 'dos'],
['three', 'tres']
];
}
Here is JSfiddle
Here is fiddle with nested lists
This question is really old and AngularDart has changed a lot in the meantime. We can use the <ng-container> tag to apply all kinds of directives to a group of tags which are to be repeated or put under an *ngIf and so forth. The <ng-container> tag will not appear in the DOM output, but its contents will be there and affected by the specified directive.
<table>
<ng-container *ngFor="let row of matrix">
<tr>
<ng-container *ngFor="let value of row">
<td>{{value}}</td>
</ng-container>
<tr>
</ng-container>
</table>
When your component.dart has:
List<List<int>> get matrix => [[1, 2, 3], [4, 5, 6]];