Not able to highlight selected items in custom-ng-select - angularjs

I created a custom ng-select with reactive form and imagine a list of data passed as dataList.
I have some default values from API to show them as selected but not able to do so. Items get's displayed in the ng-select input field but in the listing it does not make them as selected item.
Issue is not with the styles, everything is correct, because when i select item manually from list it works fine.
custom-select.component.html
<div [formGroup]="componentFormGroup">
<ng-select
class="select-dropdown"
[items]="dataList"
[bindLabel]="name"
[bindValue]="id"
[multiple]="true"
[placeholder]="placeHolder"
[formControlName]="componentFormControlName"
(change)="onSelectChange($event)">
<ng-template
ng-label-tmp
let-item="item"
let-clear="clear"
class="template-user">
<div class="selected-items pr-1">
<span class="ng-value-label label-name">
{{ item.name }}
</span>
<span
class="ng-value-icon right cross-icon"
(click)="clear(item)"
aria-hidden="true" >
×
</span>
</div>
</ng-template>
<ng-template ng-option-tmp let-item="item" let-index="index" let-item$="item$">
{{ item.id }} {{ item.name }}
</ng-template>
</ng-select>
</div>
custom-select.ts
this.dataList = [
{id: 17, name: Ahsan Shah}, {id: 28, name: John Doe}, {id: 25, name: Muhammad Yousuf}
]
// wait & get default data from API and assign it to a variable
this.defaultListData = defaultResponse?.resources; // sample [{id: 25, name: Muhammad Yousuf}]
// then assign value to form group
this.componentFormGroup.controls[this.componentFormControlName].setValue(this.defaultListData);
What i am doing wrong? Thanks in advance

Related

Angular 5 loop array

I am really a beginner in angular ionic and stuff. Here, my problem is I have tried using *ngFor to iterate someArr and pass to [something]="" but my page became blank after adding it. Can someone help me.
someArr = [1, 2, 3, 4, 5, 6]
<ion-content>
<myHeader *ngIf="qArr.length && qArr[cPg].letter === 'A'" [something]="">
</myHeader>
<myHeader *ngIf="qArr.length && qArr[cPg].letter === 'B'" [something]="">
</myHeader>
</ion-content>
When using ngFor you are creating local variable based on a class variable so you will have something like :
<div *ngFor="let item of someArr"></div>
where someArr is the class var = [1, 2, 3, 4, 5, 6]
So inside your div, you will have access to each item using this :
<div *ngFor="let item of someArr">
<p *ngIf="item === myFunction(item)"> {{ item }} </p>
</div>
Can you show what you've tried with ngFor?
Should looks something like this
<div *ngFor="let val of someArr">
{{val}}
</div>
Sidenote, you cannot combine ngFor and ngIf inside same tag
meaning this will not work
<div *ngFor="let val of someArr" *ngIf="val === 1">
{{val}}
</div>
But this would work
<div *ngFor="let val of someArr">
<div *ngIf="val === 1">
{{val}}
</div>
</div>
Update
something is not a real attribute, so we have no idea what you're refering to.
However you should be able to assign values to attribute. Take id attribute for instance
<div *ngFor="let val of someArr">
<div [id]="val">
{{val}}
</div>
</div>

How to bind tree structure to accordion or list(li) using AngularJS

How to bind tree structure to accordion using angular. The tree structure is like parent and child. How to get this? Am able to bind complete list.
angular code:
$scope.groups = [
{
ID: 1,
Name: "parent",
ParentID:0
},
{
ID: 2,
Name: "child",
ParentID: 1
},
{
ID: 3,
Name: "subchild1",
ParentID: 2
},
{
ID: 4,
Name: "subchild2",
ParentID: 2
}
];
view:
i tried to bind tree to accordion but not getting,
<uib-accordion close-others="oneAtATime">
<div uib-accordion-group class="panel-default" ng-repeat="grp in groups" is-open="status.open">
<uib-accordion-heading>
{{grp.Name}} <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</uib-accordion-heading>
{{grp.Name}}
</div>
</uib-accordion>
is there any options to bind tree in other way either accordion but using angular
Certainly there is a way to bind to this tree in AngularJS! To me this seems like a great use case for ngRepeat! Try this:
<div ng-repeat="(key, value) in groups"
<h1> {{value.ID}} </h1>
<h2> {{value.Name}} </h2>
<h3> {{value.ParentID}} </h3>
</div>
If you want the panels to expand then I would add another property to each object, isExpanded (or whatever you want to call it). Then you can hide/show the expanded content with ngIf, something like this:
<div ng-repeat="(key, value) in groups"
<h1> {{value.ID}} </h1>
<h2> {{value.Name}} </h2>
<h3> {{value.ParentID}} </h3>
<div ng-if="value.isExpanded === true">
<h3> Expanded content </h3>
</div>
</div>
You could also have nice animated transitions for expanded and closing the div with ngAnimate.
You could also check out Angular UI-Bootstrap Accordian or
(and here's a codepen example of it: http://codepen.io/funkybudda/pen/vEbgVv)
Here's a plunkr example of an AngularJS accordian: http://embed.plnkr.co/3y0Rq1/
Good luck!

Set Default Value for Multiple Selection Semantic UI Dropdown

I believe there is an answer to my question. I do exactly like some solution I found, but still I can't set default value to my dropdown. Here is my code.
<td>
<div ng-controller="daftarGroup" class="ui fluid multiple selection dropdown">
<input name="group" value="admin" type="hidden">
<i class="dropdown icon"></i>
<div class="default text">Group</div>
<div class="menu">
<div ng-repeat="y in groups" class="item" data-value="{{ y.gid }}">
{{ y.gid }}
</div>
</div>
<script type="text/javascript">
$('.ui.dropdown').dropdown();
</script>
</div>
</td>
My dropdown will have a list of group, one of the item is "admin". The data is presented using Angular. Everytime I load the page, I want the dropdown show "admin" as default value. On another fiddle, it run perfectly, but not in my machine. Every time I refresh the page, no value set on my dropdown, but the list of group is accessible. Any idea about my case?
Thanks.
You can use data-ng-options and ng-init with ng-model to have a default value.
HTML:
<select
ng-init="group = groups[0]"
ng-model="group"
data-ng-options="y.gid for y in groups">
</select>
Angular controller:
$scope.groups = [
{gid: 1},
{gid: 2}
];

Disable remaining checkboxes when n checkboxes have been checked with AngularJS

I'm just starting to learn AngularJS, so bear with me.
I have an app with a list that's bound to an array of objects (D&D spells). That list displays all the contents of the objects, by binding to the various values of the object. They filter on the value of a search textbox (query) and are sorted by two properties of the spell objects (level and name). That all works fine.
<div ng-repeat="(spellKey, spellValue) in spells | groupBy:'level'">
<a id="level-{{spellKey}}" class="anchor"></a>
<div ng-repeat="spell in spellValue | filterEach:query | orderBy:['level','name']">
<a id="spell-{{spell.name | replaceSpaces}}" class="anchor"></a>
...
</div>
</div>
I have a second list that I put in my navbar that's bound to the same array. It displays just the names and a checkbox next to each name; the checkbox determines whether or not to list each object in the first list (by setting spell.prepared to true or false). This also works fine.
<div class="navbar-header">
<form class="form-inline navbar-left col-xs-10" role="search">
...
</form>
<div class="col-xs-2">
<!-- button that displays list of spell links and checkboxes -->
<button type="button" id="btn-toggle-navbar" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#spell-nav">
...
</button>
</div>
<div class="collapse navbar-collapse" id="spell-nav">
<div class="checkbox" style="padding-bottom: 4px;">
<label>
<input type="checkbox" id="cbHideNonPrepared" ng-model="hideNonPrepared" />
Hide non-prepared
</label>
</div>
<div ng-repeat="(linkKey, linkValue) in spells | groupBy:'level'">
...
<ul style="list-style-type: none">
<li ng-repeat="spellLink in linkValue" class="checkbox">
<label>
<input type="checkbox" ng-model="spellLink.prepared" ng-class="{true: 'invis'}[spellLink.alwaysPrepared || spellLink.level == 0]" />
{{spellLink.name}}
</label>
</li>
</ul>
</div>
</div>
</div>
...
<!-- previous code block with added 'ng-hide' -->
<div ng-repeat="(spellKey, spellValue) in spells | groupBy:'level'">
<a id="level-{{spellKey}}" class="anchor"></a>
<div ng-repeat="spell in spellValue | filterEach:query | orderBy:['level','name']"
ng-hide="hideNonPrepared && !spell.prepared">
<a id="spell-{{spell.name | replaceSpaces}}" class="anchor"></a>
...
</div>
</div>
Last, I want to limit the number of checked checkboxes allowed to some value assigned in $scope (happens to be 9, but can be in arbitrary integer). I also want to exclude any values where spell.alwaysPrepared == true, but I assume that's just a filter I can add later.
This is where I'm unsure how to continue. I thought maybe I should set ng-check, but I wasn't sure to what.
You can use ng-disabled to disable your checkboxes under certain conditions.
Below is an example of how this might work for you. The key here is to create a function that will be called every digest cycle to determine whether each checkbox should be disabled.
angular.module("spells", [])
.controller("spellController", function($scope) {
$scope.shouldDisable = function(spell) {
return $scope.numPreparedSpells() == $scope.maxPreparedSpells && !spell.isPrepared;
};
$scope.spells = [
{name: "Magic Missile", isPrepared: false},
{name: "Lightning bolt", isPrepared: false},
{name: "Cure Major Wounds", isPrepared: false}
];
$scope.maxPreparedSpells = 2;
$scope.numPreparedSpells = function() {
var numPrepared = 0, len = $scope.spells.length;
for(var i = 0; i < len; i++) {
if ($scope.spells[i].isPrepared) {
numPrepared++;
}
}
return numPrepared;
};
});
With this setup in place, your spell list HTML might look like:
<div ng-controller="spellController">
<div ng-repeat="spell in spells">
<input type="checkbox" ng-model="spell.isPrepared" ng-disabled="shouldDisable(spell)"/>{{spell.name}}
</div>
</div>
Try it on Plunker.
That showed the basic idea, but it would be nice to have an O(n) solution:
angular.module("spells", [])
.controller("spellController", function($scope) {
$scope.shouldDisable = function(spell) {
return $scope.numPrepared == $scope.maxPreparedSpells && !spell.isPrepared;
};
$scope.spells = [
{name: "Magic Missile", isPrepared: false},
{name: "Lightning bolt", isPrepared: false},
{name: "Cure Major Wounds", isPrepared: false}
];
$scope.maxPreparedSpells = 2;
$scope.numPrepared = 0;
$scope.updateNumPreparedSpells = function(spell) {
if (spell.isPrepared) {
$scope.numPrepared++;
}
else {
$scope.numPrepared--;
}
};
});
The trick is to call updateNumPreparedSpells every time a checkbox is clicked:
<input type="checkbox" ng-click="updateNumPreparedSpells(spell)" ng-model="spell.isPrepared" ng-disabled="shouldDisable(spell)"/>{{spell.name}}
Now, the list of spells doesn't need to be traversed to count the number prepared. This, of course, assumes that the prepared state of each spell can only be changed by a click on the checkbox. If the data can be changed elsewhere, the count could be incorrect. Such a scenario is comparable to the cache-invalidation problem, which is known to be hard.

Getting a matching element from a different array

I have an array called groupUsers and another array within an array called tasks.users which look like this:
this.groupUsers = [
{$id: "simpleLogin:1", name: "bob"},
{$id: "simpleLogin:2", name: "joe"}];
this.tasks = [
{title: "do something", users:["simpleLogin:1","simpleLogin:2"]},
{title: "do something else", users:["simpleLogin:2"]}];
What I am trying to do is to get the user's name from groupUsers to display when I show the tasks rather than their id, but I am unsure in how to go about getting it. I assume it involves a filter?
With the following code I can display the tasks and the user id's assigned to each task, just not the names.
<div class="taskContainer" ng-repeat="task in todo.tasks | orderBy:'-when'">
<div><span ng-repeat="users in task.users">{{users}} </span></div>
<span> {{task.title}} </span>
</div>
You can expand to this function to fit your needs, right now it will return one name of the passed in id, $filter is an angular-service, remember to include it in your controller
$scope.getName = function(id){
return $filter('filter')(groupUsers, { name: id})[0].name;
};
here is your html
<div class="taskContainer" ng-repeat="task in todo.tasks | orderBy:'-when'">
<div><span ng-repeat="users in task.users">{{getName(users[0])}} </span></div>
<span> {{task.title}} </span>
</div>

Resources