I am using an ng-repeat to generate some data (username, login, role and actions). Each dropdown (role) has the same list of options.
Expected output :
Each row of data can have a different selected option (like the image) and a service call is made whenever a change is made to save the change.
My problem is that I can't choose different options for each row. Because they are all bound to the same ng-model, they all detect the change and all change to the new option.
<table>
<thead>
<tr>
<th>Name</th>
<th>Username</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="participant in model.participantData">
<td>{{participant.DisplayName}}</td>
<td>{{participant.UserLogin}}</td>
<td>
<label for="{{participant.ParticipantID}}" class="sr-only">
Choose a role
</label>
<select id="{{participant.ParticipantID}}" data-ng-options="role.RoleID as role.RoleName for role in model.rolesData" data-ng-change="roleChanged(participant)" data-ng-model="model.chosenRole">
</select>
</td>
<td>
<span aria-hidden="true" class="fa fa-minus-circle clickable"</span>
<span class="sr-only">Delete group member</span>
</td>
</tr>
</tbody>
</table>
Instead of giving same model , Give them model by ng-repeat instance
Like this
data-ng-model="participant.chosenRole"
Select will be
<select
id="{{participant.ParticipantID}}"
data-ng-options="role.RoleID as role.RoleName for role in model.rolesData"
data-ng-change="roleChanged(participant)"
data-ng-model="participant.chosenRole">
</select>
You can get selected value of each row from model.participantData
Related
I have two div elements and my requirement is how do I pass the id of present in second div element and is getting executed in the loop to the first div element button. Here is the sample code :
<div style="float: right;">
<button type="button" (click)="delete(skillGroupAndTypeRow.id);"></button>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>Select</th>
<th>Skill Group Names</th>
<th>Skill Type</th>
</tr>
</thead>
<tbody>
<tr #skillGroupAndTypeRow *ngFor="let group of groups; let i=index;" id="skillRow-{{i}}">
<td>
<input type="checkbox" id="group-{{i}}" >
</td>
<td>{{group.name}}</td>
<td>{{group.type}}</td>
</tr>
</tbody>
</table>
So how do I pass the Id of tag into the delete button present in above div.
With this approach there is a error saying cannot read id of undefined.
What would be the best way to dynamically add an HTML element, such as another column onto a basic HTML table?
I want to have a button below the table, and if the user were to click the button, the event would add the same amount of rows already in the table and add another column. I would want to support about 5 extra columns being added to the table.
Here's my HTML table as of right now:
<table>
<thead>
<tr>
<th id="row-tag"></th>
<th id="option-column">Option 1</th>
</tr>
</thead>
<tbody>
<tr>
<td id="row-tag">P</td>
<td id="option-column">{{ p }}</td>
</tr>
<tr id="row-tag">
<td>
<app-a-p (saveButtonClick)="toggleAP($event)"
[modModalValues]="modModalValues">
</app-a-p>
</td>
<td id="option-column">
<div class="input-group input-group-sm">
$<input
*ngIf="toggleAP==true"
type="text"
name="aP"
size="10"
disabled
value=""
/>
<input
*ngIf="toggleAP==false"
type="text"
name="aP"
size="10"
[ngModel]="con.pA"
(ngModelChange)="con.pA = $event" appFormatP
(blur)="checkAP($event.target.value);
inputTracker.addModifiedValue('Option 1', $event.target.value)"
/>
</div>
</td>
</tr>
<tr>
<td id="row-tag">L</td>
<td id="option-column">${{l}}</td>
</tr>
<tr>
<td id="row-tag">R</td>
<td id="option-column">${{r}}</td>
</tr>
</tbody>
</table>
I think in Angular, you define table based on your data. for example, you have fields array defining columns, and data array defines the what's actually in the table.
<table >
<thead>
<tr>
<th *ngFor='let key of this.fields'>{{key}}</th>
</tr>
</thead>
<tbody>
<tr *ngFor='let row of this.data ' >
<td scope="row" *ngFor='let key of this.fields'> {{row[key]}} </td>
</tr>
</tbody>
</table>
when you need a new column, just push a new field into fields. like
fields.push('newcolumn');
when you need a new row, just do:
data.push({col1: '', col2:'', newcolumn: ''});
Look into the insertRow() and insertCell() functions in JavaScript. This alongside an onClick function that you write will let you edit the table.
A good way of generating a table on UI when using angular would be to use 2D-array (row*column) use can have a button using which you can dynamically add values to this array and have another row/column to the table.
There is a markup:
<div class="scroll">
<table class="table table-striped">
<thead>
<tr>
<th>Image</th>
<th>Name</th>
<th>Author</th>
<th>Year</th>
<th>ISBN</th>
<th>Price</th>
<th>Count</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let book of bookService.bookList">
<td><img src="../../{{book.ImagePath}}" width="100" height="150"></td>
<td>{{book.Name}}</td>
<td>{{book.Author}}</td>
<td>{{book.Year}}</td>
<td>{{book.ISBN}}</td>
<td>{{book.Price}}</td>
<td>{{book.Count}}</td>
<td>
<input type="text" name="Count" [(ngModel)]="Count">
<button class="btn btn-block btn-outline-success" (click)="onAdd(book, Count)"><i class="fa fa-plus"></i></button>
</td>
</tr>
</tbody>
The last column looks like this:
The problem is the following: when filling one TextBox, all the TextBoxes in the column are filled.
How can I solve this problem? Tried to give unique names to text fields and to thrust this cell in form, but all the same did not work.
You need to give unique name to the input field using angular template
<input [name]="'count' + i" >
Where i is the index from the *ngFor
But I think the major issue you have is that you need to bind book.Count instead of just Count
In latter case you'll have one variable called Count and you bind the same variable to all of the input fields. You need to attach the variable to the book itself so it is unique.
All your inputs have the same [(ngModel)]="Count" and the same name so if you update one, all of them will be updated
You can fix that if you have an array of count instead. So it will be something like
<tr *ngFor="let book of bookService.bookList; let i = index">
...
<input type="text" [name]="'count' + i" [(ngModel)]="count[i]">
People are giving you the HTML way, I'm giving you the Angular way : trackBy functions.
*ngFor="let book of bookService.bookList; trackBy: book.Name"
This one should work but I've never tested it.
The one should work in any case :
*ngFor="let book of bookService.bookList; trackBy: customTB"
customTB(item, index) {
return `${index}-${item.Name}`;
}
You can't use the same name for your inputs.
To fix this, you can add an id populate by the index of the loop *ngFor
Try this :
<tr *ngFor="let book of bookService.bookList; let i = index">
<input type="text" name="Count_${i}" [(ngModel)]="count">
I have this situation: I need to bring-up a table structure into a HTML page.One of the columns in this table has to be brought from a table stored in the database.This column value along with two check boxes values needs to be stored in a database and next time these stored values should be brought in ,next time we open that page
HTML code:
<label class="col-md-3" for="Documents">Test:</label>
<div class="col-md-8" ng-controller="checklistController" ng-init='populateChecklist()'>
<div class="table-responsive">
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Not Required</th>
<th>Completed</th>
<th>Link</th>
</tr>
</thead>
<tbody>
<tr ng-repeat = "x in list">
<td>{{x.name}}</td>
<td><input type="checkbox" ng-model='notRequiredCheckList' ng-disabled="completedCheckList" ng-disabled="linkForCheckList"/></td>
<td><input type="checkbox" ng-disabled="notRequiredCheckList" ng-model="completedCheckList" /></td>
<td><input type="text" ng-model="linkForCheckList" size="30" ng-disabled="notRequiredCheckList"/></td>
</tr>
</tbody>
</table>
<button ng-click="Save()">Save</button>
</div>
<div>
Javascript code:
app.controller("checklistController",function($scope,$http){
$scope.populateChecklist = function(a){
$http.get("commonAppGet.jsp?sqlStr=select name from test where val="+a+").then(function(resp){
$scope.list = resp.data;
});
}
});
Here I am getting name from a table and populating the first column when the page is getting loaded.Now along with these names ,I have two checkboxes along with a text box.I have added few validations.Now my challenge is,how to store these values row wise into a new table in the database and load these stored values next time.
Could someone help me?
Is it possible to bind multiple JSON objects in Mustache? I have a little app where I use backbone to extract data from a restful api.
I'm essentially getting a list of employees, and then all of their subordinates. I am passing the model to mustache and binding like this:
render: function(){
//debugger;
var model = {
manager: this.model.toJSON(),
subordinates: this.model.reports.toJSON()
}
console.log('render',this.model.toJSON()); // show the employee and the list of subordinates
this.el.innerHTML = Mustache.to_html(this.template, { employee_detail: model });
}
My template looks like below. It works fine for binding and displaying the manager variables, but the subordinates variables don't show up. I want to display an employee's details and then list all of their subordinates.
{{#employee_detail}}
<h3>{{manager.firstName}} {{manager.lastName}}</h3>
<h4>{{manager.title}}</h4>
<table class="table table-striped">
{{#manager.managerId}}
<tr>
<td>Manager:</td>
<td><i class="icon-user"></i> <a href='#employees/{{manager.managerId}}'>{{manager.managerName}}</a></td>
</tr>
{{/manager.managerId}}
<tr>
<td>Office Phone:</td>
<td><i class="icon-home"></i> {{manager.officePhone}}</td>
</tr>
<tr>
<td>Cell Phone:</td>
<td><i class="icon-headphones"></i> {{manager.cellPhone}}</td>
</tr>
<tr>
<td>Email:</td>
<td><i class="icon-envelope"></i> {{manager.email}}</td>
</tr>
<tr>
<td>Twitter:</td>
<td><i class="icon-retweet"></i> {{manager.twitterId}}</td>
</tr>
</table>
<table>
<tr>
<td>Subordinates:</td>
<td><i class="icon-user"></i> <a href='#employees/{{subordinates.id}}'>{{subordinates.fullName}}</a>
</td>
</tr>
</table>
{{/employee_detail}}
subordinates suggests me you're working with array. If that's the case I believe you should iterate over its elements and display each one separately. If I am right -you are getting 2x undefined when calling {{subordinates.id}}'>{{subordinates.fullName}} because arrays don't have such properties.
more info about itarations over arrays in mustache you can find in this topic:
Mustache.js: Iterate over a list received via json