Adding a ng-click attribute to the header value of an accordion group - angularjs

I am trying to track the order in which a user clicks the headers of a bootstrap accordion. I am running into trouble trying to add a ng-click attribute to the repeated accordion-group. I am trying to limit the click area to just the header text, not the entire group. I thought a good way to do this was to pass the click $event into the ng-click function, but it is not working.
Here is a Plunker with the broken ng-click attribute here:
http://plnkr.co/edit/yOTRVRjxRDTlnZ9Qwsk4?p=preview
Can someone kindly help me figure out the best Angular way to solve this?

You can use the accordion-heading for the custom header.
Here is the sample:
<accordion-group close-others={{oneAtATime}} ng-repeat="(key, value) in groupedByCategory" is-open="value.open" >
<accordion-heading>
<a ng-click="clickTrack($event)">{{key}}</a>
</accordion-heading>
<div ng-repeat="c in value | orderBy: 'rating'">
<input type="radio" name="Category" value="{{c.name}}-{{key}} "> {{c.name}} | {{c.rating}}
</div>
</accordion-group>

Related

Unable to use ng-if with ng-repeat $index

I'm trying to use ng-if to display a button based on filters being present on screen. I'm using md-chips to show filters in categories.
HTML:
<div ng-repeat="filter in sc.filters track by $index">
<md-chips ng-model="filter.value" ng-if="sc.isArray(filter.value)" md-on-remove="sc.filter()"></md-chips>
</div>
<button ng-if="$first" ng-click="sc.newSearch()">clear filters</button>
I track the index and try to add the button if first item was present. It doesn't show the button at all. Any help appreciated.
$first should be used within an ng-repeat statement. In this case you don't want to use $first though.
If you want to add the button if the first item is present, why not just do something like this:
<button ng-if="sc.filters.length" ng-click="sc.newSearch()">clear filters</button>

AngularJS Bootstrap UI Typeahead Not Working Properly with Custom Popup Template

I'm working on a .NET MVC application that has some AngularJS pages in it. I'm trying to use Bootstrap UI Typeahead but it's not quite working properly.
If I start to type in the textbox the autocomplete popup opens with potential matches:
However, if I click on one of the matches nothing happens and the underlying angular model is not updated:
The really strange thing is that if I hit tab while the popup is open the first match will get selected and the angular model is updated appropriately:
This is the template I'm using:
<script type="text/ng-template" id="customTemplate.html">
<div class="search-result search-result--mos ng-scope" ng-if="matches.length > 0">
<ul>
<li ng-repeat="match in matches track by $index" class="search-result__item ng-scope uib-typeahead-match">
<div uib-typeahead-match match="match" index="$index" query="query" ng-bind-html="match.model.value"></div>
</li>
</ul>
</div>
This is the relevant front-end code:
<section class="mos intro" data-ng-controller="MosConverterController as vm">
<div>
<form ng-submit="GetCareers()" class="form form--mos">
<div class="form__row">
<div class="form__col form__col--half-plus">
<label for="MOS" class="form__label">MOS/Rate/Duty Title</label>
<input type="text" ng-model="vm.model.SearchTerm" uib-typeahead="career.value for career in vm.model.CareerResults | filter:$viewValue | limitTo:8" typeahead-popup-template-url="customTemplate.html" id="MOS" class="form__input--text" placeholder="Start Typing" name="MOS" required>
<div>Current Search Term: {{vm.model.SearchTerm}}</div>
<textarea>{{vm.model.CareerResults}}</textarea>
</div>
</div>
</form>
</div>
Here's our angular model. Note that we're using Typescript in this project:
import {MosConverterSearchResult} from "../models";
export class MosConverterModel implements Object {
SearchTerm: string = null;
CareerResults: MosConverterSearchResult[];
SelectedCareer: MosConverterSearchResult;
}
I followed the tutorial from the Angular Bootstrap documentation here for the "Custom popup templates for typeahead's dropdown" section but I can't figure out what I'm doing wrong. I'm sure it's something simple but I just can't figure it out. I should note that adding ng-click to the li element like they have in the tutorial doesn't fix the issue. I've tried it like this before:
<li ng-repeat="match in matches track by $index" class="search-result__item ng-scope uib-typeahead-match" ng-click="selectMatch($index)">
<div uib-typeahead-match match="match" index="$index" query="query" ng-bind-html="match.model.value"></div>
</li>
After banging my head against my desk for a couple of hours I figured out the issue was the ng-if in my template. The example in the tutorial link I posted above uses ng-show. ng-if destroys the DOM element and destroys its scope in the process. That's why nothing would happen when I clicked on an item from the list. Not sure why the tabbing would work though if this was indeed the case. If anyone knows please add a comment or better answer.

mdChips with filter

I'm a Newbie to AngularJS trying something with Angular Material and need some ideas / help.
I have icons of Font Awesome which are displayed with ng-repeat:
<ul ng-repeat="item in items">
<i ng-class="{'test': item.active}" class="fa fa-{{item.name}}">{{item.name}}</i>
</ul>
Below I have a list of the icons a with checkboxes:
<span ng-repeat="item in items | filter: item.active = false">
<input type="checkbox" ng-model="item.active"> {{item.name}}<br>
</span>
If a checkbox is activated, the list entry should disappear from the list.
This works with the filter of the property item.active
Now I want to display the activated items above the list with md-chips (Angular Material Chips).
So if a list item is activated, the element should be a md chip above the list (not displayed in the list anymore).
If I click on the 'X' in md-chip, only the state of the property item.active should change again to false.
I have my working files on Plunker, so my current working state can be read:
https://plnkr.co/edit/t3Xpp2AKEJHXBWhkLUYZ?p=preview
Does anybody got an idea how can I implement this?
The easiest way to do that is apply ng-click to your md-chip item and by this click it will set active = false:
...
<md-chips class="custom-chips" ng-model="items | filter: {active:true}" readonly="true">
<md-chip-template>
<span ng-click="$chip.active=false">
<strong>{{$chip.name}}</strong>
</span>
</md-chip-template>
</md-chips>
...
Here is a plnkr example.
EDIT:
Modified plunker to show only active md-chips.
Hope it will help.
You may want to filter the chips array using the builtin filterFilter function. The watcher that contains the latter will invoke the listener whenever the filterText changes.
...
$scope.array = [
"active directory",
"outlook",
"edrm",
"gcdocs",
"novell",
"iPrint",
"iManager",
"sigma",
"bitlocker",
];
$scope.filterText = "";
$scope.$watch('filterText', function(newValue, oldValue) {
$scope.filteredArray = filterFilter($scope.array, $scope.filterText);
}, false);
...
The following markup will render and filter the chipset.
<md-content flex class="md-padding">
<label>Filter: <input ng-model="searchText"></label>
<md-chips ng-model="filteredArray" readonly="ctrl.readonly"
md-removable="removable" placeholder="Enter an issue...">
<md-chip-template>
<strong>{{$chip}}</strong>
</md-chip-template>
</md-chips>
</md-content>
For further information on filters please see https://docs.angularjs.org/guide/filter
For further information on $watch please see https://docs.angularjs.org/api/ng/type/$rootScope.Scope

Angular Select Tag with Bootstrap Dropdown Styling

I need to create custom styling for a select dropdown (including the options). The more I've dug into this, the more I've realized that styling options is quite difficult.
I'm currently using Bootstrap's dropdown and it works great, except for the fact that I have to use a function to assign a value.
This is how I am currently using a 'custom select dropdown':
<div class="form-element-container">
<div class="drop-down dropdown-toggle">
<label for="chooseAdvisor"></label>
<div>
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">{{mySelection}}</button>
<ul class="dropdown-menu">
<li ng-repeat="option in options">{{option}}</li>
</ul>
</div>
</div>
</div>
You can see that on click, I have to manually set the option in my controller rather than it being directly bound to my model. Is there any way that I can use Bootstrap's dropdown styling with angular's select tag?
I would love to be able to use my options repeater with 'track by', etc:
<select ng-options="item as item.label for item in items track by item.id" ng-model="selected"></select>
You can try it:
https://angular-ui.github.io/bootstrap/#/dropdown
Just a suggestion, I've not tested it yet.
Update answer:
I think you can instead of angular module : acute-select
https://github.com/john-oc/acute-select
Demo : http://john-oc.github.io/

Angularjs make invisible accordion if subelement are filtered

i have created an accordion dynamically with angular.
Code:
<input type="text" class="form-control pull-left" ng-model="searchSingoloCampo.title">
<accordion-group ng-repeat="category in categories">
<li ng-repeat="resource in category.resources | filter:searchSingoloCampo">
</li>
</accordion-group>
The accordions is generated by a list , and inside each accordion there is a sublist of elements.
I can filter the element inside the accordion by using the simple angular filter, but i'm not able to handle the visibility of the Primary accordion when the sublist of element is completely "filtered" by the filter.
Any help?
Thank you
Thanks for the solution!
Here how i have handled it:
<accordion-group ng-repeat="category in categories" ng-show="(category.resources | filter:searchSingoloCampo).length>0">
In this way, i handle the visibility of the "master" accordion when the subset of element are filtered!
Thank you very much
One approach would be to introduce another variable which stores the contents of the filtered array. When the size of this array is 0, you can close the accordion. Something along these lines:
<accordion-group ng-repeat="category in categories" close-accodrion="filteredResources.length">
<li ng-repeat="resource in filteredResources = (category.resources | filter:searchSingoloCampo)">
</li>
</accordion-group>
I made up the "close-accordion" attribute, not sure how you actually close your accordion-group. This assumes you can open/close it w/a boolean expression like filteredResources.length. Maybe you just want to hide it w/a ng-show or ng-hide ... the same approach would work.

Resources