Edit table row inline on click of edit in Angular - javascript

I have a table where data is populating. Each row has an edit link. I want to edit only a particular row on click of edit link. Right now its' showing edit option for all the rows.
Also I want to show the text in a input box on click of edit.
Here is my code.
<tr *ngFor="let row of backendData.report" class="hover-highlight">
<td class="benchmark_name">
{{row.name}}
</td>
<td>
{{row.value}}
</td>
<td>
{{row.description}}
</td>
<td>
<button *ngIf="enableEdit" (click)="enableEdit=false" class="btn page-secondary-action-btn" ng-click="cancel()">Cancel</button>
<button *ngIf="enableEdit" id="saveBtn" class="btn page-primary-action-btn" (click)="saveSegment()" type="submit">Save</button>
<a class="table-row-action edit-action" *ngIf="!enableEdit" (click)="enableEdit = true">
<i class="fa fa-pencil" uib-tooltip="Edit" tooltip-trigger="mouseenter" tooltip-append-to-body="true" tooltip-placement="left"></i>
</a>
</td>
<td>
</td>
</tr>
My current output looks like this

Here is the solution
html
<tr *ngFor="let row of backendData; index as i;" class="hover-highlight">
<td class="benchmark_name">
{{row.name}}
</td>
<td>
{{row.value}}
</td>
<td>
{{row.description}}
</td>
<td>
<button *ngIf="enableEdit && enableEditIndex == i" (click)="enableEdit=false" class="btn page-secondary-action-btn" ng-click="cancel()">Cancel</button>
<button *ngIf="enableEdit && enableEditIndex == i" id="saveBtn" class="btn page-primary-action-btn" (click)="saveSegment()" type="submit">Save</button>
<a href="#" class="table-row-action edit-action" *ngIf="!enableEdit" (click)="enableEditMethod($event, i)">
edit
</a>
</td>
<td>
</td>
</tr>
ts file
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
name = 'Angular';
enableEdit = false;
enableEditIndex = null;
backendData = [{
"name": 'Target',
"value": '100',
"description": 'abc'
},
{
"name": 'Size',
"value": '20',
"description": 'def'
},
{
"name": 'Industry',
"value": '40',
"description": 'ghi'
}]
enableEditMethod(e, i) {
this.enableEdit = true;
this.enableEditIndex = i;
console.log(i, e);
}
}
Working Demo
Let me know if you have any doubt.

You have to create an index in loop
Then create an array of enableEdit of length i.
Then on click event, write a function which takes a parameter index i.

What you can do is set the "contenteditable" property of the row set to "true".
For example :
By default HTML keeps this to false.
You can get the current index of the table row using either by "trackBy" in *ngFor
*ngFor="let post of posts;trackBy:post?.id"
or you can use this keyword for the current index.
While saving or cancel just make the td's contenteditable to false.

Related

How to populate dynamically added input fields with Json object

I have a this table of input fields which I can add rows dynamically with help of KnockoutJS
<table id="sTypeTable" class="table table-bordered" hidden="hidden">
<tr>
<th> Name </th>
<th> Value </th>
<th> <a class="btn btn-primary btn-sm" onclick="addReqField(0);"><i class="fa fa-plus"></i></a></th>
</tr>
<!-- ko foreach: {data: requestFields, as: 'reqField'} -->
<tr id="sRow">
<td>
<input id="sName" data-bind="value: reqField[0]" onblur="createJSON()"/>
</td>
<td>
<input id="sValue" data-bind="value: reqField[0]" onblur="createJSON()"/>
</td>
<td>
<a class="btn btn-warning btn-sm" data-bind="click: removeResField2" ><i class="glyphicon glyphicon-remove"></i></a>
</td>
</tr>
<!-- /ko -->
</table>
<div class="col-md-11 ">
<textarea style="font-size: larger; min-height: 200px" class="form-control" id="requestData" oninput="storeValueOfTextArea()"></textarea>
</div>
From this inputs I'm generating
following Json object on textarea (id="requestData")
[
{
"users": [
{
"name": "John",
"value": "12"
},
{
"name": "Sarah",
"value": "13"
},
{
"name": "Tom",
"value": "14"
}
]
}
]
It works well, but now I need populate these input fields from Json object,
When object entered to textarea.
I have tried following way
<script th:inline="javascript">
function storeValueOfTextArea() {
var lines = $('#requestData').val();
var texts = JSON.parse(lines);
for (var i=0; i!== texts[0].users.length;i++){
addReqField(); // method for adding new row of input fields
let v = texts[0].users[i];
$("tr[id=sRow]").each(function() {
$("#sName").val(v.name);
$("#sValue").val(v.value);
});
}
</script>
but in result only first input field gets the last object
{
"name": "Tom",
"value": "14"
}
others stays empty
$("tr[id=sRow]").each(function() {
$("#sName").val(v.name);
$("#sValue").val(v.value);
});
This doesn't seem to be good. You should get the row index you want, according to the index of the user for which data you want to fill. Right now what this does is to fill every row with the same user data, in all iterations of the for loop. In the end, the last user data will be in all rows.
I think the problem is that you're giving each created new row the same ID of sRow.
So inside your loop
$("tr[id=sRow]").each(function() {
$("#sName").val(v.name);
$("#sValue").val(v.value);
});
in the last iteration this will fill all sRow elements with the objects last values of Tom and 14.
Try giving your rows an unique id like sRow + a counter from 0 onwards sRow0 sRow1...
Thank you all who have answered to this question.
I have solved this problem by this way
for (let i=0; i!== texts[0].values.length;i++){
addReqField();
let v = texts[0].values[i];
$("tr[id=sRow]").each(function(index) {
if (index === i){
$(this).find("#sName").val(v.name);
$(this).find("#sValue").val(v.value);
}
});
}

Get data from dynamically added elements and pass to Django request.POST

I have a restaurant_form which allows user to input menu items. Each menu item represent a table row which is added dynamically. Each table row has input for: menu item, price, halal(Boolean), and notes.
Here is a sample entry. data-ids and names of input elements are incremented.
<tbody class="menu-entry ">
<tr id='menu0' data-id="0" class="hidden">
<td data-name="name" class="name">
<input type="text" name='name0' placeholder='Menu Item' class="form-control"/>
</td>
<td data-name="price">
<input type="text" name='price0' placeholder='0.00' class="form-control"/>
</td>
<td data-name="halal">
<input type="checkbox" name="veg0" value="halal" class="form-control">
</td>
<td data-name="notes">
<textarea name="notes0" placeholder="Contains soy." class="form-control"></textarea>
</td>
<td data-name="del">
<button name="del0" class='btn btn-danger glyphicon glyphicon-remove row-remove'></button>
</td>
</tr>
</tbody>
What is the best way to retrieve data from the table? I have tried this:
$('#restaurant_form').submit(function () {
$('.menu-entry').each(function()
{
$(this).find('td').each(function(){
$(this).find("input").each(function() {
alert(this.value)
});
$(this).find("textarea").each(function() {
alert(this.value)
});
})
})
})
The alert() shows the correct values however I am wondering if there is a better way to do this?
Edit I simplified it using:
$('.menu-entry .form-control').each()
Also, after retrieving the values, how can I pass it to the view with a POST request? I would like to save the values to model
RestaurantMenu with columns name, price, halal and notes.
Thank you.
Here's what I did:
For every menu entry, I converted the values to a string separated by comma and added a hidden input to hold the value. I added class 'menu-row' to tr.
$('#restaurant_form').submit(function () {
$('.menu-row').each(function(){
var menu_entry = ""
$(this).find('.form-control').each(function(){
menu_entry = menu_entry + this.value + ","
})
$('#restaurant_form').append('<input type="hidden" name="menu_entries" value="'+ menu_entry +'" />')
alert(menu_entry)
})
})
In views.py :
menu_entries = request.POST.getlist('menu_entries')
for menu_entry in menu_entries:
entry = menu_entry.split(",")
if entry[1]:
price = round(float(entry[1]), 2)
else:
price = 0.00
if not entry[2]:
entry[2] = False
MenuItems.objects.create(name=entry[0], price=price, halal=entry[2], notes=entry[3], restaurant_id=r.id)
If anyone knows a better approach, I would love to know. Thank you!

How to edit a cell and delete a row by clicking icon in Angular JS 1.3?

Still be a angular learner.
I have my page like
The code is:
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div ng-controller="EmpCtrl">
<div>
<h2 align="center">Angular JS Basic Example</h2>
<h5 align="center">Employee List</h5>
<table border="1" cellpadding="10" align="center">
<tr>
<th>
Edit
</th>
<th>
Employee Id
</th>
<th>
Employee Name
</th>
<th>
Address
</th>
<th>
Email Id
</th>
<th>
Delete
</th>
</tr>
<tr ng-repeat="emp in employees">
<td>
<a href="#" class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-edit"></i>
</a>
</td>
<td>
{{emp.EmployeeId}}
</td>
<td>
{{emp.EmployeeName}}
</td>
<td>
{{emp.Address}}
</td>
<td>
{{emp.EmailId}}
</td>
<td>
<a href="#"
onclick="return confirm('Delete this Employee?');"
class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
</tr>
</table>
</div>
</div>
I have the js code for getting all employees. It works well.
app.controller("EmpCtrl", function ($scope, EmployeeService) {
GetAllEmployee();
function GetAllEmployee() {
var getAllEmployee = EmployeeService.getEmployee();
getAllEmployee.then(function (emp) {
$scope.employees = emp.data;
}, function () {
alert('Data not found');
});
}
});
My asp mvc service code to delete methos is
[HttpDelete]
public void DeleteEmployee(int id)
{
using (DatabaseContext db = new DatabaseContext())
{
var employeeList = db.EmployeeModels.ToList();
var temp = employeeList.Find(x => x.EmployeeId == id);
employeeList.Remove(temp);
db.SaveChanges();
}
}
I want to click the edit/delete icon to edit or delete, I guess that I have to add other javascript functions to do that.(Maybe ng-clcik??) But I don't know exactly, so how to edit a cell or delete a row?
//html
<td>
<a href="#"
ng-click="delFn(emp.EmployeeId,$index)"
class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
//this way u can achieve it
$scope.delFn = function(id, index){
var response = confirm('Delete this Employee?');
if(response) {
$http.delete('url/' + id).then(function(result) {
result.data ? $scope.employees.splice(index, 1) : null;
}
}
}
This will depend on how your UI looks. Delete is easy, just declare a function in your controller and pass the index of the row to the function like this:
In your controller:
$scope.delFn = function(index){
var response = confirm('Delete this Employee?');
if(response) {
$scope.employees.splice(index, 1);
}
}
In your view: instead of onclick, use ng-click
<td>
<a href="#"
ng-click="delFn($index)"
class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
where $index is implicitly available from ng-repeat. Or you can do this to make it explicit stated.
<tr ng-repeat="emp in employees track by $index">
Can you figure out the edit yourself? since you are using table tag. It looks like you can make a popup/modal, pass in the index of the row in your edit function, get the selected employee from $scope.employees, display the selected one in the popup and make it editable with input tag.
<a href="#"
ng-click="delFn(emp.EmployeeId)"
class="btn btn-default btn-sm">
<i class="glyphicon glyphicon-trash"></i>
</a>
</td>
//this way u can achieve it
$scope.delFn = function(id){
EmployeeService.delEmployee(id).then(function (data) {
GetAllEmployee();
}, function () {
alert('Data not found');
});
}
then add service
this.delEmployee= function (id) {
return $http.post('controller/delEmployee', data={id:id});
}

how to exchange date from one controller to another by using services in angularjs?

I want to get the selected data from the radio button and that particular data should be taken to that vote function and i need to view that data in another view or html by using the service.
How can i pass the values of selected attribute to another view using services?
Here is my code:
<body>
<table>
<tr id="$index" ng-repeat= "a in data ">
<td> {{a.condidateID}} </td>
<td> {{a.condidateName}} </td>
<td> {{a.territory}} </td>
<td> {{a.voteCount}} </td>
<td> <input type="radio" name="chickenEgg" value="egg" ng-model="chekratiovalue" ng-change="chengeEvnt($index)"></td>
</tr>
</table>
<button style="left: 40%;top: 40%;float: left;position: relative" ng-click="voteForPerson()">Vote</button
</body>
angular.module('Design')
.controller('MainCtrl',['profService',function($scope,profService) {
$scope.data = [{
condidateID:"1",
condidateName:"test",
territory:"APAC",
voteCount:"1",
chekratiovalue:"egg"
},
{
condidateID:"2",
condidateName:"test2",
territory:"APAC",
voteCount:"2",
chekratiovalue:"chicken"
}];
$scope.chengeEvnt = function(index) {
$scope.activeRow = index; // get the index when changing the radio button
var selected = $scope.data[$scope.activeRow]; // get the row of selected radio button using the `$scope.activeRow` function
}
$scope.voteForPerson = function() {
}
}]);

How to get the value of a Select box implemented using ng-options which is inside a loop?

I have a list page displaying customer information and in each row of customers there is a Select box with some options like Edit, Cancel, Delete etc. The customers are displayed using ng-repeat directive and the select box with above mentioned options are implemented using ng-options.
I tried to get the value of selected item from drop down against each row, but it is not working, the code worked when I pasted the select box code snippet outside the loop.
Here is my code to display the customers
<table class="table display table-striped table-bordered" ng-table="tableParams">
<tr ng-repeat="customer in $data | filter: search | filter :name">
<td data-title="'Reseller ID'" sortable="'ResellerId'" >
{{customer.ResellerId}}
</td>
<td data-title="'Reseller Name'" sortable="'ResellerName'">
{{customer.ResellerName}}
</td>
<td data-title="'Customer ID'" sortable="'CustomerID'">
{{customer.CustomerID}}
</td>
<td data-title="'Customer Name'" sortable="'CustomerName'">
{{customer.CustomerName}}
</td>
<td data-title="'Status'" sortable="'Status'">
{{customer.Status}}
</td>
<td data-title="'Available Funds'" sortable="'AvailableFunds'">
{{customer.AvailableFunds}}
</td>
<td data-title="'Created Date'" sortable="'CreatedDate'">
{{customer.CreatedDate}}
</td>
<td>
<form name="statusForm">
<select class="form-control status" ng-model="actionslist" name="actions" ng-options="action.name for action in action_options" ng-change="editCustomer()">
<option value="">Select Action</option>
</select>
</form>
</td>
<td><i class="fa fa-desktop"></i> <i class="fa fa-rss"></i> <i class="fa fa-sign-in"></i> </td>
</tr>
</table>
Here is my Angular code
var CustomerController = function ($scope, $filter, $http, ngTableParams) {
$scope.action_options = [{
name: 'Edit',
value: 'edit'
}, {
name: 'Suspend',
value: 'suspend'
}, {
name: 'Cancel',
value: 'cancel'
}, {
name: 'Delete',
value: 'delete'
}, {
name: 'Reset Password',
value: 'reset'
}];
$scope.editCustomer = function () {
//$scope.itemList=[];
alert($scope.item.value);
//alert($scope.selected.actions);
}
}
Could anyone tell me what is the mistake I'm doing here ?
It will be saved through your ng-model
$scope.editCustomer = function () {
alert($scope.actionslist);
}
working fiddle
Try this:
<select ng-model="action" ng-options="obj.value as obj.name for obj in action_options"></select>
and check out this answer https://stackoverflow.com/a/12140310/1530725

Categories

Resources