Can Angular ng-if check if the value contains something? - angularjs

I got the following in my template:
<td ng-if="invoice.paymentMethod == 'automatic'">{{ invoice.paid | date:'yyyy-MM-dd hh:ss' }}</td>
<td ng-if="invoice.paymentMethod != 'automatic'">{{ invoice.paid | date:'yyyy-MM-dd' }}</td>
It shows the payment date in a different formate (with time) when the the payment was made automatically.
But: in the future, this "invoice.paymentMethod" can become something like "automatic - ideal" or "automatic - paypal".
So, can't I make a ng-if so that it checks if invoice.paymentMethod CONTAINS "automatic" instead of be equal to it? Should be easy but I can't find it anywhere.

In that case ngSwitch will works perfectly please see documention here
https://docs.angularjs.org/api/ng/directive/ngSwitch
or see that demo: http://jsbin.com/qejoza/1/edit or here http://jsbin.com/qejoza/2/edit
HTML:
<table ng-repeat="invoice in invoices" ng-switch on="invoice.paymentMethod">
<tr>
<td ng-switch-when="automatic">automatic: {{ invoice.paid | date:'yyyy-MM-dd hh:ss' }}</td>
<td ng-switch-when="automatic-ebay">ebay: {{ invoice.paid | date:'yyyy-MM-dd hh:ss' }}</td>
<td ng-switch-when="automatic-paypal">paypal:{{ invoice.paid | date:'yyyy-MM-dd hh:ss' }}</td>
</tr>
<table>
JS:
var app = angular.module('app', []);
app.controller('firstCtrl', function($scope){
$scope.invoices=[{
paymentMethod: 'automatic-paypal',
paid: "16/01/2014"
},
{
paymentMethod: 'automatic-ebay',
paid: "16/01/2014"
},
{
paymentMethod: 'automatic',
paid: "16/01/2014"
}];
});

Related

Angular add filter based on Object value

I'm starting AngularJS. I'm dynamically building a table with angular and I'm trying to add a filter to one of my columns.
Here the code I have in my controller :
$scope.columns = [
{
"alias":"alias1",
"name":"name1",
"type":"string"
},
{
"alias":"alias2",
"name":"name2",
"type":"currency"
}
];
$scope.data = [
{
"alias1": "value1",
"alias2": "22489"
},
{
"alias1": "value2",
"alias2": "22489"
},
{
"alias1": "value3",
"alias2": "22489"
},
];
And my table looks like this :
<table class="table table-hover">
<thead>
<tr>
<th ng-repeat="c in columns" ng-click="sort(c.alias)">{{ c.name }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="result in results | filter:search | orderBy:sortKey:reverse">
<td ng-repeat="c in columns">{{ result[c.alias] }}</td>
</tr>
</tbody>
</table>
What I'd like to do is to apply a filter to the <td> value based on the type of the column. Something like {{ result[c.alias] | c.type }} doesn't work...
Is it something that can be achieved by some formatting directive for example ?
Thanks for you help.
You mean this?:
app.filter('myfilter', function() {
return function(input, param) {
//do whatever
}
})
{{ result[c.alias] | myfilter:c.type }}

How to implement angular nested ng-repeat with groupBy filter and ng-model binding on input

I'm trying to create a nested ng-repeat loop. It uses the groupBy and toArray filters from angular-filter.
The issue is that I have an editable input field in the nested array. Without implementing "track by" on the ng-repeats every time the value changes when typed it looses focus as described in this issue.
If I try to put a track by on the repeats it breaks and shows many fields with blank values. Is there any way to correctly implement track by in this situation so that the repeats display correctly and I can type into the input field without it losing focus?
Here is example, if you run it you will see as soon as you edit input you loose focus:
var app = angular.module('App', ['angular.filter']);
app.controller('MainCtrl', function() {
this.Parts = [{
Id: 1,
ShortDescription: "Premium Shocks",
SupplierSku: "ZXU3322",
SellPrice: 110,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Super Sports',
Quantity: 3
}, {
Id: 2,
ShortDescription: "Spanner",
SupplierSku: "4444",
SellPrice: 44,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Bobs Parts',
Quantity: 1
}, {
Id: 3,
ShortDescription: "Spark Plugs",
SupplierSku: "xxxxx",
SellPrice: 10,
SellPriceInclGst: 130,
ProfitExclGst: 10,
SupplierName: 'Bobs Parts',
Quantity: 5
}]
});
<html>
<head>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.4/angular-filter.min.js"></script>
</head>
<body ng-app="App">
<table class="table" ng-controller='MainCtrl as main'>
<thead>
<tr>
<th>Short Descriptin</th>
<th>SKU</th>
<th>Qty</th>
<th>Unit Price</th>
<th>Total</th>
<th>Total + GST</th>
</tr>
</thead>
<tbody ng-repeat="supplier in main.Parts | groupBy:'SupplierName' | toArray:true | orderBy:'$key'">
<tr class="title-display-row">
<td colspan="6">{{ supplier.$key }}</td>
</tr>
<tr ng-repeat="item in supplier track by $index">
<td>{{ item.ShortDescription }} {{ key }}</td>
<td>{{ item.SupplierSku }}</td>
<td class="field-cell">
<div class="field-wrap">
<input type="text" name="quantity[$index]" ng-model="item.Quantity" />
</div>
</td>
<td>{{ item.SellPrice | currency }}</td>
<td>Total</td>
<td>Total-gst</td>
</tr>
</tbody>
</table>
</body>
</html>
Any suggestions greatly appreciated.
In the unlikely event someone has the same problem as this... the solution was to remove the toArray|true filter.
Then instead of accessing the supplier name with {{ supplier.$key }} I'm using {{ Supplier[0].SupplierName }}. Because each supplier in the loop is an array of items with the same supplier name so I can just take the first and use it.

angularjs ng-repeat with Filter or ng-if condition

I want to render text if it is Name or Value. I don't want to loop if it is createdate or enventId. I'm trying with Filter and ng-if condition. It is not working.
HTML CODE
<tr ng-repeat="event in events | filter:Name ">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
JS CODE
Events: [
{
CreatedTime: "/Date(1420757322810-0800)/",
EventId: 13,
Name: "AdGroupId",
Value: "2367898"
},
{
CreatedTime: "/Date(1420757322810-0800)/",
EventId: 13,
Name: "AdGroupId",
Value: "2367898"
}
]
I expect the result should be
AdGroupId :2367898
Assuming that what you are trying to ask is how to exclude items with neither a name nor a value, you'll need a custom function for this. This should suffice:
$scope.filterEvents = function(e){
return e.Name || e.Value;
};
And then:
<tr ng-repeat="event in events | filter:filterEvents">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
Example
Alternatively, if you are saying you want to filter the values based on a specified name and/or value, you can do so like this:
$scope.filterEvents = function (e) {
return ($scope.Name || $scope.Value) &&
(!$scope.Name || $scope.Name === e.Name) &&
(!$scope.Value || $scope.Value === e.Value);
};
(HTML is same as above)
Example
Assuming you are looking for a filter to cut out the Events that has no Name and Value properties in it.
Here is a sample for you:
Controller:
$scope.filterNameValue = function(e){
if(angular.isDefined(e.Name) && angular.isDefined(e.Value))
return e;
};
Html
<table>
<tbody>
<tr ng-repeat="event in events | filter: filterNameValue">
<td >{{event.Name}} : </td>
<td>{{ event.Value }}</td>
</tr>
</tbody>
</table>
Working Sample here

AngularJS filter unable to filter

I am trying to explore the AngularJS filter but the code which I am trying is not working.
JSFiddle for the same is: http://jsfiddle.net/sajesh1985/5bp5v1z0/1/
<td><input type="text" ng-model="search.Name"/></td>
<tbody ng-repeat="item in items ">
<tr ng-repeat="temp in item | filter:search">
<td>{{temp[0].Name}}</td>
<td>{{temp[0].Price}}</td>
<td>{{temp[0].Quantity}}</td>
</tr>
</tbody>
I think that your items object is not constructed very well and I think it should be smth like this
$scope.items = [
{
Name: "Account Opening R75",
Price: "R75",
Quantity: "A_O-AngularJS"
}
,
{
Name: "AVClientService",
Price: "R74",
Quantity: "AVClientService-DotNet"
}
];
Also, I modified your code snnipet like this:
<tr ng-repeat="item in items | filter:search">
<td>{{item.Name}}</td>
<td>{{item.Price}}</td>
<td>{{item.Quantity}}</td>
</tr>
For the complete example check this jsfiddle
http://jsfiddle.net/5bp5v1z0/3/
Hope it helps!

Angularjs adding directive on click

i have table that has this body
<tbody >
<tr ng-repeat="con in mycon | array | filter:search | orderBy:predicate:reverse"
ng-click="showhistory($event,con.conid)">
<td >{{ con.fname }}</td>
<td >{{ con.lname }}</td>
</tr>
</tbody>
When the row is click i call this function my my controller
$scope.showhistory = function ($event,cid) {
$event.stopPropagation();
var contentTr = angular.element('<con_history ></con_history>');
contentTr.insertAfter(angular.element($event.target).parent());
$compile(contentTr)($scope);
$scope.$apply
};
And i can see that the con_history tags get added. But it doesn't render the directive. When I add the directive i do not see BLAH BLAH , I only see the con_history tag
this is my directive
app.directive('con_history', function() {
return {
restrict: 'AE',
replace: 'true',
template: '<tr><td colspan="11">BLAH BLAH</td></tr>'
};
});
thanks for any help
You are not doing it in angular way, I think this is what you want to do:
<tr ng-repeat="con in mycon | array | filter:search | orderBy:predicate:reverse"
ng-click="showhistory($event,con.conid)">
<td >{{ con.fname }}</td>
<td >{{ con.lname }}</td>
</tr>
<con_history ng-if="historyVisible[con.conid]"></con_history>
in your controller
$scope.historyVisible = {};
$scope.showhistory = function ($event,cid) {
.
.
$scope.historyVisible[cid] = true;
.
.
};

Resources