1

I have an array that I am looping over to create a table of records. Now, for each row in the table, I have provided an 'EDIT' button and a Cancel button. Clicking on the edit button will show textboxes populated with the actual values and will give the user an option to save. Clicking the cacncel button will collapse the editable row and will display the actual table row. Now, I am using the following arrangement to facilitate this:

 <tr *ngFor="let item of mf.data; let i = index" [class.active]="i == selectedRow">
     <td>
         <span [hidden]="edit && i==selectedRow" [innerText]="item.firstName"></span>
         <span [hidden]="i!==selectedRow"><input type="text" #fn id="fn" name="fn" [value]="item.firstName"/></span>
     </td>

Now, the problem : 1. I click the EDIT button and make some modifications to the textbox value - 2. Then I click on the cancel button. 3. I again click on the EDIT button. Now, I was hoping to see the actual data in the textbox. Instead I see the modified value (per step 2).

I want that the value of textbox should always refresh to the value in the everytime I click on EDIT button.

EDIT: I've seen that if instead of using [hidden], I use

<span *ngIf="i==selectedRow"><input type="text" #fn id="fn" name="fn" [value]="item.firstName"/></span>

then I am able to get the textbox value reset, but then I am unable to access the textbox value in the Typescript file. I access the values file like this:

<img (click)="updateContact(fn.value) .../>

EDIT: Updated with the complete table:

<tbody>
                        <tr *ngFor="let item of mf.data; let i = index" [class.active]="i == selectedRow">
                            <tr><td>ass</td><tr>
                            <td>
                                <span *ngIf="i !== selectedRow" [innerText]="item.firstName"></span>
                                <span *ngIf="edit && i == selectedRow">
                                    <input (blur)="updateEditableValues(fn.value, undefined)" type="text" #fn [value]="item.firstName"/>                                     
                                </span>
                                <!--<input type="hidden" #firstName [(ngModel)]="firstNameVal" />-->
                            </td>
                            <td>
                                <span *ngIf="i !== selectedRow" [innerText]="item.lastName"></span>
                                <span *ngIf="edit && i == selectedRow" ><input (blur)="updateEditableValues(undefined, ln.value)" type="text" #ln value="{{item.lastName}}"/></span>
                                <!--<input type="hidden" #lastName [(ngModel)]="lastNameVal" />-->
                            </td>
                            <td>
                                {{item.email}}
                                <span [hidden]="true"><input  #email type="text" value="{{item.email}}"/></span>
                            </td>
                            <td>{{item.contactStatus}}</td>
                            <td>
                                <!--<a [hidden]="edit && i==selectedRow" href="javascript:void(0);" (click)="setClickedRow(i)">EDIT</a>-->
                                <img height="20" width="20" *ngIf="i !== selectedRow" src="https://cdn2.iconfinder.com/data/icons/circle-icons-1/64/pencil-64.png"
                                    (click)="setClickedRow(i)" />
                                <div *ngIf="edit && i == selectedRow" >
                                    <img (click)="updateContact(i, fn.value, ln.value)" height="20" width="20" src="https://cdn4.iconfinder.com/data/icons/gnome-desktop-icons-png/PNG/48/Dialog-Apply-48.png"
                                    />
                                    <img (click)="closeEdit()" height="20" width="20" src="https://cdn4.iconfinder.com/data/icons/common-toolbar/36/Cancel-48.png"
                                    />
                                </div>
                            </td>

                        </tr>
                    </tbody>
  • Update 2

    updateContact(rowIndex, firstName, lastName, email){
    
          alert(firstName)      
          alert(lastName)      
      this.data.forEach((item, index) => {
        if (item.email === email) {
          this.data[index].firstName = firstName;
          this.data[index].lastName = lastName;
          this.edit = false;
          this.selectedRow = -1;  
          return false;  
        } 
    
    });
    
    }
    
va1b4av
  • 431
  • 9
  • 26

1 Answers1

2

I arranged your code a little.

    <tr *ngFor="let item of mf.data; let i = index" [class.active]="i === selectedRow">
         <td>
             <span *ngIf="!edit"> {{item.firstName}}> </span>
             <span *ngIf="edit && i===selectedRow">
                 <input type="text" #fn [value]="item.firstName"/>
                <button (click)="update(item.id, fn.value)"/> Save</button>
             </span>
         </td>
     </tr>
...

and in update() you actually update the array value. You would need ids in mf.data to identify which row it is:

    update(id, value)
    {
      this.edit=false;
      //something like this
      this.md.data[id].firstName=value;
    }

UPDATE: with your updated code, it should be:

<tbody>
           <tr *ngFor="let item of mf.data; let i = index" [class.active]="i == selectedRow">
               <td>
                   <span *ngIf="i !== selectedRow" [innerText]="item.firstName"></span>
                   <span *ngIf="edit && i == selectedRow">
                       <input (blur)="updateEditableValues(fn.value, true)" type="text" #fn [value]="item.firstName" />
                   </span>
                   <!--<input type="hidden" #firstName [(ngModel)]="firstNameVal" />-->
               </td>
               <td>
                   <span *ngIf="i !== selectedRow" [innerText]="item.lastName"></span>
                   <span *ngIf="edit && i == selectedRow">
                       <input (blur)="updateEditableValues(ln.value, false)" type="text" #ln [value]="item.lastName" />
                   </span>
                   <!--<input type="hidden" #lastName [(ngModel)]="lastNameVal" />-->
               </td>
               <td>
                   {{item.email}}
                   <span [hidden]="true">
                       <input #email type="text" [value]="item.email" />
                   </span>
               </td>
               <td>{{item.contactStatus}}</td>
               <td>
                   <!--<a [hidden]="edit && i==selectedRow" href="javascript:void(0);" (click)="setClickedRow(i)">EDIT</a>-->
                   <img height="20" width="20" *ngIf="i !== selectedRow" src="https://cdn2.iconfinder.com/data/icons/circle-icons-1/64/pencil-64.png"
                       (click)="setClickedRow(i)" />
                   <div *ngIf="edit && i == selectedRow">
                       <img (click)="updateContact(i, fn.value, ln.value)" height="20" width="20"
   src="https://cdn4.iconfinder.com/data/icons/gnome-desktop-icons-png/PNG/48/Dialog-Apply-48.png"
                       />
                       <img (click)="closeEdit()" height="20" width="20" src="https://cdn4.iconfinder.com/data/icons/common-toolbar/36/Cancel-48.png"
                       />
                   </div>
               </td>

           </tr>
   </tbody>

I corrected updateEditableValues() that will take boolean in the second argument and if it's true it will be firstnname and false lastname will be updated. you need to correct it. It's not important for the question, but more elegant way

Vega
  • 27,856
  • 27
  • 95
  • 103
  • Yes, inside updateContact, fn is inaccessible or undefined. – va1b4av Aug 13 '17 at 15:37
  • I do not use a @Viewchild. I also updated the original post with code for updateContact() – va1b4av Aug 13 '17 at 15:41
  • No..Its in accessible. The moment I remove the *ngIf conditions from the , I can access fn. – va1b4av Aug 13 '17 at 15:44
  • I am probably understanding now what's going on or at least partially. ngIf removes the element from the DOM. So it could be inaccessible. but I don't see why because the button and the input have the same ngif condition, so both are present. Could you try re-replace ngIf by [hidden] as it doesn't remove from the DOM – Vega Aug 13 '17 at 15:49
  • Well actually, I have tried that and with [hidden] it works. However, with hidden, I seem to run into a different set of issues so I thought of going in with *ngIf – va1b4av Aug 13 '17 at 15:52
  • As a quick fix, what you can do is to keep an array of values, on (keyup.enter) on each input update the array with the input value (like fn.value, ln.value) and on save button lookup for that array values – Vega Aug 13 '17 at 15:57
  • Yes, I tries that but in that case I would run into issues when the user does not click/hit enter on the textfields. This is exactly what I was trying to achieve with (blur)="updateEditableValues(fn.value, undefined)" and tried to set the values in a hidden field. But the problem in this case was if the user hots the update button without accessing the textfield, I get incorrect values. – va1b4av Aug 13 '17 at 16:00
  • put in a flew strategical places {{fn.value}}, like just after the input #fn, before the button and an other one somewhere between s. Is it undefined everywhere? – Vega Aug 13 '17 at 16:04
  • the only place fn.value is accessible is inside the *NgIf Condition block – va1b4av Aug 13 '17 at 16:18
  • https://stackoverflow.com/questions/44028873/access-local-variable-within-ngif, or https://stackoverflow.com/questions/36642487/angular2-ngif-and-local-template-variables and there are many others. I hope you can find something to make it work :) – Vega Aug 13 '17 at 16:24
  • Finally after hours and hours of research, I was able to get it done (I believe). I received so many wonderful pointers from you. The last links you sent across really saved the day for me. Really appreciate the time and effort you spent working with me today. Thank you so much. – va1b4av Aug 13 '17 at 17:56
  • 1
    Bravo! I am so glad that you got it done and very pleased that I was able to help you! I really enjoyed it and you are very welcome :) – Vega Aug 13 '17 at 18:22