I have a custom dropdown in which i need to update or set default value using formControlName. I am using ControlValueAccessors in the shared component so that I can attach formControls to them in parent component and update the formControl values of the form.
Right now I have a issue in setting the default value by using the below code.
this.parentForm = this.fb.group({
district: ['bangalore', Validators.required], // bangalore should be set as my default value.
distance: [''],
state:['']
});
HTML code :
<form [formGroup]="parentForm">
<app-common-dropdown placeHolder="select district" [dropDownId]="'districtLabel'" [dataList]="['bangalore','chennai','pune']" formControlName="district" ></app-common-dropdown>
<app-common-dropdown placeHolder="select distance" [dropDownId]="'distanceLabel'" [dataList]="[100,200,300,400]" formControlName="distance" ></app-common-dropdown>
<app-common-dropdown placeHolder="select state" [dropDownId]="'stateLabel'" [dataList]="['karnataka','tamil nadu','mumbai']" formControlName="state" ></app-common-dropdown>
I have attached the example code for this https://stackblitz.com/edit/angular-p2gvtm. Kindly look into the demo code and help me as I am feeling that code is being written more for just setting and getting values using formcontrols.
Hello here is a stackblitz with refactored fork of your code.
First thing first if you want to display the value of the control you must pass it to the place where you are going to visualize it.
app.component
<form [formGroup]="parentForm">
<app-common-dropdown [controlForDisplay]="parentForm.get('city')"
placeHolder="select district"
[dataList]="['bangalore','chennai','pune']"></app-common-dropdown>
<app-common-dropdown [controlForDisplay]="parentForm.get('state')"
placeHolder="select distance"
[dataList]="[100,200,300,400]"></app-common-dropdown>
<app-common-dropdown [controlForDisplay]="parentForm.get('country')"
placeHolder="select state"
[dataList]="['karnataka','tamil nadu','mumbai']"></app-common-dropdown>
</form>
<button type="submit" (click)="getFormValues()">submit</button>
In your case I had added new input to your app-common-dropdown
, called controlForDisplay
in order to pass reference of the desired formControl
to the component. I also deleted the dropdownId
, the reason for that action I will explain latter on.
common-dropdown.component.html
<div [ngClass]="{'cs-active': dropdownOpen}"
class="cs-select cs-skin-border"
tabindex="0">
<span (click)="selectClicked($event)" class="cs-placeholder">
{{!!controlForDisplay.value ? controlForDisplay.value : placeHolder }}
</span>
<div class="cs-options">
<ul>
<li *ngFor="let item of dataList" (click)="selectOption(item)">
<span>{{item}}</span></li>
</ul>
</div>
</div>
So now we are heading to the common-dropdown.component.html
, where the important part is the following line
{{!!controlForDisplay.value ? controlForDisplay.value : placeHolder }}
Now through the added controlForDisplay
input we can access the formControl
reference that is holding the desired default value of the dropdown and visualize it if there is any default value or display the placeholder if the form control is empty.
commpon-dropdown.component.ts
@Component({
selector: 'app-common-dropdown',
templateUrl: './common-dropdown.component.html',
styleUrls: ['./common-dropdown.component.css']
})
export class CommonDropdownComponent {
@Input() placeHolder: string;
@Input() dataList: any;
@Input() controlForDisplay: FormControl = new FormControl()
dropdownOpen = false;
selectClicked(event: any) {
this.dropdownOpen = true
}
selectOption(value: string) {
this.controlForDisplay.patchValue(value)
this.closeDropDown('')
}
closeDropDown(event: any) {
this.dropdownOpen = false;
}
}
Here the major changes are that instead of using the native elements we are updating the formControl value trough the formControl API, called patch value, by doing so we are updating the whole form which is accessed both from the parent and the current component.
p.s.
You must add the CommonModule
inside your app.module.
Pretty much that fixes your problem. Keep in mind that it's almost always preferable to use the Angular API-s when creating web pages with Angular instead the DOM API-s, I would suggest the you take the Tour of Heroes , which is the official angular tutorial.