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
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 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!
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}
];
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.
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>