2

I have a component that receives an object of employee records and displays them in a table. Each record has a checkbox that allows you to "select" the employee to be included in the next process.

<tr *ngFor="let i of importResults" >
 <td>
  <input type="checkbox"
         value="{{ i.QID }}"
         attr.data-employeename="{{ i.PreferredName }} {{ i.LastName }}"
         [checked]="isSelected" />
  </td>
  <td>{{ i.PreferredName }} {{ i.LastName }}</td>
</tr>

In this component, I created an array selectedEmployees = []; and my goal is that when I click a checkbox, its value is pushed to the array, as well as when I uncheck it, the value is removed from the array.

I tried using ngModel for 2 way binding but because this data doesn't have an initial checked value in the object, I wasn't able to get that working correctly.

Is ngModel the best way to achieve this? Perhaps I was just going about it the wrong way.

I tried following this question but typescript threw an error saying .entries was not valid. It may have been for an older version of angular?

3
  • What about just building the list of checked employees when moving on to the next process? It's going to be a lot easier. Commented Jul 13, 2017 at 15:46
  • @Steveadoo I suppose that would be an option. Still trying to figure out the whole communication between components aspect so getting those values in the next process (a sibling component) will be what I will need to figure out. Thanks for the suggestion. Commented Jul 13, 2017 at 15:50
  • You can store the isSelected property in the "i" variable. Then just do a importResults.filter(i => i.isSelected) to only select the selected employees. You can store that result on a field in your component and pass that field into the sibling component. You will need to use ngModel for that. Commented Jul 13, 2017 at 15:57

1 Answer 1

3

You can add a click event to the checkbox and pass it to a function to handle add or remove.

html:

<div *ngFor="let i of importResults" >
 <div>
  <input type="checkbox"
         value="{{ i.QID }}"
         (click)="change(i)"/>
   <span>{{ i.PreferredName }} {{ i.LastName }}</span>
  </div>
</div>

<p> Selected Employee: {{selectedEmployees | json}} </p>

component.ts:

export class SelectFormExample {
  selectedEmployees = [];

  showSiblingComp = false;

  importResults = [
    {QID: "1", PreferredName: 'Steak', LastName: "Pizza"},
    {QID: "2", PreferredName: 'Cheese', LastName: "Burger"},
    {QID: "3", PreferredName: 'Chicken', LastName: "Panini"}
  ];

  constructor(private service: SharedService){

  }

  change(obj){

    let updateItem = this.selectedEmployees.find(this.findIndexToUpdate, obj.QID));

    let index = this.selectedEmployees.indexOf(updateItem);

    console.log(index);

    if(index > -1){
      this.selectedEmployees.splice(index, 1);
    }
    else{
      this.selectedEmployees.push(obj);
    }

    this.service.setList(this.selectedEmployees);

  }

  findIndexToUpdate(obj) { 
        return obj.QID === this;
  }
}

demo

I have extended the demo to include sharing the selectedEmployees with a sibling component via shared service.

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

6 Comments

This gave me some typescript errors saying that .checked isn't a property.
Probably, can't find the element by id. Just ensure id for input field is set to id="checkbox{{ i.QID }}" or if you have a different id, that's what being used in the function. It's working in the demo :S.
Weird, this is a pre-compile error so it has not even checked the HTML template yet. I have it added in there correctly though. Property 'checked' does not exist on type 'HTMLElement'.
I have updated the answer, not using id or getElementById anymore. See, if that helps :)
This seems to be working perfectly! One small ask.. I also have a "check all" box in my table header. How could include this so that it trigger this event on all boxes? <th><input type="checkbox" name="checkAll" (change)="isSelected = !isSelected"></th>
|

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.