0
checklist = [ '1', '2', '3', '4', '5', '6'...];
user = {[ {"name": "tom", "checkbox": [ '1_A', '3_B' ]}, 
          {"name": "sam", "checkbox": [ '1_C', '3_A' ]} ...



...  
    <tr *ngFor="let checks of checklist ;  let i=index">
        <td *ngFor="let item of user">
            <div class="form-container">
                <input class="check a" [checked]="item.checkbox[i].A" (change)="change(item.checkbox[i], 'a')" [defaultChecked]="item.checkbox[i].A" type="checkbox" value="item.checkbox[i].A"  />
                <input class="check b" [checked]="item.checkbox[i].B" (change)="change(item.checkbox[i], 'b')" [defaultChecked]="item.checkbox[i].B" type="checkbox" value="item.checkbox[i].B"  />
                <input class="check c" [checked]="item.checkbox[i].C" (change)="change(item.checkbox[i], 'c')" [defaultChecked]="item.checkbox[i].C" type="checkbox" value="item.checkbox[i].C"  />
            </div>
        </td>
    </tr>
...

Here is my ts component

    paste(user: User) {
          if (user !== undefined && user.checkbox !== undefined) {
             setTimeout(() => {
              for (let i = 0; i < this.jsonData.length; i++) {
                  if (this.jsonData[i].id === user.id) {
                    this.jsonData[i].checkbox = this.copiedCheckbox;
                  }
              }
             });
          }
    }

    copy(user: User) {
        if (user !== undefined && user.checkbox!== undefined) {
          this.copiedCheckbox = user.checkbox;
        }
    }

      change(current: User, box: string) {
      if (box === 'a') {
        current.a = !current.a;
        current.b = false;
        current.c = false;
      }
      if (box === 'b') {
        current.b = !current.b;
        current.c = false;
        current.a = false;
      }
      if (box === 'c') {
        current.c = !current.c;
        current.b = false;
        current.a = false;
      }
  }

Short explanation: So from the code above I was expecting getting checkbox toggle active only one per column (of the 3 checkboxes). It works fine until I started copy / paste items the copy and paste works fine but after paste I started to see mirror results. If i clicked on the checkbox instead of the current checkbox changed it changes both copied checkbox and the checkbox that is pasted. Why is this happening?

 ---Before copy
               (tom)                         |               (sam)                    
 Type      A           B          C          |        A           B          C                     
  1    [CheckBox[x]| CheckBox[] | CheckBox[] |  [CheckBox[] | CheckBox[] | CheckBox[x]
  2    [CheckBox[] | CheckBox[] | CheckBox[] |  [CheckBox[] | CheckBox[] | CheckBox[]
  3    [CheckBox[] | CheckBox[x]| CheckBox[] |  [CheckBox[x]| CheckBox[] | CheckBox[]
  ...
 ---After copy---
                (tom)                         |              (sam)              
 Type      A           B          C           |        A           B          C                     
  1    [CheckBox[x]| CheckBox[] | CheckBox[]  |  [CheckBox[x]| CheckBox[] | CheckBox[]
  2    [CheckBox[] | CheckBox[]  | CheckBox[] |  [CheckBox[] | CheckBox[]  | CheckBox[]
  3    [CheckBox[] | CheckBox[x] | CheckBox[] |  [CheckBox[] | CheckBox[x] | CheckBox[]

 ---Select 1_B from sam after copy, the checkbox is duplicated to tom's table ---
                (tom)                         |              (sam)              
 Type      A           B          C           |        A           B          C                     
  1    [CheckBox[] | CheckBox[x] | CheckBox[] |  [CheckBox[] | CheckBox[x]| CheckBox[]
  2    [CheckBox[] | CheckBox[]  | CheckBox[] |  [CheckBox[] | CheckBox[]  | CheckBox[]
  3    [CheckBox[] | CheckBox[x] | CheckBox[] |  [CheckBox[] | CheckBox[x] | CheckBox[]  
logger
  • 1,983
  • 5
  • 31
  • 57
  • 1
    Why not use radio buttons if you only want 1 active at a time? Also, your `box === 'C'` logic if just setting `current.c`, nothing else – user184994 Oct 18 '18 at 20:08
  • I agree with @user184994, this is easily solved by using `radio` buttons instead of checkboxes. – Zze Oct 18 '18 at 20:50

2 Answers2

0

why not use other codification? I think in some like

checklist = [ '1', '2', '3', '4', '5', '6']
//see that user is an array
user = [ {"name": "tom", "checkbox": [0,2,null], 
         {"name": "sam", "checkbox": [2,null,1]}
         ...
       ]

<tr *ngFor="let checks of checklist ;  let i=index">
        <td *ngFor="let item of user">
            <div class="form-container">
                <input type="checkbox" class="check a" [checked]="item.checkbox[0]==i"
                      (change)="item.checkbox[0]=item.checkbox[0]==i?null:i" />
                <input type="checkbox" class="check b" [checked]="item.checkbox[1]==i"
                      (change)="item.checkbox[1]=item.checkbox[1]==i?null:i" />
                <input type="checkbox" class="check c" [checked]="item.checkbox[2]==i"
                      (change)="item.checkbox[2]=item.checkbox[2]==i?null:i" />
            </div>
        </td>
    </tr>
    <div>
    <!---just for check--->
    {{user|json}}
    </div>

See that you needn't write any code to change the values Then a copy can be like

//You create a variable called
userCopy:User
copy(user:User)
{
    this.userCopy=user;
}
paste(user:User)  //The argument in to which user you copy "this.userCopy"
{
    if (this.userCopy)
    {
        user.checkbox[0]=this.userCopy.checkbox[0];
        user.checkbox[1]=this.userCopy.checkbox[1];
        user.checkbox[2]=this.userCopy.checkbox[2];
    }
 }
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • thanks but this does not solve the problem. when copy / paste it still reference to both data. (previous and the current). The solution is the same with the original. Just that somehow the reference is being made to user (arraylist) so in angular it update both even if you change the current. – logger Oct 19 '18 at 16:27
0

I finally found the problem.

When I loop through the table the array is referenced through copy. In order to dereference an array I need to make a copy of the original array and then use that copied array to paste my object. Therefore two entity will not be connected.

      setTimeout(() => {
        let checkbox: Checkboxes[] = this.copiedCheckbox.map(x => Object.assign({}, x));
        this.copiedCheckbox= checkbox; });
    }

Deep copy an array in Angular 2 + TypeScript

logger
  • 1,983
  • 5
  • 31
  • 57