0

I want a dropdown menu "subcategories" to be disabled with a grey background (and no possibility to open the dropdown menu with the defined placeholder) until the user has selected a value from the dropdownmenu "categories". I'm working with reactive forms. My lists "categories" and "subcategories" are hardcoded in the component class and I have a list selectedSubcategories declared on top to retain the list of subcategories based on the chosen category.

In the template-driven approach, I managed to disable this dropdown by using the [disabled] attribute.

My html for the dropdown menu "categories":

<select class="form-control" (change)="selectChangeCategory($event)">
          <option disabled selected>Select...</option>
          <option *ngFor="let category of categories">
            {{category.name}}
          </option>
        </select>

The selectChangeCategory method who keeps track of the value chosen in the dropdown menu "categories":

selectChangeCategory(event: any){
    this.selectedCategory = event.target.value;
    this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
  }

The selectSubcategory method who returns the right list of subcategories:

selectSubcategory(selectedCategory: string){
  if(selectedCategory == "Category 1"){
    this.selectedSubcategories = this.subcategoriesCategory1;
  }
  else if(selectedCategory == "Category 2"){
    this.selectedSubcategories = this.subcategoriesCategory2;
  }
  else{
    this.selectedSubcategories = [{name: 'empty!'}];
  }
  return this.selectedSubcategories;
  }

My html for the dropdown menu "subcategories":

<select class="form-control" (change)="selectSubcategory(selectedCategory)" value="subcategory.name" [disabled]="selectedCategory===''">
          <option disabled selected >Select...</option>
          <option *ngFor="let subcategory of selectedSubcategories">
            {{subcategory.name}}
          </option>
        </select>

The [disabled]="selectedCategory===''" works perfectly in the template-driven approach. The dropdown menu "subcategories" has a nice grey background and is disabled until the user selects a category. In the reactive form approach, this code fails. I manage to display only subcategories when a category has been chosen, but you can still open the dropdown menu of "subcategories" and see the "Select..." label.

Edit: this is my code in the ngOnchanges() method:

ngOnChanges(){
    this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
  }

I really appreciate any help here.

3 Answers 3

1

in reactive form you should disable controls in one of these forms

FormControl({value: '', disabled: true})

or reactivly

control.disable() 
control.enable()

because in template driven form you actually set disable attribute on control. or if you want a simpler solution you can create a custom directive like this

import { NgControl } from '@angular/forms';

@Directive({
  selector: '[disableControl]'
})
export class DisableControlDirective {

  @Input() set disableControl( condition : boolean ) {
    const action = condition ? 'disable' : 'enable';
    this.ngControl.control[action]();
  }

  constructor( private ngControl : NgControl ) {
  }

}

This directive does exactly disable attribute in context of reactive form

Sign up to request clarification or add additional context in comments.

1 Comment

I want to try your first approach. Can you explain where I can put the control.disable() (so without the separate directive)? How can I add the condition that the control can be enabled only when a category has been chosen?
0

I think the issue is with reactive form implementation. Check below example, this should resolve your issue. You can use [disabled]="!categoryForm.controls['category'].value" condition directly on formControlName so that if something is selected subcategories will be enabled then only. Also try to avoid assignment in ngOnChanges as it will get called a lot of times. Try assigning after initialization of service or after ngAfterViewInit hook.

      constructor( private formBuilder: FormBuilder){} //take an instance of FormBuilder
                
                this.categoryForm= this.formBuilder.group({
                  'category': [''], //if you want to initialize any selected value you can pass it directly here
                  'subCategory': ['']
            }); // initialize a form group
                 
             selectChangeCategory(event: any){
              this.selectedCategory = this.categoryForm.controls['category'].value;
              this.selectedSubcategories = this.selectSubcategory(this.selectedCategory);
             }
            selectSubcategory(selectedCategory: string){
              if(selectedCategory == "Category 1"){
              this.selectedSubcategories = this.subcategoriesCategory1;
            }
           else if(selectedCategory == "Category 2"){
            this.selectedSubcategories = this.subcategoriesCategory2;
           }
           else{
            this.selectedSubcategories = [{name: 'empty!'}];
           }
          return this.selectedSubcategories;
         }
//html file
    <form  [formGroup]="categoryForm" >
               <select class="form-control" formControlName="category" (change)="selectChangeCategory($event)">
                      <option value="" disabled selected>Select...</option>
                      <option *ngFor="let cat of categories" [value]="cat.name">
                        {{cat.name}}
                      </option>
                    </select>
            <select class="form-control" formControlName="subCategory"(change)="selectSubcategory(selectedCategory)[disabled]="!categoryForm.controls['category'].value">
                      <option value="" disabled selected >Select...</option>
                      <option *ngFor="let scat of selectedSubcategories" [value]="scat.name">
                        {{scat.name}}
                      </option>
                    </select>
                </form>

Let me know if you still face any challenge. Thank You.

Other ways : Instead of adding disabled condition in html this.categoryForm= this.formBuilder.group({ 'category': [''], //if you want to initialize any selected value you can pass it directly here 'subCategory': [{value: '', disabled: !this.selectedCategory}] }); // initialize a form group

5 Comments

I tried your code and now my dropdown for category is empty. I removed the html and the dropdown for category is filled again. The dropdown for subcategory isn't disabled. I can open it and see the Select... option, but there are no values in it.
please check the updated answer..maybe formControlName and *ngFor let var name was same that is why the dropdown was not loading , also in disable condition formGroup is categoryForm. Try again with this.
I think changing the names in the ngFor to avoid confusion with the formControlName is a good suggestion. The values appear again. I like your creative way of thinking about a solution for disabling the dropdown. Unfortunately, it's still not working... The dropdown is disabled, but stays disabled even when I select a category.
did u add the disable condition to formGroup or html ?
I've added the disable condition to the FormControl and added this.form.controls['subcategory'].enable() to the selectChangeCategory method. That works! Thanks for your input.
0
this.form.controls['formControlName'].enable()

or

this.form.controls['formControlName'].disable() 

works

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.