How to distinct HTML select options with angularjs? - javascript

I have an HTML for select tag, with this code :
<div ng-controller="Models">
<select ng-model="myModel" ng-options="Model.name for Model in Models" class="form-control"></select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>
and I want it to show only myModel.id==1.
how can I do it ?

I think this question needs a bit more of an explanation.
Do you mean you want to display a select for each model in models however only if the model.id ==1?
You can do this with a filter, while the models are being written to the page in your select box this filter checks if they have an .id == 1 and if TRUE then allows it to be written into the select.
I would imagine however that this means you'll only have 1 item in your select box as duplicate id's in objects are bad news bears.
angular.module('YOURAPPNAME', [])
.filter('myModelFilter', function() {
return function(myModel) {
if (myModel.id == 1) {
return myModel;
}
};
})
<div ng-controller="Models">
<select ng-model="myModel" ng-options="Model.name for Model in Models | myModelFilter" class="form-control"></select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>
EDIT: P.s.
Calling a controller and objects in your controllers "Model" and "Models" is confusing, I'd recommend choosing a different naming convention as AngularJS is an MVWhatever framework the term "Model" has a very different meaning to what you're using it for.

You could this on HTML side itself by using filter with strict checking true like ng-options="Model.name for Model in Models | filter: {id: 1}: true"
Markup
<div ng-controller="Models">
<select ng-model="myModel" class="form-control"
ng-options="Model.name for Model in Models | filter: {id: 1}: true" >
</select>
{{ {selected_Model:myModel.name} }} {{ {selected_Model:myModel.id} }}
</div>

Related

How to enable/visible mat-autocomplete only if condition gets true

UPDATED
Creating user input popup form, in one field trying to do autocomplete, with THIS solution.
I guess the auto-complete is working fairly fine, the issue is the options not coming below the input box.
Code:
<div>
<div class="modal-header">
</div>
<div class="modal-body">
<form novalidate [formGroup]="myform">
<div class="form-floating form-group">
<input type="text" class="form-control" id="fltName" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto">
<label for="fltName">Name</label>
<mat-autocomplete autoActiveFirstOption #emp="matAutocomplete" class="form-control">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{option}}
</mat-option>
<mat-autocomplete>
</div>
Question:
1. The options box should display, only if there 2 or less matches?
2. return emp names options by inserting emp_id?
How can I setup option such as {name:xyz, emp_id:123, emp_no:333}, and if I text any value should give name as option like if I write 33 should bring option xyz.
Question 1: The options box should display, only if there 2 or less matches
For this you need to apply the ng-container (To avoid rendering the option box) directive and apply the length condition over there according to your requirement.
<mat-autocomplete #auto="matAutocomplete">
<ng-container *ngIf="filteredOptions && (filteredOptions | async)?.length <= 2">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option" >
{{option.name}} //this is the value you always want to display
</mat-option>
</ng-container>
</mat-autocomplete>
Question 2: return emp names options by inserting emp_id?
The second part can be achieved by applying filter on the required fields, i.e.
private _filter(value: string): string[] {
if(value && value !== ""){
const filterValue = value.toLowerCase();
return this.options.filter(option => option.name.toLowerCase().includes(filterValue) || option.emp_no.toString().startsWith(filterValue));
} else {
return [];
}
}
apart from this you need to fix the pipe part as well, you have to pass the control value in RxJs startWith operator like,
this.filteredOptions = this.myControl.valueChanges
.pipe(
startWith(this.myControl.value),
map(value => this._filter(value))
);
Note: you can access the working solution here

AngularJS - checkboxes and dropdownlist

As I mentioned in topic i try do depends checkboxes from dropdownlist. I fill data to my dropdownlist from controller:
#RequestMapping(value = "/all", method = GET)
public List<Warehouse> findAll(){
return warehouseService.findAll();
}
$http
.get('/api/warehouses/all')
.then(function (response) {
$scope.warehouses = response.data;
});
Every Warehouse object have a List with package:
#OneToMany
private List<Package> packages = new ArrayList<>();
Now when i am creating Route and when i select one Warehouse from dropdownlist i wanna fill checkboxes from List from currently selected Warehouse.
Select Warehouse:
<select ng-model="credentials.warehouseStart">
<option ng-selected="credentials.warehouseStart == x" id="startId" ng-value="x" ng-repeat="x in warehouse" >{{x.name}}</option>
</select>
And checkboxes:
<div flex-xs flex="50">
<md-checkbox aria-label="Select All"
ng-checked="isChecked()"
md-indeterminate="isIndeterminate()"
ng-click="toggleAll()">
<span ng-if="isChecked()">Un-</span>Select All
</md-checkbox>
</div>
<div class="demo-select-all-checkboxes" ng-model="credentials.packages" flex="100" ng-repeat="item in packages">
<md-checkbox ng-checked="exists(item, selected)" ng-click="toggle(item, selected)">
{{ item.name }} <p> </p>
{{ item.user.firstName }} {{ item.user.lastName }}
</md-checkbox>
</div>
Checkbox fill:
$http
.get('/api/package/all')
.then(function (response) {
$scope.packages = response.data;
});
It is possible if i select one object in Dropdowlist(Warehouse) can i get a object id? Then i think i can get a correct chebkoxes by directive /package/all/{id} ?
I am basing my answer of your comment that every warehouse has a list of packages. That said, I am expecting packages to be a part of your GET call to /api/warehouses/all.
First, I would change your warehouse selection to use ngOptions:
<select ng-model="selected.warehouse"
ng-options="x.name for x in warehouses"></select>
Then, to list the packages:
<div ng-model="selected.packages"
ng-repeat="item in selected.warehouse.packages">
<input type="checkbox"
ng-checked="exists(item, selected)"
ng-click="toggle(item, selected)"> {{ item.name }}
<p> </p>
{{ item.firstName }} {{ item.user.lastName }}
</div>
I have created a sample here. Within, I have added a couple of wrappers around the package list in your ui using ngIf, but that's not necessary, but figured you'd probably have a view area to show based on whether or not a selection was made.

nested ng-repeat on two separate arrays

More than finding a way to resolve this, I am now interested in understanding why this is not working.
Let's say I have this array in angular:
$scope.movieThemes = [ 'Fiction', 'Drama'];
And another array with with movies like:
$scope.movies=[{theme:'Drama', movie:'One million dollar baby'}, {theme:'Drama', movie:'Green mille'},{theme:'Fiction', movie:'Avatar'}, {theme:'Fiction', movie:'The Hobbit'}]
I have an ngRepeat with my themes
<div ng-repeat= "t in movieThemes">
And a nested datalist filtering the themes:
ng-repeat="m in movies|filter:{theme:t}
Where t is from the parent repeater like:
<datalist id="movieList">
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</datalist>
OK as you can confirm on my fiddle this is not working:
Online Demo
But the question is why not?
Worth to mentioned without a data list it works fine:
Without Data List Demo
Try like this. i change your filter function syntax and also add select tag to dataList.
Edit:
Your problem cuase for datalist id. i.e your datalist ids in ne-repeat are same. i change datalist ids by adding $index to it. now it work correctly.
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', ["$scope",function MyCtrl($scope) {
$scope.movieThemes = [ 'Fiction', 'Drama'];
$scope.movies=[
{theme:'Drama', movie:'One million dollar baby'},
{theme:'Drama', movie:'Green mille'},
{theme:'Fiction', movie:'Avatar'},
{theme:'Fiction', movie:'The Hobbit'}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat= "t in movieThemes">
<input type="text" ng-model="t" />
{{t}} - {{$index}} <input type="text" placeholder="Users" list="movieList{{$index}}">
<datalist id="movieList{{$index}}">
<select>
<option ng-repeat="m in movies|filter:{theme:t}" value="{{m.movie}} - {{t}}"></option>
</select>
</datalist>
</div>
</div>
You can use groupBy filter. This way you don't need wot worry about themes array. You can write your own/use angular filters module.(https://github.com/a8m/angular-filter)
<ul>
<li ng-repeat="(key, value) in movies| groupBy: 'theme'">
Group name: {{ key }}
<ul>
<li ng-repeat="m in value">
player: {{ m.movie}}
</li>
</ul>
</li>
</ul>
BTW I like angular filters modules

angularjs two select with same model

I am not sure if this is possible or not, i am having single data list (ng-model) which is getting passed to more then 4 select as below HTML code. When i select some option in one select box then all another selected value in all select box get un-selected, i guess because of same ng-model is used in more then 4 select box.
Controller :-
angular.module('App').controller('RoleDialogController',
['$scope','entity', 'RoleType',
function($scope, entity,RoleType) {
$scope.role = entity;
$scope.roletypelist = RoleType.query();
});
HTML :-
<div class="form-group">
<label translate="App.role.role" for="field_regions">role</label>
<select class="form-control" id="field_regions" multiple
name="roletype" ng-model="role.roletypelist"
ng-options="roletype as roletype.roleTypeName for roletype in froletypelist = (roletypelist | filter:search | rolelistfilter:120:130) track by roletype.id "></select>
</div>
<div class="form-group">
<label translate="App.role.products" for="field_regions">products</label>
<select class="form-control" id="field_regions" multiple
name="roletype" ng-model="role.roletypelist"
ng-options="roletype as roletype.roleTypeName for roletype in froletypelist = (roletypelist | filter:search | rolelistfilter:130:140) track by roletype.id "></select>
</div>

AngularJS add CSS class on new item in ng-repeat

Here is my view for a list.
back...
<ul>
<input type="text" ng-model="search">
<li ng-repeat="item in items | filter:search | orderBy:'date'">
{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}
<button ng-click="deleteItem(item.ID)">del</button>
</li>
<form>
<input type="text" ng-model="itemName">
<input type="date" min="{{ date }}" max="{{ maxDate }}" value="{{ date }}" ng-model="itemDate">
<button ng-click="addItem()">add</button>
</form>
</ul>
On click my contoller adds a new item to the view, which works fine. Now i want to animate only the new item with css3. Therefore the new item needs a class. How can i achieve this with angular?
This should assign class the-class to the last element of the list dynamically:
<li ng-class="{'the-class': $last}" ng-repeat="item in items | filter:search | orderBy:'date'">
{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}
<button ng-click="deleteItem(item.ID)">del</button>
</li>
If you're using Angular 1.1.5, you can use ngAnimate enter event instead which is precisely designed for this kind of situation.
Have a look at http://www.nganimate.org/ and http://code.angularjs.org/1.1.5/docs/api/ng.directive:ngAnimate
If you use a function to add an Item, you could also set a variable to know which Id is the last inserted while adding the item to the list
First, you can see what I did here http://jsfiddle.net/DotDotDot/Eb2kR/
I just created a lastInsertedId variable, which I use to add a class in the ng-repeat :
<span ng-class='{lastinserted: item.ID==lastInsertedId}'>{{ item.ID }} - {{ item.heading }} - {{ item.date | date:"dd.MM.yy" }}</span>
I had no idea how you implemented you addItem method and what are your IDs, so I created my own method and I assumed your IDs are unique numbers, but it could work with anything (hoping you can find a unique set of data)
$scope.addItem=function(){
var dd=new Date($scope.itemDate);
$scope.items.push( {"ID":$scope.items.length+1, "heading":$scope.itemName, "date":dd.getTime()});
$scope.lastInsertedId=$scope.items.length;
}
I change the last inserted id, which will apply the selected class to the item
You could also unset the lastInsertedId value in the delItem() method
If you have a more difficult logic (here I assumed you had unique IDs) you can also use a function in the ng-class. Here, on my example it wouldn't be hard to code :
$scope.amITheOne=function(item){
return item.ID==$scope.lastInsertedId;
}
then
<span ng-class='{lastinserted: amITheOne(item)}'>
It doesn't change much with a simple logic, but you could totally have a logic based on the ID, the name and the date for example
Have fun

Categories