最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to properly handle mutually exclusive checkbox selection with reactive forms - Stack Overflow

programmeradmin3浏览0评论

I need some assistance with handling checkbox selection using angular. I have 4 checkboxes, ALL, FirstName, LastName, MiddleName. When the page loads ALL should be the only one selected. If I click any of the other boxes ALL should be deselected. Likewise if I click ALL again the other checkboxes should be deselected. Currently ALL is selected when the page loads. I then can click the other boxes. However I can't click ALL unless I manually uncheck the other boxes. Any assistance you can provide will be greatly appreciated.

I am using component projection to include the child form type filter in the parent.html.

— parent html

<form [formGroup]="reportListFG">
<app-form-type-filter 
                  [formGroup] ="reportListFG.get('filterGroup')"
                  (formTypeFilterChanged)="onFormTypeSelectionChange($event)"
                  (clear)="clearReceipt($event)" 
                  #formFilter></app-form-type-filter>

—parent ts

this.reportListFG = this.fb.group(
    {
      Address: [[]],
      PhoneNumber: [[]],
      filterGroup: this.fb.group({
      ALL: [true],
      FirstName: [false],
      LastName: [false],
      MiddleName: [false],
      }),
      
    
  )
  // Listen to form changes and handle the logic for "All" and other checkboxes
this.reportListFG.get('filterGroup').valueChanges.subscribe(values => {
  this.handleCheckboxSelection(values);
});

}

  handleCheckboxSelection(values: any) {
  const allSelected = values.ALL; 

  console.log('Inside handleCheckbox');

  // If "All" is selected and another box is checked, uncheck "All"
  if (allSelected && (values.FirstName || values.LastName || values.MiddleName)) {
    this.reportListFG.get('filterGroup')?.patchValue(
      {
        ALL: false
      },
      { emitEvent: false } // Prevent infinite loop
    );
  }

  // If "All" is selected, ensure other checkboxes remain unchecked
  else if (allSelected) {
    console.log(allSelected, '********');
    this.reportListFG.get('filterGroup')?.patchValue(
      {
        FirstName: false,
        LastName: false,
        MiddleName: false
      },
      { emitEvent: false } // Prevent infinite loop
    );
  }
}

I need some assistance with handling checkbox selection using angular. I have 4 checkboxes, ALL, FirstName, LastName, MiddleName. When the page loads ALL should be the only one selected. If I click any of the other boxes ALL should be deselected. Likewise if I click ALL again the other checkboxes should be deselected. Currently ALL is selected when the page loads. I then can click the other boxes. However I can't click ALL unless I manually uncheck the other boxes. Any assistance you can provide will be greatly appreciated.

I am using component projection to include the child form type filter in the parent.html.

— parent html

<form [formGroup]="reportListFG">
<app-form-type-filter 
                  [formGroup] ="reportListFG.get('filterGroup')"
                  (formTypeFilterChanged)="onFormTypeSelectionChange($event)"
                  (clear)="clearReceipt($event)" 
                  #formFilter></app-form-type-filter>

—parent ts

this.reportListFG = this.fb.group(
    {
      Address: [[]],
      PhoneNumber: [[]],
      filterGroup: this.fb.group({
      ALL: [true],
      FirstName: [false],
      LastName: [false],
      MiddleName: [false],
      }),
      
    
  )
  // Listen to form changes and handle the logic for "All" and other checkboxes
this.reportListFG.get('filterGroup').valueChanges.subscribe(values => {
  this.handleCheckboxSelection(values);
});

}

  handleCheckboxSelection(values: any) {
  const allSelected = values.ALL; 

  console.log('Inside handleCheckbox');

  // If "All" is selected and another box is checked, uncheck "All"
  if (allSelected && (values.FirstName || values.LastName || values.MiddleName)) {
    this.reportListFG.get('filterGroup')?.patchValue(
      {
        ALL: false
      },
      { emitEvent: false } // Prevent infinite loop
    );
  }

  // If "All" is selected, ensure other checkboxes remain unchecked
  else if (allSelected) {
    console.log(allSelected, '********');
    this.reportListFG.get('filterGroup')?.patchValue(
      {
        FirstName: false,
        LastName: false,
        MiddleName: false
      },
      { emitEvent: false } // Prevent infinite loop
    );
  }
}
Share Improve this question asked Mar 17 at 16:23 SunnySunny 1671 gold badge3 silver badges16 bronze badges 3
  • please share working example on stackblitz, steps to replicate issue and expected output. – Naren Murali Commented Mar 17 at 16:38
  • This is what radio groups are for. – Sam Scholefield Commented Mar 18 at 8:36
  • @SamScholefield, that was my first thought, but it sounds like the first, last, middle names can be selected simultaneously. – mykaf Commented Mar 18 at 13:08
Add a comment  | 

1 Answer 1

Reset to default 1

Here you have an example in HTML and vanilla JavaScript. The fieldset is rather handy here because it's easier to get a hold of the other checkboxes.

document.forms.form01.addEventListener('change', e => {
  let form = e.target.form;
  switch (e.target.name) {
    case 'all':
      if (e.target.checked) {
        [...form.others.elements].forEach(input => input.checked = false);
      }
      break;
    default:
      let otherschecked = ([...form.others.elements]
        .filter(input => !input.checked).length == 0) ?? true;
      form.all.checked = otherschecked;
      break;
  }
});
<form name="form01">
  <label><input type="checkbox" name="all" checked>ALL</label>
  <fieldset name="others">
    <label><input type="checkbox" name="other1">Other 1</label>
    <label><input type="checkbox" name="other2">Other 2</label>
    <label><input type="checkbox" name="other3">Other 3</label>
  </fieldset>
</form>

发布评论

评论列表(0)

  1. 暂无评论