0

First of all sorry for the confused question language I will try to explain as much as possible. This is in addition to my previous question on stackoverflow.

I wanted to add/show the values of selected checkbox. I am able to achieve it partially but current issue is if I am selecting one checkbox it's showing 1st value, on two checkboxes it's showing 2nd value 2 times instead of 1st n 2nd, on three checkboxes it's showing 3rd value 3 times instead of 1st, 2nd, 3rd.

You can view here: https://angular-ivy-d2gbad.stackblitz.io/ click on each row to see the form

Code: https://stackblitz.com/edit/angular-ivy-d2gbad?file=src%2Fapp%2Fapp.component.html

enter image description here enter image description here

Kunal Vijan
  • 425
  • 2
  • 9
  • 28

2 Answers2

1

Please update your addSubData function like below -

addSubData(user: any) {
    let i: any;
    i = document.querySelectorAll('input[type="checkbox"]:checked');
    for(var checked of i) {
      const newUser = Object.assign({}, user)
      newUser.dl = checked.value;
      newUser.sub_impact = "Applicable";
      newUser.co_score = "Added";
      this.userObj.assigned_to.push(newUser);
    }  
  }

The problem was you were assigning the values to the same user object. So it was updating the values in array as well. You need to clone your user object using Object.assign.

Also, you were transversing the array by index to fetch the value, but the index k-1 will always return same value in the for loop, as they are constant in the for loop. I have updated the code, so it picks up from the checkbox itself.

Apart from this, there are minor issue, which I think you will get once you solve this problem.

Nikhil Patil
  • 2,480
  • 1
  • 7
  • 20
  • thanks @nikhil-patil can you please help me with the minor issues which you r talking about? maybe I will be able to resolve it sooner before tester raise – Kunal Vijan Dec 24 '20 at 12:53
  • Please re-thinking a more "Angular way". use querySelectorAll(..) for get the checked is not a good aproach – Eliseo Dec 24 '20 at 12:55
  • @KunalVijan, I was referring to issues like - `addSubData`, if called repeatedly, it will not clear previous appended list. I am not sure if you want to clear it or not? – Nikhil Patil Dec 24 '20 at 15:11
  • @Eliseo, You are right. It is better to directly bind the values from HTML instead going through the DOM. As there was a lot of code to go through, I just solved the problem at hand. – Nikhil Patil Dec 24 '20 at 15:17
  • @NikhilPatil can I ask for something else? I wanted to search from existing data n if that matches disabled that checkbox so, that it should'nt let user to add duplicate record. – Kunal Vijan Jan 03 '21 at 20:24
  • @NikhilPatil i am able to compare `this.userObj.assigned_to.forEach((row:any) => { this.dlCategory.findIndex((element,index) => { if (element.value === row.dl) { } }); });` but how do i hide checkbox matching the if case – Kunal Vijan Jan 03 '21 at 21:29
  • @KunalVijan, Can you add your stackblitz? – Nikhil Patil Jan 04 '21 at 06:08
  • @NikhilPatil please refer to this: https://stackblitz.com/edit/angular-ivy-y8d7yt?file=src%2Fapp%2Fapp.component.html once you click on any record, you will get Select DL checkboxes. I want to make sure if data is already added user shouldn't able to add the duplicate dL – Kunal Vijan Jan 04 '21 at 13:18
  • 1
    @KunalVijan, Please check this - https://stackblitz.com/edit/angular-ivy-mwbryf – Nikhil Patil Jan 06 '21 at 06:46
0

Your code it's a bit confussed. Really I can not imagine you want to do so, But..

First. When we has an input, in Angular we use [(ngModel)]="variable". This makes that in our .ts we has the value of the variable an in the .html we show the value of the variable.

So, define four variables in your .ts

gender:string
impact:string
fromDate:any
toDate:any

And your "form" to Apply must be like

Gender:<select [(ngModel)]="gender">
   ...
</select>
Impact:<select [(ngModel)]="impact">
   ...
</select>
<input type="date" [(ngModel)]="fromDate">
<input type="date" [(ngModel)]="toDate">
          class="form-control form-control-sm"
          name="gender"
          ngModel
          [ngModelOptions]="{updateOn: 'submit'}"
        >

Idem when you loop over the categories you can use an auxiliar array

categories:boolean[]=[]

And use

<ul *ngFor="let list of dlCategory">
    <div class="form-check form-check-inline">
        <input type="checkbox" [(ngModel)]="categories[i] 
              name="{{list.name}}">
        <label class="form-check-label" for="">{{list.label}}</label>
     </div>
 </ul>

Well, I tell you in your before post how "convert" an list of checked values in an array with the values checked, this SO

So instead create an array of booleans with true,false, we are going to makes that a property of the "user" becomes an with the values selected

<ul *ngFor="let list of dlCategory">
    <div class="form-check form-check-inline">
        <input #check type="checkbox" 
              [ngModel]="user.categories.indexOf(list.name)>=0" 
              (ngModelChange)="onChange(list.name,check.checked)"
              name="{{list.name}}">
        <label class="form-check-label" for="">{{list.label}}</label>
     </div>
 </ul>

And the onChange becomes like

  onChange(option:string,checked:boolean)
  {
     if (checked && this.user.categories.indexOf(option)<0)
         this.user.categories=[...this.user.categories,option]
         .sort((a,b)=>this.dlCategory.findIndex(x.name==a)>this.dlCategory.findIndex(x.name==b)?1:-1)
    if (!checked)
          this.user.categories=this.user.categories.filter(x=>x!=option)
  }

Finally, when we want to show the data of the categories, we can iterate over dlCategory and show only if the cat is in user.categories

<div *ngFor="cat of dlCategories;let i=index>
  <ng-container *ngIf="user.categories.indexOf(cat.name)>=0">
     {{cat.name}}{{cat.value}}
  <ng-container>
</div>

NOTE: I'm in hurry, is possible that the code has syntax error, but I hope that the answer can help you a few

Eliseo
  • 50,109
  • 4
  • 29
  • 67