ng-if is condition is not in Ng-repeat - javascript

Is it possible to hide the row of ng-repeat using ng-if condition?
We are trying to restrict the displaying the ng-repeat row using ng-if condition. Here, I'm checking for the value five and three if it is not there then I need to hide the row.
angular
.module('myApp', [])
.controller('TodoCtrl', function($scope) {
$scope.comments = [{
type: 'one'
}, {
type: 'two'
}, {
type: 'three'
}, {
type: 'four'
}]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="TodoCtrl">
<table>
<tr ng-repeat="data in comments">
<td ng-if="data.type == 'five' ">five</td>
<td ng-if="data.type == 'three' ">Three</td>
</tr>
</table>
</div>
</div>
Output:
five Three five Three five Three five Three
Expected output:
Three Three Three Three

It's always preferred to initialize your angular module with a name instead of making it blank.
The ngIf directive removes or recreates a portion of the DOM tree
based on an {expression}. If the expression assigned to ngIf evaluates
to a false value then the element is removed from the DOM, otherwise a
clone of the element is reinserted into the DOM. For more details see
below snippet... More information ngif
var myApp = angular.module('myApp', []);
myApp.controller('TodoCtrl', function($scope) {
$scope.comments = [
{
type: 'one'
}, {
type: 'two'
}, {
type: 'three'
}, {
type: 'four'
}
]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="TodoCtrl">
<div >
<table>
<tr ng-repeat="data in comments">
<td ng-if="data.type == 'five'"> five </td>
<td ng-if="data.type == 'three'"> Three </td>
</tr>
</table>
</div>
</div>

Yes, you can use multiple directives on the same element, thus achieving your desired output. Have a look at this example in which, on the same element, I placed ngRepeat, ngIf, ngClick and ngBind.
angular
.module('myApp', [])
.controller('MyCtrl', function() {
this.myList = [1, 2, 3, 4, 5, 6, 7, 8, 9];
this.showNum = function(num) {
console.log('You clicked on', num);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<div ng-app="myApp">
<div ng-controller="MyCtrl as vm">
<ul>
<li ng-repeat="listItem in vm.myList"
ng-if="listItem % 2 === 0"
ng-click="vm.showNum(listItem);"
ng-bind="listItem"></li>
</ul>
</div>
</div>

I think that u did not add five in your comment array
$scope.comments = [ {type:'one'},{type:'two'},{type:'three'},{type:'four'},{type:'five'} ]

Related

nested ng-repeat in angular js

I have a following code where I need to extract value of a at all the occurrence . What I have to do is use <span ng-repeat="x in carname"> as parent element, which I dont want to. How can I get value of a directly.
P.S.: $scope.carname can not be moderated
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.carname = [
[{
"a": 1
}],
[{
"a": 2
}],
[{
"a": 3
}],
[{
"a": 4
}]
];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<span ng-repeat="x in carname">
<h1 ng-repeat="y in x">{{y.a}}</h1>
</span>
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.carname =[
[{"a":1}],
[{"a":2}],
[{"a":3}],
[{"a":4}]
];
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="cn in carname">
{{cn[0].a}}
</div>
</div>
You can pretty much run one loop over the carname array, and since each element in that array is another array with just one element, get the first item cn[0] and then find the value by key, which is a.
And of course you can always use a nested ng-repeat or transform the data to some other format that makes it even easier to display.
If you have this structure then you can do like this
<span ng-repeat="x in carname">
<h1>{{x[0].a}}</h1>
</span>

Binding dynamic checkbox in angular.js

I have a list of options pulled from the database via json based on product selection in angular.js
Here's a sample code:
<ion-checkbox ng-repeat="extra in extras" ng-model="order.extras" checklist-value="{{ extra.id }}"><strong>{{ extra.name }}</strong></ion-checkbox>
I want a user to be able to select multiple extras but can't seem to be able to bind these selections.
I think it could work with ng-model="order.extras[extra.id]" then you can track the checked extras in order.extras.
Please have a look at the demo below or at this jsfiddle.
angular.module('demoApp', ['ionic'])
.controller('mainController', mainController);
function mainController($scope) {
$scope.order = {};
$scope.extras = [
{
id: 0,
name: 'first'
},
{
id: 1,
name: 'second'
},
{
id: 2,
name: 'third'
}
]
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/css/ionic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/js/ionic-angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.2.4/js/ionic.bundle.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
<ion-content>
<ion-checkbox ng-repeat="extra in extras" ng-model="order.extras[extra.id]" checklist-value="{{ extra.id }}"><strong>{{ extra.name }}</strong></ion-checkbox>
current order: {{order}}
</ion-content>
</div>

Ng-repeat and Ng-show in angular

I want to display only the first element in ng-repeat and by click display the rest elements.
That's what I tried to do without success:
<button data-ng-click="term = !term">Show rest</button>
<div data-ng-repeat="y in mQues track by $index" data-ng-show="term" data-ng-init="term = $first">
...
</div>
it really display only the first but the button click do noting for some reason...
Change your ng-show condition: data-ng-show="term || $first"
try this...
<div data-ng-repeat="item in items" data-ng-show="term || $index == 0">{{item.title}}</div>
<div data-ng-repeat="y in mQues track by $index" data-ng-if="$first"></div>
I think this will help
Using the angular filter limitTo it is rather straight forward.
function MyCtrl($scope) {
$scope.items = [
{ title: "item 1" },
{ title: "item 2" },
{ title: "item 3" },
{ title: "item 4" }
]
$scope.limit = 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="MyCtrl">
<span ng-click="limit = limit == 1 ? items.length : 1">Toggle</span>
<ul>
<li ng-repeat="item in items | limitTo:limit" ng-bind="item.title"></li>
</ul>
</div>
https://docs.angularjs.org/api/ng/directive/ngShow
ng-show displays an element by evaluating the expression given to it.
the expression assigned to ng-show gets converted to true or false depending on whether the result is 'truthy' or 'falsy'. When you assign term a truthy value, ng-show is assigned true.
when you do click button, it evaluates term = !term and term then becomes false and therefore the whole div will be hidden
Guess simpler and more straight forward:
var app = angular.module('app', []);
app.controller('DisplayController', function($scope) {
$scope.ShowRest = 0;
$scope.items = [{
title: 'myTitle1'
}, {
title: 'myTitle2'
}, {
title: 'myTitle3'
}, {
title: 'myTitle4'
}, {
title: 'myTitle5'
}];
});
app.$inject = ['$scope'];
Then:
<div data-ng-controller="DisplayController">
<div data-ng-repeat="item in items">
<div data-ng-class="{'no-display': !$first}">{{ item.title }}</div>
</div>
<div data-ng-repeat="item in items" data-ng-show="ShowRest">
<div data-ng-class="{'no-display': $first}">{{ item.title }}</div>
</div>
<button data- ng-click="ShowRest = !ShowRest">Show rest</button>
</div>
Maybe it's not the most efficient way of doing it, but it works!
Fiddle: http://jsfiddle.net/cb6pggL8/1/

ng-grid expand and collaspe row

I am trying to achieve an expand and collapse row for ng-grid, basically what we have here http://datatables.net/examples/api/row_details.html if you click the "plus icon" your displayed with more detail.
I have seen a similar question asked here but no solution. https://github.com/angular-ui/ng-grid/issues/517
Does anyone know how to achieve this?
Any help is appreciated.
var app = angularexpand('myApp', ['ngGrid']);
app.controller('MyCtrl', function($scope) {
$scope.myData = [{
somedata: "data to be expanded in another",
moredata: 1
}, {
somedata: "b data to be expanded in another",
moredata 2
}, {
somedata: "c data to be expanded in another",
moredata: 3
}, {
somedata: "d data to be expanded in another",
moredata: 4
}, {
somedata: "e data to be expanded in another",
moredata: 5
}];
$scope.gridOptions = {
data: 'myData'
};
$scope.expandRow = function(e) {
e.preventDefault();
var getData = {
somedata: '',
moredata: ''
};
$scope.gridOptions.selectItem(index, false);
$scope.myData.splice(index + 1, 0, getData);
$(this.row.elm).append('<div>' + this.row.entity.somedata + '</div>');
};
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-controller="MyCtrl">
<div class="gridStyle" ng-grid="gridOptions"></div>
<button ng-click="expandRow($event)">add row</button>
</body>
I have never done this with ng-grid, however, have achieved this functionality with a regular table. You could write a custom directive to solve this.
Something along the lines below should do the trick. This example was NOT tested in JSFiddle. The key here is using 'ng-repeat-start' and 'ng-repeat-end' instead of just 'ng-repeat'.
HTML:
<div ng-controller="MyCtrl">
<table class="table dataTable no-hover">
<tbody>
<tr ng-repeat-start="row in rows" ng-init="ind = $index">
<td ng-click="rowExpanded[row.name]=!rowExpanded[row.name]"></td>
<td ng-repeat="val in row.vals" class="column"> </td>
</tr>
<tr id="rowexpand" ng-show="rowExpanded[row.name]" colspan="100%" ng-repeat-end></tr>
</tbody>
</table>
</div>
AngularJS Controller:
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.rowExpanded=[];
$scope.rows= [
{ "name": "row1",
"vals" :[1, 2, 3, 4, 5],
},
{ "name": "row1",
"vals" :[1, 2, 3, 4, 5],
}
]
}
Currently nggrid doesn't support this feature [issue #1111][1] and its being implemented in UIGrid 3.0 version.
But i have found a workaround and this is how you can try to achieve in nggrid using rowTemplate and a little bit of jquery. hope this helps!
rowTemplate:
"< div class="**row**" >"
"add column data"
// expand or collapse image
< div class=\"col-xs-1 col-md-1\" >< img "id='**showHide**_{{row.rowIndex}}' ng-src='src/img/{{**imgArrowRight**}}' ng-click=\"**rowExpand** (row.rowIndex);\" />< / div>"< /div>< div id='**expRowId**_{{row.rowIndex}}' style=\"display:none;\">< div class=\"**expData**\">< span ng-bind=\"**row.entity.Attr**\">< /span>
//add whatever you want in the expanded row.< /div>< /div>
//Defined customArray for handling dynamic row Toggle
angular.forEach($scope.**gridData**, function(row,index) {
$scope.customArray[index] = true;
});
//row expand code
$scope.**rowExpand** = function(**index**){
$scope.customArray[index] = $scope.customArray[index] === false ? true : false;
if($scope.customArray[index]){
$('#showHide_'+index).attr('src','src/assets/img/rigthIcon.gif');
$('#expRowId_'+index).hide();
}else{
$('#showHide_'+index).attr('src','src/assets/img/downIcon.gif');
$('#expRowId_'+index).show();
}
}
Also, override the ngRow style class
.ngRow {
position: relative !important;
}

How to create a composite filter with two way binding?

I want to display a list of items in a table and allow users to filter the items using form controls.
My Problem
I am able to accomplish this when the controller first executes, but when I change the values of the inputs, the table doesn't re-render with the correct data.
My Question
How can I make my table filter based on new values in the form fields?
Live Example
http://plnkr.co/edit/7uLUzXbuGis42eoWJ006?p=preview
Javascript
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.travelerFilter = 2;
$scope.groupFilter = "A";
$scope.records = [
{ leadName: "Jesse", travelerCount: 1, group: "A"},
{ leadName: "John", travelerCount: 1, group: "B"},
{ leadName: "James", travelerCount: 2, group: "A"},
{ leadName: "Bill", travelerCount: 2, group: "B"}
];
var travelerCountFilter = function(record) {
return record.travelerCount >= $scope.travelerFilter;
};
var groupFilter = function(record) {
return record.group === $scope.groupFilter;
};
$scope.filteredRecords = _.chain($scope.records)
.filter(travelerCountFilter)
.filter(groupFilter)
.value();
});
Html
<!doctype html>
<html ng-app="plunker" >
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Show records with at least <input type="number" ng-model="travelerFilter" /> travelers.</p>
<p>Group <input type="text" ng-model="groupFilter" /></p>
<table>
<tr>
<th>Name</th>
<th>Count</th>
<th>Group</th>
</tr>
<tr ng-repeat="record in filteredRecords">
<td>{{record.leadName}}</td>
<td>{{record.travelerCount}}</td>
<td>{{record.group}}</td>
</tr>
</table>
</body>
</html>
angular can automatically two-way-bind everything for you without the need for filters:
JS:
$scope.filteredRecords = function() {
return $scope.records.filter(function(record, i) {
return record.travelerCount === $scope.travelerFilter &&
record.group === $scope.groupFilter;
});
}
HTML:
<tr ng-repeat="record in filteredRecords()">
See here for a live example: http://plnkr.co/edit/aeBv2soGG06Trpp9WI4f?p=preview
You can specify the filter as part of the ng-repeat, i.e.:
<tr ng-repeat="record in records | filter:{group:groupFilter} | filter:{travelerCount:travelerFilter}">
See here for a live version: http://plnkr.co/edit/1UcGDpwUAbtvEhUyCFss?p=preview

Categories