ui-select show array elements as choices in drop down - javascript

I am using ui-select as follows.
<ui-select id="ItemId" ng-model="ctrl.ItemId" theme="bootstrap"
ng-disabled="ctrl.DownDisabled" required>
<ui-select-match placeholder={{ctrl.Placeholder}}>{{$select.selected.item}}
</ui-select-match>
<ui-select-choices
repeat="item in ctrl.owners.components">
<div ng-bind-html="item | highlight: $select.search"></div>
</ui-select-choices>
<ui-select-no-choice>
No features were found
</ui-select-no-choice>
</ui-select>
The JSON it is itearing over is
ctrl.owners = {
value : 123,
teamName : ABC,
components : [a,b,c]
};
But UI dropdown shows "No features were found" . What is the issue. My objective is to show the components as individual choices in the drop-down. AFAIK this needs to be done in some way by using a nested repeat in ui-select-choices . How canI do that?

<div class="form-group ">
<ui-select ng-model="person.selected" theme="bootstrap">
<ui-select-match placeholder="Select or search a person in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item in people | filter: $select.search">
<div ng-bind-html="trustAsHtml((item.name | highlight: $select.search))"></div>
<small ng-bind-html="trustAsHtml((item.email | highlight: $select.search))"></small>
</ui-select-choices>
</ui-select>
</div>
$scope.people = [
{ name: 'Adam', email: 'adam#email.com', age: 12, country: 'United States' },
{ name: 'Amalie', email: 'amalie#email.com', age: 12, country: 'Argentina' }];
You can use like this it will work.
Here trustAsHtml is method.
$scope.trustAsHtml = function(value) {
return $sce.trustAsHtml(value);
};

Related

How can I filter data in two fields using angular ui-select?

I have an angular app and using ui-select, on the page there two input fields with multiselectors, both of them dropdown lists. Everything works fine. When I choose an option in first field (in this case its programming language) the second field (frameworks that belongs to particular programming language) must be filtrated and show only list of correct frameworks.
WORKING CODE:
<div class="col-md-2 col-md-offset-2">
<ui-select multiple ng-model="newdeveloper.langs">
<ui-select-match placeholder="Select skills">[[ $item.lang_name ]]</ui-select-match>
<ui-select-choices repeat="item in (allSkillList.langs | filter: $select.search) track by item.id">
<span ng-bind="item.lang_name"></span>
</ui-select-choices>
</ui-select>
</div>
<div class="col-md-2">
<ui-select multiple ng-model="newdeveloper.frameworks">
<ui-select-match placeholder="Select frame">[[ $item.frame_name ]]</ui-select-match>
<ui-select-choices repeat="item in (allSkillList.frameworks | filter: $select.search) track by item.id">
<span ng-bind="item.frame_name"></span>
</ui-select-choices>
</ui-select>
</div>
JSON WITH DATA:
{
"frameworks": [
{
"id": 1,
"frame_name": "Django",
"frame_lang": 1
},
{
"id": 2,
"frame_name": "jQuery",
"frame_lang": 2
},
{
"id": 3,
"frame_name": "Spring",
"frame_lang": 3
}
],
"langs": [
{
"id": 1,
"lang_name": "Python"
},
{
"id": 2,
"lang_name": "JavaScript"
},
{
"id": 3,
"lang_name": "Java"
},
]
}
"frameworks.frame_lang" must match with "langs.id" in order to make filter work properly.
THE QUESTIONS:
How can I resolve this problem? Should I use some custom filter?
Thank you!
You have to create a custom filter filterByLang and then apply it to frameworks repeat.
angular.module('demoApp').filter('filterByLang',function(){
return function(frameworks,langs){
var filtered = [];
if(langs && langs.length){
angular.forEach(frameworks,function(framework){
angular.forEach(langs,function(lang){
if(framework.frame_lang == lang){
filtered.push(framework);
}
})
});
}
return filtered;
};
});
Inside html update your second dropdown code by.
...
<ui-select-choices repeat="item in (allSkillList.frameworks | filterByLang: newdeveloper.langs | filter: $select.search) track by item.id">
...

Angular UI select not displaying

I am currently using ui-select (https://github.com/angular-ui/ui-select) for dropdowns. I have included select.js and select.css in my index.html file. I have also installed angular-sanitize through bower.
This is what my controller looks like :
use strict';
angular.module('myApp.home', [ 'ui.select', 'ngSanitize']).controller('ScheduleCtrl', ScheduleCtrl);
ScheduleCtrl['$inject'] = [ '$stateParams', '$state' ];
function ScheduleCtrl($stateParams, $state) {
var vm=this;
vm.itemArray = [
{id: 1, name: 'first'},
{id: 2, name: 'second'},
{id: 3, name: 'third'},
{id: 4, name: 'fourth'},
{id: 5, name: 'fifth'},
];
vm.scheduleEvents = [{
id:1,
name:'Event1'
},
{
id:2,
name:'Event2'
}];
}
And my view contains :
<ui-select ng-model="selectedItem">
<ui-select-match>
<span ng-bind="$select.selected.name"></span>
</ui-select-match>
<ui-select-choices repeat="item in (vm.itemArray | filter: $select.search) track by item.id">
<span ng-bind="item.name"></span>
</ui-select-choices>
</ui-select>
However, my view is blank and it does not seem to be hitting the ui-select directive.
Remove ( and ).
<ui-select-choices repeat="item in vm.itemArray | filter: $select.search track by item.id">
<span ng-bind="item.name"></span>
</ui-select-choices>
See running on plunker.
Another thing you can test, comment this line:
//ScheduleCtrl['$inject'] = [ '$stateParams', '$state' ];
I didn't understand what it is doing, but with it the example on plunker doesn't work.

angular ui-select - update selected when updating choices

So I have a pretty basic select that looks like this:
<ui-select theme="select2" search-enabled="false" ng-model="obj.myModel">
<ui-select-match>{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="item.value as item in choices">
<span>
{{item.name}}
</span>
</ui-select-choices>
</ui-select>
Let's say the choices are defined as
$scope.choices = [
{value: 'some_value_1', name: 'Default name'},
{value: 'some_value_2', name: 'Default name 2'}
]
Now let's assume that the user has selected the item with value some_value_1. After that a server response comes in that updates the choices list with different names
$scope.choices = [
{value: 'some_value_1', name: 'Real name'},
{value: 'some_value_2', name: 'Real name 2'}
]
Notice that the value part that is saved in the model stays the same. The name in <ui-select> is still Default name when I would want it to change to Real name.
plnkr.co
Is there a way to make the selected name correspond to updated choices?

AngularJS dynamically specify flag on orderBy

I'm trying to perform an orderBy operation in AngularJS based on a chosen select box value.
The problem I'm having is changing the optional :true or :false flags depending on the selected value.
For example, 'alphabetical' order, the flag would have to be :false, but for 'date' (most recent), the flag needs to be :true.
I've tried hardcoding the flags in the scope options but still not working.
html
<div>
<label>Country filter</label>
<input type="text" ng-model="countryFilter" />
<label>Order by</label>
<select ng-model="selectedOrder" ng-options="option for option in options"></select>
</div>
<ul>
<li ng-repeat="detail in details | filter:{country: countryFilter} | orderBy:selectedOrder">{{ detail }}</li>
</ul>
app.js
var app = angular.module('plunker', []);
app.controller('MyCtrl', function($scope) {
// order by options
$scope.options = ['country', 'address', 'date'];
// all countries
$scope.details = [{
id:1, country:'Finland', address:'Mainstreet 2', date:'2015-05-02'
},{
id:2, country:'Mexico', address:'Some address', date:'2015-05-05'
},{
id:3, country:'Canada', address:'Snowroad 45', date:'2015-03-02'
}];
});
Here is a plunker.
I would suggest to change your order options from strings to objects, which include the information if the list should be reversed for this order:
$scope.options = [{value : 'country', reversed : false}, {value : 'address', reversed : false}, {value : 'date', reversed : true}];
And the ng-repeat to:
<li ng-repeat="detail in details | filter:{country: countryFilter} | orderBy:selectedOrder.value:selectedOrder.reversed">{{ detail }}</li>
http://plnkr.co/edit/JXtHa2jXUy7Y5BsvsdL9?p=preview

ng-repeat continuously fired on hover

I'm using UI-Select 0.8.4 and have a large data set. Then I'm using UI-Select to display property values in a dropdown beside the data set. I'm using that for filters. So when choosing from the dropdown, will filter the results.
Every time when I hover over some item in the dropdown, it always fires the ng-repeat filter.
This is lagging my application because I'm working with a large set in the ng-repeat.
Why is this?
GIF:
http://i.imgur.com/cStlXzy.gif
Plunker (open console and see for yourself):
http://plnkr.co/edit/OxiutZ8t4IX1bOxiOTgo?p=preview
HTML:
<h3>Age list</h3>
<p>Selected: {{age.selected}}</p>
<ui-select ng-model="age.selected" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select a person">{{$select.selected}}</ui-select-match>
<ui-select-choices repeat="age in ageArray | filter: $select.search">
<div ng-bind="age | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
JavaScript:
$scope.theFilter = function(item) {
console.log(item);
return item;
};
$scope.ageArray = [];
$scope.$watch('people', function(item) {
for(var i = 0; i < item.length; i++) {
$scope.ageArray.push(item[i].age);
}
});
$scope.people = [
{ name: 'Adam', email: 'adam#email.com', age: 10 },
{ name: 'Amalie', email: 'amalie#email.com', age: 12 },
{ name: 'Wladimir', email: 'wladimir#email.com', age: 30 },
{ name: 'Samantha', email: 'samantha#email.com', age: 31 },
{ name: 'Estefanía', email: 'estefanía#email.com', age: 16 },
{ name: 'Natasha', email: 'natasha#email.com', age: 54 },
{ name: 'Nicole', email: 'nicole#email.com', age: 43 },
{ name: 'Adrian', email: 'adrian#email.com', age: 21 }
];
Edit: I even tried to filter the property values out of the "data set array" and using that in the dropdown, but it doesn't work.
Edit 2: If you think that the watch was triggering this, I removed the watch and this is still a problem: http://plnkr.co/edit/oD3Tt3vfjtOjADMnemW1?p=preview
Edit 3: Still haven't found a solution for this so I'm stuck with chosen. I created an issue but haven't gotten any response. Please upvote the issue if you want this fixed.
The issue is that the filter is executing on every $digest (every ng-mouseenter, ng-click, etc). For a huge data set, this can obviously kill performance. (See this article http://www.bennadel.com/blog/2489-how-often-do-filters-execute-in-angularjs.htm)
Instead, try a $watch on the age.selected value, then applying a filter only when that value actually changes.
http://plnkr.co/edit/TIeKPAyrAQsGHwakqwEp?p=preview
HTML
<!-- filtered list "ageMatches" -->
<ul ng-show="age.selected">
<li ng-repeat="person in ageMatches">{{person.name}} - {{person.age}}</li>
</ul>
<!-- default list of all "people" -->
<ul ng-hide="age.selected">
<li ng-repeat="person in people">{{person.name}} - {{person.age}}</li>
</ul>
JS
// add age to scope
$scope.age = {};
// add age match placeholder
$scope.ageMatches = [];
// watch age.selected for changes, apply filter
$scope.$watch('age.selected', function(newVal, oldVal){
if(newVal){
$scope.ageMatches = $filter('filter')($scope.people, {age: newVal});
}
});

Categories