How to output items from an array in angular - arrays

Im really new to angular. And I find that it is really hard to get an item from an array and output in the relevant html file in that component.
The below code shows the onClick function of the bill-item.component.ts file
arr: Array<any> =[];
itemArray: Array<any> =[];
onAddToBill(itemId:string, name:string , expireDate:string , quantity:string){
this.itemArray.push([itemId,name,expireDate,quantity]);
this.arr.push(this.itemArray);
console.log(this.arr);
}
And I need to output the item array on my bill-item.component.html which is shown below
<tbody>
<tr *ngFor="let itemArrays of arr">
<td *ngFor="let obj of itemArrays">{{obj[1]}}</td>
<td *ngFor="let obj of itemArrays">{{obj[0]}}</td>
<td><input type="number" class="is-center" id="number" value="1" style="width: 50%;" /></td>
<td *ngFor="let obj of itemArrays">{{obj[2]}}</td>
<td *ngFor="let obj of itemArrays">{{obj[3]}}</td>
</tr>
</tbody>
The below image shows the item list when I add the first item
But after adding the second item , the item list shows like this
Here all the items gets add up to the same row , I want to get each item in separate row , line after line.
Then I tried the below code
<tbody>
<tr *ngFor="let entries of arr">
<td>{{entries [1]}}</td>
<td>{{entries [0]}}</td>
<td><input type="number" class="is-center" id="number" value="1" style="width: 50%;" /></td>
<td>{{entries [2]}}</td>
<td>{{entries [3]}}</td>
</tr>
</tbody>
And this was the result. As ID has the entry[0] it was filled with all the instances in that array.
The below image shows my console.log(arr) result after adding 3 items

you can easily get values from "itemArray" rather than use "arr" and get the item details and print in table.
<table>
<tr *ngFor="let x of itemArray">
<td>{{x[0]}}</td>
<td>{{x[1]}}</td>
</tr>
</table>
like wise

you do not need to use *ngFor for each of entries as you are using array indexes like entries[1]
<tbody>
<tr *ngFor="let entries of arr">
<td>{{entries [1]}}</td>
<td>{{entries [0]}}</td>
<td><input type="number" class="is-center" id="number" value="1" style="width: 50%;" /></td>
<td>{{entries [2]}}</td>
<td>{{entries [3]}}</td>
</tr>
</tbody>
I tried this above code with following value of arr
arr = [['a','b','c','d'],['a1','b1','c1','d1']]
and got the result as

There is no need for iterating itemArrays. You can directly access element using the index.
Remove *ngFor of each itemArrays on each row.
<tbody>
<tr *ngFor="let itemArrays of arr">
<td>{{itemArrays[1]}}</td>
<td >{{itemArrays[0]}}</td>
<td><input type="number" class="is-center" id="number" value="1" style="width: 50%;" /></td>
<td >{{itemArrays[2]}}</td>
<td>{{itemArrays[3]}}</td>
</tr>
</tbody>

In td you are already accessing the items in the array, so you do not need to use *ngFor.
<tbody>
<tr *ngFor="let itemArrays of arr">
<td>{{itemArrays[1]}}</td>
<td>{{itemArrays[0]}}</td>
<td><input type="number" class="is-center" id="number" value="1" style="width: 50%;" /></td>
<td>{{itemArrays[2]}}</td>
<td>{{itemArrays[3]}}</td>
</tr>
</tbody>

Related

Array Data Binding in VueJS

I need help in making my checkboxes in an array format. I have these codes:
<form #keyup="validate">
<div class="form-group">
<thead>
<th>Task Schedule</th>
<th>Notify Me</th>
<th>Email Me</th>
</thead>
<tbody>
<tr v-for="(row, index) in tableData.data" :key="index">
<td> {{ row.name }} </td>
<td><input type="checkbox" id="notify" name="notify" :value="tasks.id" v-model="data.notify"></td>
<td><input type="checkbox" id="email" name="email" :value="tasks.id" v-model="data.email"></td>
</tr>
</tbody>
</div>
</form>
Not sure though about the v-model of my checkboxes. because if I check even just one checkbox, the other boxes also gets checked. I think I need to add computed as well but Im not sure what to code. Thanks

thymeleaf Array index

I want to put a variable Between array's brackets [...] Like:
th:value="${MyArray[${cmp.id}].checked}"
Here is my code
<tbody>
<tr th:each="cmp : ${allcomps}" >
<td><input type="checkbox" th:name="checkbox" th:checked="${cmp.checked}" th:value="${MyArray[0].checked}" /> </td>
<td th:text="${cmp.id}">Id</td>
<td th:text="${cmp.l_fr}" >fr</td>
<td th:text="${cmp.l_de}">de</td>
</tr>
</tbody>
Leave off the extra ${}. It should look like this:
th:value="${MyArray[cmp.id].checked}"

Why cannot I add new list in a table in angularJS 1.x?

I have example code below where I am supposed to create a list of items.
<div ng-hide="listTrigger">
<!--FIRST TABLE-->
<table class="table table-bordered table-striped">
<thead>
<tr>
<th sortable="code" class="sortable">
Product Name
</th>
<th sortable="placed" class="sortable">
Qty
</th>
<th class="st-sort-disable th-dropdown">
Price
</th>
<th sortable='total.value' class="sortable">
Split
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr grid-item>
<td width="40%">
<select class="form-control" ng-model="prod.uid">
<option selected disabled>Select Product</option>
<option ng-repeat="product in products | orderBy : 'name'" ng-value="product.uid" >{{product.name}}</option>
</select>
</td>
<td width="20%">
<input type="number" min="0" ng-model="prod.qty" class="form-control">
</td>
<td width="20%">
<input type="number" min="0" ng-model="prod.price" class="form-control">
</td>
<td width="10%">
<input type="number" min="1" max="100" ng-model="prod.split" class="form-control">
</td>
<td width="10%"><button ng-click="addNewProduct(prod.id)" class="form-control">Add</button></td>
</tr>
</tbody>
</table>
<!--SECOND TABLE-->
<table ng-show="newProducts.length!=0" class="table">
<thead>
<tr>
<th >
Product Name
</th>
<th >
Qty
</th>
<th >
Price
</th>
<th >
Split
</th>
<th>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="newProduct in newProducts">
<td width="60%" ng-bind="newProduct.uid"></td>
<td width="10%" ng-bind="newProduct.qty"></td>
<td width="10%"ng-bind="newProduct.price"></td>
<td width="10%" ng-bind="newProduct.split"></td>
<td width="10%"><button ng-show="newProducts.length!=0" ng-click="removeProduct(newProduct.uid)">X</button></td>
</tr>
</tbody>
</table>
Output
but whatever i type in the textbox of first table is coming just like that in second table. It is supposed to come list by list
In JS I am getting all details from input fields and settinf to an object prod and then pushing it in to an array newProducts.
Later in the table I am using ng-repeat to repeat items in newProducts array. The top table and bottom table are connected in no other way and I cannot figure out why values are chaging in bottom table when they are changed in input fields. Also while trying to add it one more time, it throws an error.
jquery.js:4409 Error: [ngRepeat:dupes] http://errors.angularjs.org/1.4.3/ngRepeat/dupes?p0=newProduct%20in%20newPr…0a-42d3-949e-3e8e59ac2be9%22%2C%22%24%24hashKey%22%3A%22object%3A359%22%7D
Here is the JS to add new item
//function to add new product while creating
$scope.addNewProduct= function(id){
$scope.newProducts.push($scope.prod);
console.log("product array-"+JSON.stringify( $scope.newProducts));
}
I tried console.log to log newProducts array in console, it is getting updated with new array , but not showing up in second table. Please help!
use angular copy.
angular $scopes are two way binded.. the changes u make in first table will be reflected in second table as you are pushing $scope.prod which is two way binded.
Using $scope can be very tricky. I'm not the best in Angular but i have no idea
$scope.newProducts.push($scope.prod);
if you are using here the $scope of the function or the $scope of the Controller.
Put in at the very top of your Controller "var vm=$scope", and in your html use "Controller as vm".
So if you are then there, we can see if the problem still exists.
Angular variables are reference type. So you can use angular.copy() to overcome from this issue. Below the code.
$scope.addNewProduct= function(id){
var products = angular.copy($scope.prod);
$scope.newProducts.push(products);
console.log("product array-"+JSON.stringify( $scope.newProducts));
}
Hope it will help you thanks.

Keep dynamic table synced with model in AngularJS

I have the following sample model:
{
a:{
x:0,
z:0,
f:1
},
b:{
x:"a",
u:"b"
}
}
Which I render into two different tables
<div class="col-sm-5">
<h1>A</h1>
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="(key,value) in schema.a">
<td>
<input type="text" ng-model="key" required>
</td>
<td>
<input type="text" ng-model="value" required>
</td>
<td></td>
</tr>
</table>
</div>
<div class="col-sm-5 col-md-offset-2">
<h1>B</h1>
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="(key,value) in schema.b">
<td>
<input type="text" ng-model="key" required>
</td>
<td>
<input type="text" ng-model="value" required>
</td>
<td></td>
</tr>
</table>
</div>
The tables are dynamic, which means I can add new rows to it.
Now when I change any values inside the table, they aren´t synchronized with the model -> Editing not possible
What do I need to do to store changes automatically in the original
model?
If this is not possible, how can I get a Json Schema from my table
like the one the tables are rendered from, so that I only have to
overwrite the old one?
First off you can't dynamically change an object property name or key. So what you are trying to do with ng-model="key" simply won't work.
As far as the value part you should be using the object reference in your ng-model
<tr ng-repeat="(key,value) in schema.b">
<td>{{key}}</td>
<td>
<input type="text" ng-model="schema.b[key]" required>
</td>
<td></td>
</tr>
if you need to be able to edit the key then you need to change your data structure to an array of objects with each object having the same property names for keys

how to Avoid ng-repeat in <tr> for particular <td> - Angular Js?

I need to skip the ng-repeat for particular column.
My Code:
<tr ng-repeat="(lunches,price) in lunchTwo">
<td>
<label class="label_wraptext">{{lunches}}</label>
</td>
<td class="td_width">
</td>
<td>
<label>{{price}}</label>
</td>
<td style="padding-left:190px">
</td>
<td>
<select ng-controller="Quantity">
<option ng-repeat="key in notSorted(data)" ng-init="value = data[key]">
{{key}}
</option>
</select>
</td>
</tr>
I need to avoid binding the 'Select' control for all the rows.
Thanks in Advance,
Stephen.L
Suppose if you want to show the select control only for the first row, you can give a check using the index if it is equals ZERO, then show the select box, else not.
Please find the updated code below, check if it works for you.
<tr ng-repeat="(lunches,price) in lunchTwo">
<td>
<label class="label_wraptext">{{lunches}}</label>
</td>
<td class="td_width">
</td>
<td>
<label>{{price}}</label>
</td>
<td style="padding-left:190px">
</td>
<td>
<select ng-controller="Quantity" ng-show="$index==0">
<option ng-repeat="key in notSorted(data)" ng-init="value = data[key]">
{{key}}
</option>
</select>
</td>
</tr>

Resources