I have an array of items and I want to render it as a table with 2 columns.
I did the basic implementation which is rendering with only one column. Any suggestions please?
<body ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat="i in items">
<td>{{i}}</td>
</tr>
</table>
</body>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.items = ["12", "22", "34", "657", "129"];
});
https://jsfiddle.net/nkarri/9czrqLny/1/
This is because your HTML only has a single <td> element, which you are not repeating. Since there's only 1, you get just 1 column. You'll need to have a nested ng-repeat in the <td> element in order to get more than 1 column, or explicitly have two <td> elements defined in your HTML.
You could try to write something more complicated to try to determine when a new column or row should be created, but I'd simplify things by creating your array into something that will be a little easier to consume: essentially a 2-dimensional array. Here's what I would do instead:
<body ng-app="myApp">
<div ng-controller="myCtrl">
<table>
<tr ng-repeat="row in items">
<td ng-repeat="column in row">{{column}}</td>
</tr>
</table>
</div>
</body>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.items = [];
$scope.items[0] = ["12", "22"];
$scope.items[1] = ["34", "657"];
$scope.items[2] = ["129", null];
});
https://jsfiddle.net/bntguybm/
Note that if any of these arrays were to contain more than 2 values, then you would also see extra columns for the rows that contains that data.
An alternative way would be like this, which would guarantee only 2 columns. You would need to create an array of objects for your items object. Like this:
<body ng-app="myApp">
<div ng-controller="myCtrl">
<table>
<tr ng-repeat="row in items">
<td>{{row.column1}}</td>
<td>{{row.column2}}</td>
</tr>
</table>
</div>
</body>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function($scope) {
$scope.items = [];
$scope.items[0] = {};
$scope.items[0].column1 = "12";
$scope.items[0].column2 = "22";
$scope.items[1] = {};
$scope.items[1].column1 = "34";
$scope.items[1].column2 = "657";
$scope.items[2] = {};
$scope.items[2].column1 = "129";
$scope.items[2].column2 = null;
});
https://jsfiddle.net/6v1701gx/1/
I googled and figured it out. This is what I came up with using index.
<body ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat="i in items" ng-if="$index%7 == 0">
<td>{{items[$index]}}</td>
<td>{{items[$index+1]}}</td>
<td>{{items[$index+2]}}</td>
<td>{{items[$index+3]}}</td>
<td>{{items[$index+4]}}</td>
<td>{{items[$index+5]}}</td>
<td>{{items[$index+6]}}</td>
</tr>
</table>
</body>
// the main (app) module
var myApp = angular.module("myApp", []);
// add a controller
myApp.controller("myCtrl", function($scope) {
$scope.items = ['12', '22', '34', '657', '129', '11', '23', '45', '65', '9', '76', '87', '90', '33', '51'];
});
https://jsfiddle.net/nkarri/9czrqLny/2/
Related
Below I have added my data
[{
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
}]
I want to make ng-repeat but I don't want to hard code any field (name, version, description, applicationenvironment)
How can I achieve this?
MY expectation :
IN TABLE it should come like this
Your array should be an object. So your structure simplifies quite a lot. Just extract key and values from your object and loop over it for each row. Then display key and values in separate columns per row:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.table = [{
"name": "testapp",
"version": "2.0",
"description": "testapp",
"applicationenvironment": "angularjs"
}]
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="(key, value) in table[0]">
<td>{{key}}</td>
<td>{{value}}</td>
</tr>
</table>
</div>
</body>
</html>
Although I don't recommend you to have this strucuture, you can do something like this:
angular.module('app', [])
.controller('appController', function () {
this.data = {
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
};
});
And your HTML would be something like this:
<div ng-app="app" ng-controller="appController as vm">
<ul>
<li ng-repeat="(key, value) in vm.data"> {{ key }} : {{ value }}</li>
</ul>
</div>
If you still need to have the data inside an array as you've wrote in the question, you would have to iterate over both the array and the object.
Now since your data source is an array, you need to do two nested ng-repeats
let app = angular.module("table",[]);
app.controller("tableCtrl", ["$scope", function($scope){
$scope.data = [{
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
},
{
"name":"testapp 2",
"version":"2.1",
"description":"testapp 2",
"applicationenvironment":"angularjs"
}];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="table" ng-controller="tableCtrl">
<table ng-repeat="row in data">
<tr><td>Key</td><td>Value</td></tr>
<tr ng-repeat="(key,value) in row">
<td>{{key}}</td><td>{{value}}</td>
</tr>
</table>
</div>
Now if you do this, your data structure should yield the wanted result
You need to loop twice: Once through each the entire array of objects to access each object, and then inside each object to access individual key-value pairs.
I have posted the code below:
angular.module('app', [])
.controller('Controller1', function () {
this.data = {
"name":"testapp",
"version":"2.0",
"description":"testapp",
"applicationenvironment":"angularjs"
};
});
<div ng-app="app" ng-controller="Controller1 as c1">
<table>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr ng-repeat="c in c1.data">
<table>
<tr ng-repeat="(key, value) in c">
<td> {{ key }} </td>
<td> {{ value }} </td>
</tr>
</table>
</tr>
</table>
</div>
Please help. I am new at angularjs, I want to bind json data into div as list using angularjs
Sample Data
"[{"T_FORM_CODE":"T12040"},{"T_FORM_CODE":"T18025"},{"T_FORM_CODE":"Q12014"},{"T_FORM_CODE":"R12039"}]"
Json Data :
const HEROES = [
{"T_FORM_CODE":"T12040"},{"T_FORM_CODE":"T18025"},{"T_FORM_CODE":"Q12014"},{"T_FORM_CODE":"R12039"}
];
Template :
<tr *ngFor="let hero of heroes">
<td>{{hero.T_FORM_CODE}}</td>
</tr>
do like this:
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat="x in array">
<td>{{x.T_FORM_CODE}}</td>
</tr>
</table>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.array = [{"T_FORM_CODE":"T12040"},{"T_FORM_CODE":"T18025"},{"T_FORM_CODE":"Q12014"},{"T_FORM_CODE":"R12039"}];
});
</script>
you can use ng-repeat.
you can see plunker
<div ng-repeat ="dr in data">
{{dr.column}}
</div>
Plunker
Someone help me please!
Lets say I have an a list of a checkboxes, each checkbox have an ID.
I would like to $scope an array with checked checkboxes IDs.
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key, value) in providers">
<td><input type="checkbox" ng-model="ids[value.Id]"> {{value}} </td>
</tr>
</table>
{{ids}}
</div>
And my controller:
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.providers = [{Id:5},{Id:6},{Id:8},{Id:10}];
$scope.ids = {};
});
Now my array output (if all check boxes are checked) is: {"5":true,"6":true,"8":true,"10":true}
And I would like: [{Id:5},{Id:6},{Id:8},{Id:10}]
this is a possible solution:
<input type="checkbox" ng-model="ids[$index]" ng-true-value="
{{value}}" ng-false-value="{{undefined}}"/>{{value}}
In this way, you will have an array of objects, because you are assigning ids[$index] = value.
There is a cons however: when you double check a checkbox, you will have an empty element in the array.
var app = angular.module('myapp', []);
app.controller('ctrlParent', function($scope) {
$scope.providers = [{
Id: 5
}, {
Id: 6
}, {
Id: 8
}, {
Id: 10
}];
$scope.ids = [];
$scope.$watchCollection('ids', function(newVal) {
for (var i = 0; i < newVal.length; ++i) {
console.log(newVal[i]);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<table>
<tr ng-repeat="(key,value) in providers">
<td>
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" ng-false-value="{{undefined}}" />{{value}}
</td>
</tr>
</table>{{ids}}</div>
</div>
http://jsfiddle.net/b9jj0re2/3/
<input type="checkbox" ng-model="ids[$index]" ng-true-value="{{value}}" >
Addign the ng-true-value directive will solve the problem
and in controller change the ids from object to array
plunker
In the following code, when I delete a customer, I want the TR row to disappear.
What is the best way to do this? Do I need to send the row as a parameter to deleteCustomer somehow? Do I have access to the TR DOM element within AngularJS somehow?
<html ng-app="mainModule">
<head>
<script src="http://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/js/bootstrap.min.js"></script>
<link href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-controller="mainController" style="padding: 20px">
<div class="col-lg-5">
<table style="width: 500px" class="table-striped table-bordered table table-hover">
<tr ng-repeat="customer in customers">
<td style="width:50px"><button ng-click="deleteCustomer(customer)">Delete</button></td>
<td style="text-align:right">{{customer.id}}</td>
<td>{{customer.firstName}}</td>
<td>{{customer.lastName}}</td>
</tr>
</table>
</div>
<div class="col-lg-7">
<div class="panel panel-info">
<div class="panel-heading">Logger</div>
<div class="panel-body" style="padding:0">
<table class="table table-bordered" style="margin:0">
<tr ng-repeat="loggedAction in loggedActions">
<td>{{loggedAction.action}}</td>
<td>{{loggedAction.description}}</td>
</tr>
</table>
</div>
</div>
</div>
<script>
var mainModule = angular.module('mainModule', []);
function mainController($scope) {
$scope.loggedActions = [];
$scope.customers = [
{id: 1, firstName: 'Joe', lastName: 'Thompson'},
{id: 2, firstName: 'Hank', lastName: 'Howards'},
{id: 3, firstName: 'Zoe', lastName: 'Frappe'}
];
$scope.deleteCustomer = function (customer) {
$scope.$emit('customerDeleted', customer);
};
$scope.$on('customerDeleted', function (event, customer) {
$scope.loggedActions.push({action: 'delete', description: 'Deleted customer ' + customer.firstName + ' ' + customer.lastName});
});
}
</script>
</body>
</html>
EDIT:
as pointed out by #K.Toress's comment, it's better to retrieve the index of the deleted customer via indexOf() from within the function, rather than passing $index from the ng-repeat.
passing $index will give unexpected results if using a filter or sorting the array.
deleteCustomer function:
$scope.deleteCustomer = function (customer) {
var index = $scope.customers.indexOf(customer);
$scope.customers.splice(index, 1);
$scope.$emit('customerDeleted', customer);
};
updated plnkr
you can use the $index provided by ng-repeat, and array.splice from within the delete function:
html:
<button ng-click="deleteCustomer($index, customer)">Delete</button>
js:
$scope.deleteCustomer = function ($index, customer) {
$scope.customers.splice($index, 1);
$scope.$emit('customerDeleted', customer);
};
plnkr
Working example:
http://plnkr.co/edit/7MOdokoohX0mv9uSWuAF?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.data = ['a', 'b', 'c', 'd', 'e'];
$scope.delete = function(at) {
$scope.data.splice(at, 1);
}
});
Template:
<body ng-app="plunker" ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<div ng-repeat="elem in data">
{{elem}}
<button ng-click="delete($index)">delete {{elem}}</button>
</div>
</body>
I have a simple angular app with a a data array:
app.js
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl', function ($scope) {
$scope.data = [
{name: "Alice", age: 28},
{name: "Bob", age: 55},
...
];
});
index.html
<input type="text" ng-model="data.search">
<table>
<tbody>
<tr ng-repeat="row in data | filter:data.search">
<td>{{ data.name }}</td>
<td>{{ data.age }}</td>
</tr>
</tbody>
</table>
Now, I want to start using the firebase service to experience cool 3-way binding. So I do something like this:
app.js
var myApp = angular.module('myApp', ['firebase']);
myApp.controller('Ctrl', function ($scope) {
var ref = new Firebase("https://<myapp>.firebaseio.com/");
// assume there is already data in here similar to above
$scope.data = $firebase(ref);
});
Of course now my search filter breaks because $scope.data is an Object not an Array. Of course I could transform the data, but that would break the automatic 3-way binding.
So my question is - how should filters be applied to this data whilst maintaining the 3-way relationship?
You can use the orderByPriority filter first which converts the object to an array:
<tr ng-repeat="row in data | orderByPriority | filter:data.search">
Alternatively, you can use the filter in your controller to make sure $scope.data is an array to begin with.
Anant's suggestion works. Working fiddle: http://jsfiddle.net/rwk1/vqVw7/
Can't post as a comment yet.
HTML
<div ng-app="myApp">
<div ng-controller="testController">
<input type="text" ng-model="search.searchText"></input>
<div>
<ul ng-repeat="person in people | orderByPriority | filter:search.searchText">
<li>name:{{ person.name }}</li>
<li>age:{{ person.age }}</li>
</ul>
<input type="text" placeholder="name" ng-model="newPerson.name"/>
<input type="text" placeholder="age" ng-model="newPerson.age"/>
<button type="submit" ng-click="addPerson()">Add New Person</button>
</div>
</div>
</div>
JS
var myApp = angular.module('myApp', ["firebase"]);
myApp.controller('testController', function ($scope, $firebase) {
$scope.data = [{
name: "Alice",
age: 28
}, {
name: "Bob",
age: 55
}];
var peopleRef = new Firebase("https://sqt.firebaseio.com/people");
// Automatically syncs everywhere in realtime
$scope.people = $firebase(peopleRef);
$scope.addPerson = function(){
$scope.people.$add($scope.newPerson);
$scope.newPerson = "";
};