I am creating a website that would display multiple collapsible list (e.g. categories & sub categories), so far I have managed to create dynamic divs using ng-repeat but my problem is when toggling the collapse. In the second category, when trying to toggle to display/hide the list, it toggles the list on the first div instead.
HTML:
<div class="col-lg-9 col-sm-3 col-xs-12">
<div ng-repeat="cat in categories">
<div class="row">
<div class="col-lg-2 col-sm-3 col-xs-3">
<img src="http://placehold.it/75x75" class="img-circle center-block img-responsive" height="75" width="75">
</div>
<div class="col-lg-9 col-xs-8">
<b>
{{cat}}
</b>
</div>
</div>
<hr>
<div class="row" ng-repeat="item in items ">
<div class="col-lg-12 col-xs-12">
<p ng-click="toggleCollapse($index + 1)"><i class="fa fa-fw fa-arrow-circle-right"></i>
{{item}}
</p>
<div id="collapse{{ $index + 1}}" class="collapse collapse-checklist">
<div ng-repeat="c in checklist">
<p>Lorem Ipsum</p>
</div>
JavaScript:
$scope.toggleCollapse = function (ind) {
var collapseInd = ("#collapse" + ind);
$(collapseInd).collapse('toggle');
};
Now, I have identified that the problem is ng-repeat creates the div with the same ID(collapsei) which causes the function on the second div toggle the list on the first div instead.
My function works well in the first cat div, but on all other div, it still toggles the list on the first div. Can anyone help me fix my function so it would toggle the lists on its respective div?
Try this : You can avoid using ID by calling collapse on next div element. See below code
$scope.toggleCollapse = function (ind) {
$(this).next('div.collapse.collapse-checklist').collapse('toggle');
};
If you have some duplicate id by using ng-repeat, you should probably use it like this:
<tr ng-repeat="(key, value) in data">
<td> {{key}} </td> <td> {{ value }} </td>
</tr>
So, now you will see that key will be changed every-time. And making some custom id.
<tr ng-repeat="(key, value) in data">
<td id="myCustomId_{{key}}"> {{key}} </td>
<td> {{ value }} </td>
</tr>
you will get a unique id.
This method is listed in the docs: http://docs.angularjs.org/api/ng.directive:ngRepeat
As suggested by tudor-gergely.
Used angular approach.
<p ng-click="showChecklist = !showChecklist"><i class="fa fa-fw fa-arrow-circle-right"></i>
{{item}}
</p>
<div ng-show="showChecklist">
<div ng-repeat="c in checklist">
<p>Lorem Ipsum</p>
</div>
Thanks!
Related
I would like to know how to do the ngFor with two rows in angular flex layout.
<div *ngFor="let item of items">
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-1" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
<div class="item item-2" fxFlex="50%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
<div class="container" fxLayout fxLayout.xs="column" fxLayoutAlign="center" fxLayoutGap.xs="0">
<div class="item item-3" fxFlex="100%">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
</div>
Here its looping but each time its printing 3 values for every index. I would like to print index 0 value of first column, index 1 on second column and index 2 value on second row.
I've created for you an example on stackblitz, based on your requirements.
The correct way would be :
<div class="container" fxLayout="row wrap" fxLayoutAlign="center" fxLayoutGap.xs="0">
<!-- you can use ngClass to manage 'item-1' or 'item-2' style -->
<div class="item" fxFlex="50%" *ngFor="let item of items">
<div fxLayoutAlign="center" class="item-label">
{{item.name}}
</div>
<div fxLayoutAlign="center" class="item-value">{{item.value}}</div>
</div>
</div>
The wrap/nowrap property on the fxLayout directive does everything, because childs are set with fxFlex="50%".
I put out fxLayout.xs to render it correctly on stackblitz.
Here is #angular/flex-layout documentation
Hope it helps ;-)
The "wrap" parameter in the "fxLayout" is used to wrap the child content with the help of "fxFlex"
I trying to filter an ng-repeat view of multiple item titles wrapped in hyperlinks but am getting results based on the Title and the URL string value.
How can I limit my filter to only the text of the Title and omit positives in the URL? E.g. If I search for "email" I would get results for items that have "email" in their title or text body but I would also get results that have "email" in their URL string.
Search Google for email<p>Blah blah blah</p>
Any help is greatly appreciated!
<div ng-app="Home">
<div ng-controller="Details">
<div class="row">
<div class="col-xs-12 col-sm-5 col-md-4 col-lg-4">
<div class="searchBox">
<input type="search" ng-model="search"/>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 col-md-4 col-lg-4" ng-repeat="SectionItem in Sections" ng-init="filterResult=[]" ng-hide="filterResult[$parent.$index].length <= 0">
<div class="panel panel-default">
<div class="panel-body">
<div>
<h1>{{SectionItem.Title}}</h1>
</div>
<div>
<!-- BEGIN: items belonging to this section -->
<table class="table table-condensed table-hover">
<tr ng-repeat="item in (filterResult[$parent.$index] = (SectionItems | filter:search | filterByMatchingSection:SectionItem.Title)) ">
<td>
<div class="container-fluid">
<div class="row">
<div class="col-sm-12" ng-show="item.Title != null">
{{item.Title}}
<p>
{{item.TextBody}}
</p>
</div>
</div>
</div>
</td>
</tr>
</table>
<!-- END: items belonging to this section -->
</div>
</div>
</div>
</div>
</div>
</div>
This should do the trick
<input type="search" ng-model="search.Title"/>
According to the docs you can use a pattern object expression. For your case this should work:
... | filter: { title: search } | ...
This will search only in the title property.
If I have in my view this html code, generated dinamically with ng-repeat:
<div ng-repeat="item in selectedProcedures track by $index">
<span style="display:none;">{{item.id}}</span>
<div class="row" ng-repeat="item2 in item.serviceComposite.designators">
<div class="col-sm-10 col-md-10 col-xl-10">
<div>
<button ng-click="hidePartBindings{{$parent.$index}} = !hidePartBindings{{$parent.$index}}" style="background: none; border: 0; float:left; text-align:center; margin-right: 5px;"><img src="./css/themes/parsek/img/layout/caret-blue.svg"/></button>
<span id="serviceComposite{{$parent.$index}}">{{ item2.extension }}</span>
</div>
<div class="row" id="partBindings{{$parent.$index}}" ng-repeat="item4 in item.serviceComposite.partBindings" ng-show="hidePartBindings{{$parent.$index}} === false">
<div ng-repeat="item5 in item4.part.designators">
<span class="col-sm-12 col-md-12 col-xl-12">
<a style="margin-left: 3rem;" href="#item-information" class="lightbox2" ng-click="checkIfIsModified({{item5.id}}, $event)">{{ item5.extension }}</a>
</span>
</div>
</div>
</div>
</div>
</div>
How can I initialize all generated hidePartBindings{{$parent.$index}} to true in my controller?
Thanks in advance.
You could also consider a controller for each instance of your repeated item. Of course, it would not be the best thing to do if you have hundreds of items.
<div class="row" ng-repeat="item2 in item.serviceComposite.designators" ng-controller="ItemController">
If you had fewer items and wanted to go down the route of a controller for each item, it would be a simple case of setting item.hideParts = true in your item controller.
I want to select the first item in my ng-repeat as soon the list is loaded to the user, is there an easy way to do that?
Right now im using the ng-click, but i dont know how to automatic click that first item.
This is my ng-repeat
<div ng-hide="hideMembershipSection" ng-repeat="membership in memberships" class="row">
<div class="membership-box col-lg-9 col-md-9 col-sm-9 col-xs-8">
<img class="img-responsive" ng-src="/images/onlinesalg_ny/{{ membership.image }}">
<h1 class="text-uppercase">{{ membership.titel_onlinesalg }}</h1>
<p>{{ membership.onlinesalg_produktbeskrivelse }}</p>
</div><!-- col-lg-9 -->
<div class="membership-box__price col-lg-3 col-md-3 col-sm-3 col-xs-4 text-center">
<h1>
<small>Kr.</small>
{{ membership.pris }},-
</h1>
<button ng-click="selectMembership(membership)" type="button" ng-class='{"btn-success": membership.pid == success}' class="text-uppercase btn btn-primary" ng-disabled="membership.pid == success">{{ membership.pid === success ? "valgt" : "vælg"}}</button>
</div><!-- col-lg-9 -->
In the controller, after the code where you load the list into $scope.memberships, what about using the line:
selectMembership($scope.memberships[0]);
This is essentially doing what ng-click is doing, but after the list is loaded. It depends on what your selectMembership function does though.
you can use ng-init to select first element by default as in ng-init="ngModelFieldName=memberships[0]
i dont know the name of the ng-model hence gave the name ngModelFieldName
<div ng-hide="hideMembershipSection" ng-repeat="membership in memberships" ng-init="ngModelFieldName=memberships[0]" class="row">
I am trying to group items using the following trick:
<div data-bind="foreach: types ">
<div data-bind="foreach: $root.items">
<div data-bind="if: type == $data">
<span data-bind="text: name"></span>
</div>
</div>
</div>
Notice that on line 3, I am trying to filter current date based on a value that comes from the outer loop.
Is this possible?
Here is a JS Fiddle: if you look at line 5 the value is hard coded, and I am trying to use $data in place of "odd".
You can access the iterator in the outer loop using $parent...
<div data-bind="foreach: types ">
<div data-bind="foreach: $root.items">
<div data-bind="if: type == $parent">
<span data-bind="text: name"></span>
</div>
</div>
</div>
JSFiddle