Accessibility of $index in ng-show - angularjs

I try displaying a select when the previous select was checked.
<div ng-repeat="item in collection">
<div ng-show="$index === 0 || $parent.list[$index].nom">
<select ng-model="$parent.list[$index].nom" ng-options="..."></select>
</div>
<div ng-repeat="item in collection">
I loop through collection and I create many selects that there are item in collection.
<div ng-show="$index === 0 || $parent.list[$index].nom">
I want to display/hide the parent div of selects with two conditions :
I show the div if the index is equal to 0 (for display first select)
I show the div if the current ngModel contains the nom
<select ng-model="$parent.list[$index].nom" ng-options="...">
I put a dynamic ngModel where each select has his own model like :
(source: noelshack.com)
Test Exemple : I have three options in a select, so I want give opportunity to member to choose each option of the select.
If the member choose an option of select 1 the seconde select show on and If he select an option of second select the third select show on but no more else...
THE PROBLEME HERE :
$index in the directive ngShow seem's known with this condition :
$index === 0
but no here :
$parent.list[$index].nom

You must include track by $index in your ng-repeat...
<div ng-repeat="item in collection track by $index>

I think it should be:
<div ng-show="$index === 0 || $parent.list[$index - 1].nom">
<select ng-model="$parent.list[$index].nom" ng-options="el for el in els"></select>
</div>
Note, that you want to refer previous item in the list, hence $index - 1.

Related

Start $index at 1 in Ng Repeat

Is there a way to use 1 instead of 0 for $index in ng-repeat as the initial item? Im not trying to filter out the first item in the array. It is for paypal they want the first to be item_num_1... using 0 doesnt work
as in
<div ng-repeat = "item in items">
<input type ="hidden" name ="item_num_{{$index}}" value ="item_num_{{item.id}}">
//the rest like this
</div>
Maybe you can try this. I am not sure if it works though. Good luck
<div ng-repeat = "item in items track by $index">
<input type ="hidden" name ="item_num_{{$index + 1}}" value ="item_num_{{item.id}}">
//the rest like this
</div>
Why not to do just
{{$index+1}}

ng-show if filter and inner if statements are valid

I have an ng-repeat being created like so:
<div class="items">
<!-- WANT TO HIDE THIS ENTIRE AREA IF THERE IS NO VALID ITEMS -->
<b>Items</b>
<span ng-repeat="item in items | orderBy:'priority'" itemid="{{item.$id}}" ng-if="!item.groupID || item.groupID == 'misc'">
{{item.title}}
</span>
</div>
As you can see I have an ng-if which checks if the item has a null item.groupid or is in the misc category.
Many times there is no items that match all of these criteria and in that case I want to hide the outer div <div class="items">
I can't figure out how to hide it because I can't do an ng-show on the inner elements part of the loop.
You can use a filter, and assign the result of the filter to a variable. Use that variable to decide if the enclosing div should be shown or not.
Here's a plunkr showing how it works:
<div ng-show="filteredItems.length > 0">
Test
<div ng-repeat="item in items | filter:hasGroupFilter(group) as filteredItems">
{{ item.name }} - {{ item.group }}
</div>
</div>
And in the controller:
$scope.hasGroupFilter = function(group) {
return function(item) {
return !item.group || item.group === group;
};
};
I think the cleanest way to do that is to pre filter the list, and add a condition on your parent div.items instead of using ng-if in each one of the span in the ng-repeat.
Here is a working plunker
You should filter the list in your controller and just add the condition on the parent div
<div class="items" ng-if="filteredItems.length">
<b>Items</b>
<span ng-repeat="item in filteredItems | orderBy:'priority'" itemid="{{item.$id}}">
{{item.title}}
</span>
</div>
You could potentially create a function that has access to a public variable on the outer scope. It would look something along the lines of this:
Inside your JS file
$scope.NoValidItems = true; //assume no valid items code also might look different based on how you format your angular
$scope.CheckItems = function(item){
var check = false;
if(item.groupID && item.groupID !== 'misc'){
check = true;
$scope.NoValidItems = false;
}else
check = false;
return check;
};
HTML
<div class="items" ng-if="!NoValidItems ">
<!-- WANT TO HIDE THIS ENTIRE AREA IF THERE IS NO VALID ITEMS -->
<b>Items</b>
<span ng-repeat="item in items | orderBy:'priority'" itemid="{{item.$id}}" ng-if="!CheckItems(item)">
{{item.title}}
</span>
</div>
This should work, and the if statement might not be exact, but you get the drift. Pretty much if there is one that is valid it will show, but if there is not a valid item do not show. Valid being meeting your conditional criteria. Hopefully this helps, and I explained it alright

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.

Angular ng-if to set a class in ng-repeat

I am creating pagination buttons that call specific content through custom angular directives. These buttons are created via ng-repeat.
<div class="margin-less row">
<a ng-repeat="i in getNumber(9)" href="#/5-4-9_novena?day={{$index + 1}}">
<div class="small-1 panel-default columns pagination-panel" ng-if { ng-class="current: $index + 1 == date.weekday"}>
<h4 class="panel-title ">{{$index + 1}}</h4></div>
</a>
</div>
I attempted to use ng-if to add a class "current" on the pagination link that matches the link whose index matches {{date.weekday}}. However, to my disappointment I couldn't get it to add the class when the index matched the scope. Am I missing anything?
About ng-class you could use something like
<div class="small-1 panel-default columns pagination-panel" ng-class="{ current: $index + 1 == date.weekday}">
You don't need an ng-if to achieve that. Also, the ng-if syntax is completely different.
change ng-if { ng-class="current: $index + 1 == date.weekday"}
to
data-ng-class="{current: $index + 1 === date.weekday}"
For this case it's better to use ng-class:
ng-class="{current: $index == selected}"
For Both condition ng-if and ng-class
Change This:
<div class="small-1 panel-default columns pagination-panel" ng-if { ng-class="current: $index + 1 == date.weekday"}>
To:
<div class="small-1 panel-default columns pagination-panel" ng-if="$index + 1 == date.weekday" ng-class="{'current': $index + 1 == date.weekday }">

Angular js Filter Highlight the first result

I have an ng-repeater and filter in side of diretive, I would like to high light the first cell of the filtered data when start typing and filtered data appear. I have tried with doucment.querySelect select the first child but it didn't work i guess because the filter data is not ready yet, and first-child are still old data. is there anyway can get the first search result and add a class?
<textarea ng-model="keyword" ng-keydown="search($event)">
<ul class="hint-list">
<li ng-show="showPanel || (filtered.length > 0 && keyword.length > 0)" ng-repeat="option in filtered = (options | filter:keyword)" ng-click="appendOption(option, $index, $event)">{{option.name}}</li>
</ul>
ng-repeat exposes a $first variable that you can use to apply a class (here, we assume the class highlight is the class you want to apply):
<ul class="hint-list" ng-class="{highlight: $first}">
<li ng-show="showPanel || (filtered.length > 0 && keyword.length > 0)" ng-repeat="option in filtered = (options | filter:keyword)" ng-click="appendOption(option, $index, $event)">{{option.name}}</li>
</ul>
JSBin example

Resources