1

I can't get my checkboxes to work, they appear and I can click on the box but they don't get checked and my onSelect function isn't getting called either. I'm new to angular so this is probably something simple that I have missed.

Heres my html:

<div *ngIf="pager.index < quiz?.questions.length">
  <h5 class="flow-text"><span [innerHTML]="quiz?.questions[pager.index].text"></span></h5>
  <br>
  <div class="row text-left">
    <div class="col s12 m12" *ngFor="let answer of quiz?.questions[pager.index].answers">
      <div class="answer">
        <input type="checkbox" [checked]="answer.selected" (change)="onSelect(answer);"/><label class="black-text flow-text"> {{answer.text}} </label>
      </div>
    </div>
  </div>
  <footer class="row">
    <div class="col s6 m6"></div>
    <div class="col s6 m6">
      <div *ngIf="pager.index < quiz?.questions.length - 1">
        <button id="nextButton" class="btn-flat black-text right flow-text" (click)="goTo(pager.index + 1);">Next</button>
      </div>
      <div *ngIf="pager.index == quiz?.questions.length - 1">
        <button id="nextButton" class="btn-flat black-text right flow-text" (click)="goTo(pager.index + 1);">Finish</button>
      </div>
    </div>
  </footer>
</div>

<div *ngIf="pager.index == quiz?.questions.length">
  {{ selections }}
</div>

here is the component.ts

import { Component, OnInit, EventEmitter } from '@angular/core';
import { QuizService } from '../services/quiz.service';
import { Answer, Question, Quiz } from '../models/index';
import {MaterializeAction} from "angular2-materialize";

@Component({
  selector: 'app-quiz',
  templateUrl: './quiz.component.html',
  styleUrls: ['./quiz.component.sass'],
  providers: [QuizService]
})
export class QuizComponent implements OnInit {

  quiz: Quiz;
  pager = {
    index: 0,
    size: 1,
    count: 1
  };
  selections: [string]

  constructor(private quizService: QuizService) { }

  ngOnInit() {
    this.loadQuiz()
  }

  loadQuiz() {

    this.quizService.get().subscribe(res => {
      this.quiz = new Quiz(res);
      this.pager.count = this.quiz.questions.length;
    });
  }

  goTo(index: number) {
   if (index >= 0 ) {
     this.pager.index = index;
   }
 }

 onSelect(answer: Answer) {
   if (answer.selected = true) {
     this.selections.splice(this.selections.indexOf(answer.text), 1);
   } else {
     this.selections.push(answer.text);
   }
   answer.selected = !answer.selected
 }
}

Any help would be great as ive tried everything ive seen but to no prevail. Thanks

Update: added app.nodule.ts

import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { NgModule } from '@angular/core';
import { AppRoutingModule } from './app-routing.module';
import { MaterializeModule } from 'angular2-materialize';

import { Angular2TokenService } from 'angular2-token';
import {AuthService} from "./services/auth.service";
import {AuthGuard} from "./guards/auth.guard";

import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { ToolbarComponent } from './toolbar/toolbar.component';
import { AuthDialogComponent } from './auth-dialog/auth-dialog.component';
import { LoginFormComponent } from './login-form/login-form.component';
import { RegisterFormComponent } from './register-form/register-form.component';
import { AboutComponent } from './about/about.component';
import { QuizComponent } from './quiz/quiz.component';
import { FooterComponent } from './footer/footer.component';

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    ToolbarComponent,
    AuthDialogComponent,
    LoginFormComponent,
    RegisterFormComponent,
    AboutComponent,
    QuizComponent,
    FooterComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpModule,
    AppRoutingModule,
    MaterializeModule
    ],
  providers: [Angular2TokenService, AuthService, AuthGuard],
  bootstrap: [AppComponent]
})
export class AppModule { }
Wazza
  • 1,725
  • 2
  • 17
  • 49

2 Answers2

2

According to this issue: https://github.com/Dogfalo/materialize/issues/1376 The asker had noticed this:

I've noticed that checkboxes only appear if they are coded like this: <input type="checkbox" id="checkboxid"><label for="checkboxid">Yes?</label>

Tried your code, so the following seems to work just fine. We need to add an id for your checkboxes, and then also use for in the label. Since you are iterating the checkboxes, we need to set dynamic id to separate the checkboxes. I used the index for this.

<div class="col s12 m12" 
     *ngFor="let answer of quiz?.questions[pager.index].answers; let i = index">
  <div class="answer">
    <input type="checkbox" [id]="i" [ngModel]="answer.selected" 
      (ngModelChange)="onSelect(answer)"/>
    <label [for]="i" class="black-text flow-text"> {{answer.text}} </label>
  </div>
</div>
AT82
  • 71,416
  • 24
  • 140
  • 167
1

Use the [ngModel] binding combined with (ngModelChange) so that whenever your checkbox value changes, the ngModelChange will call the onSelect function specified in the attribute. Whenever you change the selected flag of a particular answer object the [ngModel] binding will reflect it over on the UI.

<input type="checkbox" [ngModel]="answer.selected" (ngModelChange)="onSelect(answer)"/>

You can even skip the answer.selected = !answer.selected part from your onSelect function if you use the two way binding style [(ngModel)]="answer.selected"


#Update

Since ngModel directive resides in FormsModule you have to import that module into your main AppModule imports metadata. You could refer Angular 2 two way binding using ngModel is not working

Pankaj Parkar
  • 134,766
  • 23
  • 234
  • 299