2

I have a table with input fields which I am populating with model values, I want to apply readonly/disable to these populated fields. when I click on add row, I add empty rows to the table. The empty rows added to the table must be editable. I am unable to find a logic which applies readOnly/disable only to already populated table cells.

HTML

<table>
<thead>
    <th> Name </th>
    <th> Age </th>
    <th> Url </th>
    <th> Gender </th>
    <th> Image </th>
    <th> Keywords </th>
</thead>
<tbody>
    <tr *ngFor="let data of userList; let $index = index">
        <td> <input class="form-control" type="text" id="userListName"[(ngModel)]="userList[$index].name"
            name="userListName{{$index}}" [readonly]="userList[$index].name.length"/></td>
        <td> <input class="form-control" type="text" id="userListAge" [(ngModel)]="userList[$index].age"
            name="userListAge{{$index}}" readonly/></td>
        <td><input class="form-control" type="text" id="userListUrl" [(ngModel)]="userList[$index].url" name="userListUrl{{$index}}" readonly/></td>
        <td> <input class="form-control" type="text" id="userListGender" [(ngModel)]="userList[$index].gender"
            name="userListGender{{$index}}" readonly/></td>

        <td> <input class="form-control" type="text" id="userListImage" [(ngModel)]="userList[$index].image"
            name="userListImage{{$index}}"  readonly/>
        </td>
        <td> <input class="form-control" type="text" id="userListKeywords" [(ngModel)]="userList[$index].keywords"
            name="userListKeywords{{$index}}" readonly/></td>
      </tr>
     </tbody>

 <button (click) ="addRow()"> Add Row </button>
 </table>

Component:

 import { Component, OnInit } from '@angular/core';

 @Component({
 selector: 'my-app',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
 })
 export class AppComponent {

 userList: userModel[] = [];

jsonUser = [
{
name: 'abc',
age: 17,
url: "a.com",
gender: "F",
image: "i-ocion.png",
keywords: "blah"
}, 
{
name: 'cde',
age: 18,
url: "cde.com",
gender: "F",
image: "i-oddcion.png",
keywords: "blahhh"
}, 
{
name: 'efg',
age: 19,
url: "efg.com",
gender: "F",
image: "i-ocfffion.png",
keywords: "blahhhhhhh"
}
]
ngOnInit() {
this.userList = this.jsonUser;
}

addRow() {
this.userList.push(new userModel);
}
}

export class userModel {
name: string;
age: number;
url: any;
gender: string;
image: string;
keywords: string;
}

Demo

4 Answers 4

5

You could declare a variable that identifies the size of the array that comes from backend (like initialArraySize), then when you add a new row you verify if the index of that row is greater than the initial array size, if its true, you make it editable..

<tbody>
<tr *ngFor="let data of userList; let index = index">
    <td> <input class="form-control" type="text" id="userListName" [(ngModel)]="userList[index].name"
        name="userListName{{index}}" [readonly]="index >== initialArraySize"/></td>
</tr>
</tbody>
Sign up to request clarification or add additional context in comments.

Comments

0

The new empty row has an index of $index === userList - 1 since it is the last item of that collection. You can use that condition and apply any attribute you want.

1 Comment

I believe if I add two or more empty rows in the table, this condition will not work.
0
<td>
<input
    class="form-control"
    type="text"
    id="userListKeywords"
    [(ngModel)]="userList[$index].keywords"
    name="userListKeywords{{$index}}"
    [attr.disabled]="true" readonly/>
</td>

[attr.disabled]="true" will make the input non-editable, you can modify your code to make this attribute configurable.


add a property inside the jsonUser object

jsonUser = [
{
name: 'abc',
age: 17,
url: "a.com",
gender: "F",
image: "i-ocion.png",
keywords: "blah",
readonly: true
}, 
]

and then

<td>
<input
    class="form-control"
    type="text"
    id="userListKeywords"
    [(ngModel)]="userList[$index].keywords"
    name="userListKeywords{{$index}}"
    [attr.disabled]="userList[$index].readonly" readonly/>
</td>

[attr.disabled]="userList[$index].readonly"

7 Comments

I can make the input non-editable. my question is how to make few inputs editable when they are in a loop.
I'm looking for a UI approach. I receive jsonUser object from backend, I cannot make changes to API
by default in the start you can initilize your jsonUser item true and later on you keep on updating the readonly propery as you like
after receiving the response, modify the it userJson.forEach(item => item.readonly = false); And keep updating the userJson depending on the business logic
In this case, when new row is added, item.readonly will apply as false to new row, since it is in *ngFor.
|
0

Care fully see the following code:

    <td> <input class="form-control" type="text" id="userListImage" [(ngModel)]="userList[$index].image"
        name="userListImage{{$index}}"  [disabled]="data.readonly"/>
    </td>
    <td> <input class="form-control" type="text" id="userListKeywords" [(ngModel)]="userList[$index].keywords"
        name="userListKeywords{{$index}}" [disabled]="data.readonly"/></td>
  </tr>
 </tbody>

and in array in each index there must be a boolean named as readonly and when it is true then the input field will be disabled(uneditable) otherwise it will be enabled,

jsonUser = [
{
name: 'abc',
age: 17,
url: "a.com",
gender: "F",
image: "i-ocion.png",
keywords: "blah",
readonly:true
}, 
{
name: 'cde',
age: 18,
url: "cde.com",
gender: "F",
image: "i-oddcion.png",
keywords: "blahhh",
readonly:false
}, 
{
name: 'efg',
age: 19,
url: "efg.com",
gender: "F",
image: "i-ocfffion.png",
keywords: "blahhhhhhh",
readonly:true
}
]

the index 1 and 3 will be disabled

3 Comments

Like I mentioned, I don't want any changes to the array. I receive the JSON from backend, I cannot change API. I'm looking for UI approach
do you know then which index will be disabled how you gonna checkout that which input should be disabled and which enabled
Please check the accepted answer. That's how I resolved my issue.

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.