Anna
Anna

Reputation: 1689

Typescript:Iterate over list of checkbox

I work on angular 4, I have list of checkbox which on page load will be unchecked. There is a delete button which will be enabled when any checkbox is checked.

hero.component.html

<div *ngFor="let hero of heros">
    <span>
        <input type='checkbox' name='drama' (click)='selectedHero()' />
    </span>
    <span>hero.name</span>
</div>
<button [class.disabled]='!inEditMode'>Delete</button>

hero.component.ts

private inEditMode = false;

selectedHero(){
    var elements = document.getElementsByName("drama");
    for (let i = 0; i < elements.length; i++) {
        if (elements[i].type == "checkbox") {
            if (elements[i].checked) {
                this.inEditMode = true;
            }
            else {
                this.inEditMode = false;
            }
        }
    }
}

I am getting error in .type and .checked.

Error is

Property 'type' doesnot exist on type 'HTMLElement
Property 'checked' doesnot exist on type 'HTMLElement.

How can I iterate over the checkboxes to see if any on them is checked, and if checked enable the button. And if not checked disabled the button? Please guide

Upvotes: 1

Views: 6311

Answers (7)

Parth Savadiya
Parth Savadiya

Reputation: 1211

Add one extra property in Hero model like, IsSelected and bind it with every check-boxes

selectedHero() {

  var data = this.heroes.find((obj: Hero) => obj.IsSelected === true);
  if (data) {
    this.inEditMode = true;
  } else {
    this.inEditMode = false;
  }

}
<div *ngFor="let hero of heros">
  <span>
       <input type='checkbox' value="{{hero.IsSelected}}" [(ngModel)]="hero.IsSelected" name='IsSelected' (change)='selectedHero()'/> />
    </span>
  <span>hero.name</span>
</div>
<button [class.disabled]='!inEditMode'>Delete</button>

stackblitz working demo

Upvotes: 0

Sanoj_V
Sanoj_V

Reputation: 2986

Your code is working fine, but your for loop in typescript sometime works and sometime fails because of for loop.

in your html : <button [disabled]='!inEditMode'>Delete</button>

In your typescript:

selectedHero() {
   var elements = (<HTMLInputElement[]><any>document.getElementsByName("drama"));
   for (let i = 0; i < elements.length; i++) {
   if (elements[i].type == "checkbox") {
      if (elements[i].checked) {
         console.log("Checked", elements[i].checked);
         this.inEditMode = true;
         break;                      //<== Add this line in your for loop
       }
       else {
         console.log("Unchecked", elements[i].checked);
         this.inEditMode = false;
       }
     }
   }
 }

When for loop starts until all elements has to be check you have to break the for loop when atleast one checkbox is checked.

Here is working example: Enable Button on mutiple check box selection

Hope this will works for you!!!

Upvotes: 1

Joe Belladonna
Joe Belladonna

Reputation: 1339

When working with checkboxes, I create an array of checkboxes and in that array, I keep all (in your case id of heroes) checked checkboxes. If array is empty, you disable your button, and if array has at least one member, you enable button. Also when you want to check which checkboxes are checked, you simply itterate through an array of checkboxes.

checkarray: any = [];

To check is checkbox checked:

isChecked(item: any): boolean {
        if (this.checkarray.find(x => x.IDHero == item.IDHero)) {
            return true;
        }
        else {
            return false;
        }
    }

To delete member from array:

deletefromArray(array: any, element: any, id: string) {
        let temp: any = [];
        for (let i = 0; i < array.length; i++) {
            temp.push(array[i]);
        }
        array.splice(0);
        for (let i = 0; i < temp.length; i++) {
            if (temp[i][id] != element[id]) {
                array.push(temp[i]);
            }
        }
        return array;
    }

To add checked checkboxes to array:

checkbox(item: IDK, event) {
    if (event.ctrlKey) {
        if (this.checkarray.find(x => x.IDHero == item.IDHero)) {
            this.deleteFromArray(this.checkarray, item, 'IDHero');

            let temp: any = [];
            for (let i = 0; i < this.checkarray.length; i++) {
                temp.push(this.checkarray[i]);
            }
            this.checkarray.splice(0);
            for (let i = 0; i < temp.length; i++) {
                if (temp[i].IDHero != item.IDHero) {
                    this.checkarray.push(temp[i]);
                }
            }
        }
        else {          
            this.checkarray.push(item);
        }
    }
    else {      
        if (!this.checkarray.find(x => x.IDHero == item.IDHero)) {
            this.checkarray.splice(0);
            this.checkarray.push(item);
        } else {
            this.checkarray.splice(0);
        }

    }
}

I use CTRL for multy check.

HTML would be:

<div *ngFor="let hero of heros" (click)="checkbox(hero,$event)>
<span><input type='checkbox' name='drama' [checked]="isChecked(hero)"/></span>
<span>hero.name</span>

<button [disabled]='checkarray.length == 0'>Delete</button>

Upvotes: 0

manish kumar
manish kumar

Reputation: 4692

Your approach is not wrong.

Try typecasting it with

var elements = (<HTMLInputElement[]><any>document.getElementsByName('drama'));

alternative try using ngModel, it makes your life easier.

<input [(ngModel)]="checkBox.option1" type="checkbox" data-toggle="toggle">Option
<input [(ngModel)]="checkBox.option2" type="checkbox" data-toggle="toggle">Option

<button [disabled]='checkBox.option1 || checkBox.option2'>Delete</button>

app.component.ts

checkBox:any{};
constructor(){
   checkBox={
       option1:false,
       option2:false
   };
}

optionChecked becomes true when checked thus disabling the button

Upvotes: 0

Avinash
Avinash

Reputation: 1243

your elements[i] is a HTMLElement, typecast it to HTMLInputElement.

Checked property will be there for HTMLInputElement in typescript.

Below should work.

for(let i=0;i<elements.length;i++){
if((elements[i] as HTMLInputElement).type == "checkbox"){
if((elements[i] as HTMLInputElement).checked){
  this.inEditMode = true;
}

Upvotes: 0

Padmapriya Vishnuvardhan
Padmapriya Vishnuvardhan

Reputation: 2166

Try with .

The problem is that typescript is typesafe. The elements[i] holds the type HTMLElement which does not contain a type property. The subtype HTMLInputElement does however contain the type property.

selectedHero(){
var elements = document.getElementsByName("drama");
for(let i=0;i<elements.length;i++){
var element = <HTMLInputElement>elements[i];
if(element.type == "checkbox"){
if(element.checked){
this.inEditMode = true;
}
else{
this.inEditMode = false;
}
}
}
}

Upvotes: 0

Mohd Tabish Baig
Mohd Tabish Baig

Reputation: 452

You have to cast the result of getElementsByName("drama"); like this:

var elements = (<HTMLInputElement[]><any>document.getElementsByName('drama'));

as document.getElementsByName() returns the type HTMLElement

Upvotes: 0

Related Questions