How to use ng-switch in angularjs - angularjs

I was trying to display some content using ng-switch:
<div ng-app ng-controller="ctrl" >
<div ng-repeat="list in statusList">
<p ng-switch on="list">
<span ng-switch-when="incorrect">
i am incorrect
</span>
<span ng-switch-when="stuff">
i am stuff
</span>
<span ng-switch-when="wrong">
i am wrong
</span>
<span ng-switch-default>
Correct
</span>
</p>
</div>
</div>
controller
function ctrl($scope){
$scope.statusList=["incorrect","wrong","stuff"];
}
Getting the output like this:
i am incorrect
i am wrong
i am stuff
But I need output to display in order what I specified. i.e.
i am incorrect
i am stuff
i am wrong
How can I do this, and one important point is we should not change the order in controller.

You can create custom order by function, something like this.
<div ng-repeat="list in statusList | orderBy:myValueFunction">
You can order it alphabetically (with filter), but I would not recommend it because you will probably add new element that are not ordered alphabetically.

ng-repeat iteration uses the order of your list. You can either define a custom filter to order the list as you want or use another approach:
Define a 'contains' filter, returning true if an array contains an element:
.filter('contains', [function() {
return function(array, element) {
return array.indexOf(element) > -1;
}
}])
Use ng-ifs for your template (no repeat):
<div ng-if="statusList | contains : 'incorrect'">i am incorrect</div>
<div ng-if="statusList | contains : 'stuff'">i am stuff</div>
<div ng-if="statusList | contains : 'wrong'">i am wrong</div>
This way you can define whatever order you want to have.
Plunkr: http://plnkr.co/edit/yaYodJAVCVQ55KbOrf3A?p=preview

Related

Angular limit to first ng-if TRUE item in ng-repeat

Hej, how do I show only the first number that evaluates to true inside ng-repeat?
In my directive (or controller) I have:
ctrl.things = [1,2,3,4,5,6];
and in my html:
<div ng-repeat='thing in ctrl.things' >
<span ng-if="thing>3" ng-show="$first">{{thing}}</span>
</div>
How do I display only 4 as a result?
Please bear in mind that this example is simplified. There is actually an ng-repeat inside ng-repeat and because of that (and other things) there are not many things I co do inside the directive (controller). Many thanks for any solution.
Declare a method in the scope
$scope.getData=function(obj){
return obj > 3;
}
Then add this as filter in div
<div ng-repeat='thing in things | filter : getData' ng-if="$first">
<span >{{thing}}</span>
</div>
JSFIDDLE
If wanna to use this
Try like this
Declare a method in the scope
vm.getData=function(obj){
return obj > 3;
}
Then add this as filter in div
<div ng-repeat='thing in vm.things | filter : vm.getData' ng-if="$first">
<span >{{thing}}</span>
</div>
JSFIDDLE
You should have to create a filter or inline it like this:
<div ng-repeat='thing in ctrl.things' ng-if="thing > 3">
<span ng-if="$first">{{thing}}</span>
</div>
That should work
I think you are looking for this:
//controller
$scope.ctrl={};
$scope.ctrl.things=[{1:false},{2:false},{3:false},{4:true},{5:true}];
$scope.check=function(value){
$scope.count = value === true?($scope.count+1):$scope.count;
return $scope.count ===1 ;
}
//end of controller
HTML
<div ng-repeat='(key,value) in ctrl.things' >
<span ng-if="check(value)">{{key}}</span>
</div>
To show first element if you want to show last item you can put ng-if="$last"

How to bind array with ng-bind-html directive in angularJS?

I want to show for every item different description.
This is the controller:
todoApp.controller('todos',function($scope,todoFactory){
todoFactory.getTodos().success(function (data) {
courses = x2js.xml_str2json(data);
$scope.todos = courses.rss.channel.item;
for(var i = 0 ; i < $scope.todos.length ; i++){
item = $scope.todos[i];
console.log(item.description);
$scope.message = item.description;
}
});
this is the html:
<div ng-controller="todos" class="list" style="padding-top: 8%">
<div class="list card" ng-repeat="todo in todos | filter:search" >
<div class="item item-avatar" ng-click="openLink(todo.link)" >
<img src="Bla-Bla-Logo-1.png">
<h2>{{todo.title}}</h2>
<p>{{todo.pubDate | limitTo:25 }}</p>
</div>
<div class="item item-body">
<p ng-bind-html="message"></p>
<p>
1 Like
5 Comments
</p>
</div>
</div>
<!--end list card-->
</div>
<!--end todos-->
Just to explain the code I get xml and convert into json so todos is array of objects.
Message is entering every object and get the description (but in the description has tags so i use ng-bind-html directive to show it properly).
I understand that $scope.message will hold just the last description. How to make it to belong in the ng-repeat so I can get different description for different item?
Thanks.
replace
<p ng-bind-html="message"></p>
with
<p ng-bind-html="todo.description"></p>
please provide the data which is you want to displayed repeatedly.
How data is represented.You are getting last one because it is overriding.
The "ngBind" attribute tells Angular to replace the text content of the specified HTML element with the value of a given expression, and to update the text content when the value of that expression changes.
Typically, you don't use "ngBind" directly, but instead you use the double curly markup like {{ expression }} which is similar but less verbose.

how to create greater than and less than filter in angularjs ng-repeat

I am trying to use range slider in angularjs to filter the grid. I want a greater than and less than filter in my ng-repeat. But I am not getting how to do this. I am using the following code for now. But this is not working for me. This code is not giving me desired output
Here is my html for grid
<div class="col-md-3 product-left-grid" ng-repeat="data in Products| filter:priceSlider.max |filter:priceSlider.min">
<div class="product-grid"></div>
<div class="product-grid-text">
<a href="javascript:void(0)">
<img alt="" src="{{data.Picture1}}">
</a>
<div class="products-grid-info">
<div class="price">
<a class="btn btn-sm btn-width btn-default btn-font-weight"
href="javascript:void(0)"
ng-click="viewDetails($index)">Quick View</a>
<a href="javascript:void(0)"
class="btn btn-sm btn-width btn-default btn-font-weight"
ng-click="addToCart (data.ProductID,data.Picture1,data.ProductName,data.UnitPrice,data.Discount,data.ShippingCharges,data.wieght)">Add to cart</a>
<div class="tovar_description clearfix">
<a class="tovar_title" href="#"><b>{{data.ProductName}} </b> | {{data.UnitPrice | currency:mycurrency}}</a>
</div>
</div>
<div class="clearfix"> </div>
</div>
</div>
</div>
this is my price range slider
<rzslider rz-slider-floor="priceSlider.floor"
rz-slider-ceil="priceSlider.ceil"
rz-slider-model="priceSlider.min"
rz-slider-high="priceSlider.max"
rz-slider-on-change="onSliderChange()"></rzslider>
Now I am using filter but I have doubt that I am going wrong somewhere. Please experts help to solve this problem. Price range filter I need like every eCommerce website have.
Thanks
You have to make a custom filter :
//create an angular filter named "price"
app.filter('price', function () {
//our function will need three arguments
return function(items, greaterThan, lowerThan) {
//then we filter the array with dedicated ES5 method
items = items.filter(function(item){
//if item price is included between the two boundaries we return true
return item.price > greaterThan && item.price < lowerThan;
});
//then we return the filtered items array
return items;
};
});
You can see how Array.filter() works here
Our function will need 3 arguments to work, the items list which is passed by default and the lower and higher boundaries that we will pass as arguments in our ng-repeat filter.
Then you can use the filter as follow :
<div ng-repeat="data in Products | price:priceSlider.min:priceSlider.max | orderBy:'price'">...</div>
As I said above, items array is passed by default, then, to specify other parameters you have to separate them with a colon : right after the filter name.
You can read about custom filters in the official documentation here.
Finally you can then specified as many other filters as you want by separating them with a pipe |.
In our example I'm ordering them by price after the array has been filtered.
Here is a working JSFiddle.

AngularJS Show List Items based on ng-model

I'm trying to create some functionality where the user would have an input box and all the data (li's) below are hidden.
Then when a user types into the input box, those li's that match that text are show.
What would the best way to do this using angular? I've set up plunker below:
http://plnkr.co/edit/T6JOBJE4LrAtshbmaoPk?p=preview
I was thinking of setting the li's to:
li {
display: none;
}
and then was going to try an ng-if with the ng-model as the value. Something like this:
<div class="input-group">
<span class="input-group-addon" id="basic-addon1">Search</span>
<input type="text" class="form-control" ng-model="search">
</div>
<ul>
<li ng-repeat="x in data | filter:search " ng-if="!search">{{x.name}}</li>
</ul>
Can someone help point me in the right direction? Even if its just explaining the logic.
You can just set ng-show attribute to your <ul> tag, where you will watch on length of search variable and if it's greater that zero, your list with filtered results will be shown. So, you don't need any css.
<ul ng-show="search.length">
<li ng-repeat="x in data | filter:search ">{{x.name}}</li>
</ul>
Demo on plunker.
Part of your problem is the filter matches on the empty search string. You could create a custom filter to handle this, something like this http://plnkr.co/edit/i4lsuVUmOLO3pbISu7FR?p=preview
$scope.filterName = function(datum) {
console.log($scope.search, datum);
return $scope.search !== '' && datum.name.indexOf($scope.search) !== -1;
};
Used in the template like:
<ul>
<li ng-repeat="x in data | filter:filterName">{{x.name}}</li>
</ul>
Then you would have greater control over the filter if you want to tweak it in future.

angularjs how set right scope for function?

have this ng-repeat
<li class="tmmenu-admin-tabs-builder-panel-portlet" ng-repeat="question in questions">
<div>
<span class="tmmenu-admin-tabs-builder-panel-portlet-toggler" ng-click="tatbppTogler()">{{{tatbppt}}}</span>
<span class="tmmenu-admin-tabs-builder-panel-portlet-number">{{question.id}}</span>
{{question.text}}
</div>
<div class="tmmenu-admin-tabs-builder-panel-portlet-options" ng-show="showTatbppo">
...
</div>
</li>
I want, for click in "tmmenu-admin-tabs-builder-panel-portlet-toggler" change visibility "tmmenu-admin-tabs-builder-panel-portlet-options" and change text in "tmmenu-admin-tabs-builder-panel-portlet-toggler".
And i write this code for get result:
$scope.tatbppTogler = function(){
$scope.showTatbppo = !$scope.showTatbppo;
if($scope.showTatbppo){
$scope.tatbppt = "-";
}else{
$scope.tatbppt = "+";
}
}
It's works, but changed dom in all "Li", how changed only current (where user click) "li"?
You can do it like this:
<li class=portlet" ng-repeat="question in questions">
<div>
<span class="toggler" ng-click="showTatbppo=!showTatbppo">{{showTatbppo ? "+" : "-" }}</span>
<span class="number">{{question.id}}</span>
{{question.text}}
</div>
<div class="options" ng-show="showTatbppo">
...
</div>
</li>
Working fiddle, with this concept:
http://jsfiddle.net/x1nguaxj/
btw. You have very-very-very long css class names :)
1 way
you can pass this in ng-click="tatbppTogler(this)" and then in function manipulate with this
2 way
you can create custom directive and apply it to your li element and then on this directive bind click to element and listen , and on click function will be triggered your listener and you will have access on this element
You can create an attribute id for each question and then change based on the id of the question you clicked
I would suggest you'd take a look at $index. From the angularjs docs:
iterator offset of the repeated element (0..length-1)
Using this, you can clearly determine the certain div that was clicked on.

Resources