angular material select (auto complete) via code insertion - javascript

I have this markup:
<md-input-container class="md-block" flex-gt-sm>
<label>Language</label>
<md-select name="languageAndLocale" ng-model="$ctrl.voice.languageAndLocale" required>
<md-option ng-value="language2" ng-repeat="language2 in $ctrl.languagesAndLocales">
{{language2}}
</md-option>
</md-select>
</md-input-container>
and in my component i try to insert value to this field.
self.voice.languageAndLocale = "eng";
$scope.voiceForm.languageAndLocale = "eng";
How can I trigger autocomplete if I want to add just a prefix via code?
say the drop down contains eng:en and I set the field via code to be eng so I want it to be auto completed to eng:en as would have happened if i insert eng in the UI and no via code.

Related

Angular Material Autocomplete - how to select option

I am using Angular material autocomplete and I am trying to select value using #Input and form control. Almost everything is working fine. I am setting value using input like this:
#Input() set startingPointValue(value) {
this.control.setValue(value, { emitEvent: false });
this.resizeInput();
}
And the value of the input is properly set but when I open autocomplete, an option which should be selected don't have mat-selected class so basically there is no indication which option was selected and this is confusing. When I click same option again class is added.
Is there a way to do that using setValue or I need to use something else?
This is my autocomplete HTML:
<mat-form-field class="starting-point-filter-container">
<mat-label>{{ label }}</mat-label>
<input
id="inputStartingPoint"
#startingPointInput
matInput
placeholder="Type to filter results"
type="text"
[formControl]="control"
[matAutocomplete]="startingPointAutocomplete"
spellcheck="false"
/>
<mat-icon class="starting-point-icon--dropdown">arrow_drop_down</mat-icon>
</mat-form-field>
<mat-autocomplete
#startingPointAutocomplete="matAutocomplete"
[displayWith]="displayName"
(opened)="scrollToSelected()"
>
<perfect-scrollbar class="select-scrollbar" [config]="scrollBarConfig" #scrollFilterContainer>
<mat-optgroup
*ngFor="let group of groups"
[label]="group.name"
[class.mat-optgroup-no-label]="!group.name"
class="starting-point-group-container"
#scrollToContainer
>
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.id }}
</mat-option>
</mat-optgroup>
</perfect-scrollbar>
</mat-autocomplete>
Any help will be appreciated
Edit:
I created StackBlitz with autocomplete: https://stackblitz.com/edit/angular-ivy-mqwwky. You can inspect option number 2 after init. There is no class .mat-selected on it. You need to click it manually to set it properly. Question is how to do that during init?

How to pass whole object to input from md-autocomplete angular 4

Generally i have an object of objects -> filteredDrivers.
Single object looks like this:
DRIVER_ID: 99
DRIVER_NAME: "JOHN SNOW"
which i'm using in md-autocomplete:
<md-input-container>
<input type="text"
name="driver"
mdInput
[mdAutocomplete]="auto"
placeholder="Driver"
ngModel
>
</md-input-container>
<md-autocomplete #auto="mdAutocomplete">
<md-option *ngFor="let driver of filteredDrivers| async" [value]="driver"
ngDefaultControl>
{{ driver.DRIVER_NAME}}
</md-option>
</md-autocomplete>
And i want to pass whole object by submitting a form but in input i want to view just driver.DRIVER_NAME.
If i pass whole driver like [value]="driver" in input i see [object Object]
and form submit gives me full object
but when i go with [value]="driver.DRIVER_NAME" i can see what i want - JOHN SNOW but form submit gives me only driver.DRIVER_NAME
How can i pass whole object by submitting the form and see only driver.DRIVER_NAME property in input?
It's clearly documented in the Angular Material docs for
Autocomplete.
Specifically:
Setting separate control and display values
If you want the option's control value (what is saved in the form) to
be different than the option's display value (what is displayed in the
actual text field), you'll need to set the displayWith property on
your autocomplete element. A common use case for this might be if you
want to save your data as an object, but display just one of the
option's string properties.
To make this work, create a function on your component class that maps
the control value to the desired display value. Then bind it to the
autocomplete's displayWith property.
<md-input-container>
<input type="text" mdInput [formControl]="myControl" [mdAutocomplete]="auto">
</md-input-container>
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn">
<md-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.name }}
</md-option>
</md-autocomplete>

ng-change breaking angular material dropdown with Uncaught TypeError: Cannot read property '$$ngAnimateParentKey' of null

I am adding angular material to my site. I am able to run the following without any issue:
<md-input-container class="md-block" flex-gt-sm>
<label>Package</label>
<md-select ng-model="vm.search.parameters.package">
<md-option ng-repeat="package in vm.packages.list" value="{{package.id}}">
{{package.name}}
</md-option>
</md-select>
</md-input-container>
But I need to trigger a function on change, so I need to add an ng-change like so:
<md-input-container class="md-block" flex-gt-sm>
<label>Package</label>
<md-select ng-model="vm.search.parameters.package" ng-change="vm.updatePhotographersList()">
<md-option ng-repeat="package in vm.packages.list" value="{{package.id}}">
{{package.name}}
</md-option>
</md-select>
</md-input-container>
It works the first time and even runs the function and returns the correct data, but it won't allow me to select from the dropdown again and the console shows the following error:
Uncaught TypeError: Cannot read property '$$ngAnimateParentKey' of null
I have tried adding an ng-click to the the elements like so:
<md-input-container class="md-block" flex-gt-sm>
<label>Package</label>
<md-select ng-model="vm.search.parameters.package">
<md-option ng-repeat="package in vm.packages.list" value="{{package.id}}" ng-click="vm.updatePhotographersList()">
{{package.name}}
</md-option>
</md-select>
</md-input-container>
But these do not trigger at the correct time (seems like the function triggers before the ng-model updates). What is causing this error and what can I do to fix it?
Here are my dependencies:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.3/angular-material.min.css" />
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/1.1.3/angular-material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.0/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.0/angular-aria.min.js"></script>
This wasn't an issue with ng-animate at all. The problem was that my ui-router was triggering a reload. I'm still not sure why that was causing the problem, but here is the change that fixed it. I cahnged:
$state.transitionTo($state.current.name, newStateParameters);
to:
$state.transitionTo($state.current.name, newStateParameters, {notify: false});

md input container throwing error when I put input tags as child

Trying to use the following code from the Angular examples page:
<md-input-container>
<label>Vegetables</label>
<md-select ng-model="selectedVegetables"
md-on-close="clearSearchTerm()"
data-md-container-class="selectdemoSelectHeader"
multiple>
<md-select-header class="demo-select-header">
<input ng-model="searchTerm"
type="search"
placeholder="Search for a vegetable.."
class="demo-header-searchbox md-text">
</md-select-header>
<md-optgroup label="vegetables">
<md-option ng-value="vegetable" ng-repeat="vegetable in vegetables |
filter:searchTerm">{{vegetable}}</md-option>
</md-optgroup>
</md-select>
</md-input-container>
But this is the error I get:
Error: can only have one child input, textarea or select element!
The example can be found here (look for Select Header): https://material.angularjs.org/latest/demo/select
Well as i said on the comments the problem was the version of your Angular-material
Try to update it to the lastest version 1.0.9 or 1.1.0 and make a try.
<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.1.0/angular-material.min.js">

Trouble with filtering in AngularJS

The problem that i am facing is as follows: If i were to select a particular tag/author from the Tags/Author dropdown, the results are getting narrowed down as expected; however, when i click the 'Clear' button, the content disappears. I have to refresh the page for all the results to be displayed again.
I have another application using the same logic and in that clicing the 'Clear' button does not lead to the results disappearing. So i'm a bit concerned as to why it's working in one instance and not in the other.
I'd appreciate if you can help me understand where i'm going wrong here.
The foll is a part of my filter logic:
<md-input-container>
<label>Enter Search Term</label>
<input type="text" ng-model="classifiedsFilter">
</md-input-container>
<md-input-container>
<label>Tags</label>
<md-select ng-model="tag">
<md-option ng-repeat="tag in tags | orderBy: 'toString()'" value="{{ tag }}"> <!-- tags here refers to a newly defined array that stores only one instance of all the tags against the 'tags' property on each object/word -->
{{ tag }}
</md-option>
</md-select>
</md-input-container>
The foll are my filters on md-card:
<md-card ng-repeat="classified in classifieds | filter: classifiedsFilter | filter: tag:true | filter: expression | filter: book:true | filter: author:true | orderBy: order" flex-xs="100" flex-sm="40" flex-gt-sm="30" class="classified">

Categories