0

when user clicks on div(class=unit) i want to target checkbox and mark it as checked/unchecked. also apply class unit-selected if checkbox is checked and remove class unit-selected if checkbox is unchecked.

i tried referring similar questions but nothing worked for me. can anyone help me to complete selectUnit($event)

<div class="unit" (click)="selectUnit($event)" [ngClass]="{'unit-selected'}">
        <input type="checkbox" name="unit" />
        <div class="unit-number">abc</div>
        <div class="unit-desc">Description</div>
      </div>
      
<div class="unit" (click)="selectUnit($event)" [ngClass]="{'unit-selected'}">
        <input type="checkbox" name="unit" />
        <div class="unit-number">xyz</div>
        <div class="unit-desc">Description</div>
      </div>
      
<div class="unit" (click)="selectUnit($event)" [ngClass]="{'unit-selected'}">
        <input type="checkbox" name="unit" />
        <div class="unit-number">mno</div>
        <div class="unit-desc">Description</div>
      </div>

2 Answers 2

2

You can do something simple like giving each div's checkbox a name and pass the variable reference to a function triggered by click event, taking care of the toggle (since you want to toggle by clicking on the div, not just the checkbox itself). You can use the variable name to control ngClass condition and bind it to ngModel to handle the checkmark view.

Sample html:

<div class="unit" 
     (click)="toggleCheckbox('unitABC')"
     [ngClass]="{ 'unit-selected' : unitABC == true }">
   <input type="checkbox" name="unit" [(ngModel)]="unitABC">
   <div class="unit-number" >abc</div>
   <div class="unit-desc">Description</div>
</div>

component.ts:

unitABC = false;
unitXYZ = false;
unitMNO = false;

toggleCheckbox(currCheckbox){
  console.log(currCheckbox);
  switch(currCheckbox){
    case 'unitABC' :
      this.unitABC = !this.unitABC;
      break;
    case 'unitXYZ' :
      this.unitXYZ = !this.unitXYZ;
      break;
    case 'unitMNO' :
      this.unitMNO = !this.unitMNO;
      break;
  }
}

Full demo

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

Comments

1

Although @Nehal's answer is perfectly valid and will work if there are limited 'units', it will not scale well because you have to edit the switch statement every time, which violates the open/closed principle of SOLID.

If you are likely to use multiple, unknown amounts of 'units'. Consider using reactive forms like so (Plunker here):


    @Component({
      selector: 'my-app',
      template: `
      <form [formGroup]="form">
        <div formArrayName="unitArr">
          <div 
            *ngFor="let unit of units; let i = index"
            class="unit"
            (click)="onClick(i)"
            [ngClass]="{'unit-selected': unitArr.controls[i].value}">
              <input type="checkbox" formControlName="{{i}}"/>
              <div class="unit-number">{{ unit.num }}</div>
              <div class="unit-desc">{{ unit.desc }}</div>
          </div>
        </div>
      </form>
      `,
      styles: [`.unit-selected { color: red; }`]
    })
    export class App implements OnInit{
      private units = [
        {num: 1, desc: 'Decription'},
        {num: 2, desc: 'Decription'},
        {num: 3, desc: 'Decription'},
      ]
      private form: Form

      constructor (private fb: FormBuilder) {}

      ngOnInit () {
        this.form = this.fb.group({
          unitArr: this.fb.array(
            this.units.map((unit) => {
              return this.fb.control(false) // Set all initial values to false
            })
          )
        });
      }

      // Shorten for the template
      get unitArr (): FormArray {
        return this.form.get('unitArr') as FormArray;
      };

      onClick(i) {
        const control = this.unitArr.controls[i]
        control.setValue(!control.value) // Toggle checked
      }
    }

3 Comments

thanks can you please help me understand this.from, get unitarr and onclick function step by step .... sorry but i am new to this
this.form references the property defined earlier with private form: Form. I assign it a new [FormGroup](goo.gl/5gBcXY) with the this.fb.group method. get unitArr is so that I can write unitArr instead of this.form.get.... in the template. It is an [ES6 getter](goo.gl/FwnDdt). I assume you know how the onClick is called. It takes the index of the *ngFor loop as a param, gets the correlating control from the form array (unitArr as shortened earlier) and sets its value to the opposite of what it currently is by ['toggling'](goo.gl/i2h2rb) it. [tutorial](goo.gl/gkJb65)
thanks it worked for me. need one more help .... i got select all and unselect all checkbox .... how do i do it

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.