forming an array from dynamic input fileds using angularjs - javascript

I am working on a employee attendance system where i need to know their attendance status.I am generating a dynamic form which contains a text input field and a checkbox for each employee using angularjs ng-repeat inside a table to know whether the the employee was present or absent along with comments.I want to save the values of these dynamic text filed and checkbox using a single save button.Text fields may have null values or any other values and checkbox may be all checked,all unchecked and few checked and few unchecked. If the check box is checked then i want to save "checked":"yes" otherwise as no.I have also a single date input field to save the record for this particular date.
I think the solution of my situation is forming a dynamic array from inputs and assign it to a variable but and don't know how to form array dynamically in angularjs and then pass the array to a php page.Can you help me on this issue?
My expected array format is :
[{"Did":"10","supervisor":"ms1001","date":"2017-06-01",
"info":
{"eid":"10","checked":"yes","cmnt":"on time"},
{"eid":"20","checked":"NO", "cmnt":"absent"},
{"eid":"30","checked":"yes","cmnt":""},
{"eid":"40","checked":"NO","cmnt":"OK"},
{"eid":"50","checked":"YES","cmnt":""},
{"eid":"60","checked":"YES","cmnt":""},
{"eid":"70","checked":"YES","cmnt":""},
{"eid":"80","checked":"NO","cmnt":"Late"},
{"eid":"90","checked":"YES","cmnt":""}
}];
I will store the input details in attendance table which schema is
attendance(did,eid,date,checked,comment,supervisor_id)
var myApp = angular.module('myApp',['ui.bootstrap']);
myApp.controller('MyCtrl', function($scope) {
$scope.list = [
{"dept_id":"d10","dname":"sales","supervisor":"ms1001"},
{"eid":"10","ename":"nam1"},
{"eid":"20","ename":"nam2"},
{"eid":"30","ename":"nam3"},
{"eid":"40","ename":"nam4"},
{"eid":"50","ename":"nam5"},
{"eid":"60","ename":"nam6"},
{"eid":"70","ename":"nam7"},
{"eid":"80","ename":"nam8"},
{"eid":"90","ename":"nam9"},
{"eid":"120","ename":"nam10"}
];
$scope.did= $scope.list[0].dept_id;
$scope.dname= $scope.list[0].dname;
$scope.sp_name= $scope.list[0].supervisor;
$scope.selectedText = 'Select All';
$scope.isAll = false;
$scope.selectAll = function() {
if($scope.isAll === false) {
angular.forEach($scope.list, function(data){
data.checked = true;
});
$scope.isAll = true;
$scope.selectedText = 'Deselect All';
} else {
angular.forEach($scope.list, function(data){
data.checked = false;
});
$scope.isAll = false;
$scope.selectedText = 'Select All';
}
};
$scope.selectedFriends = function () {
return $filter('filter')($scope.list, {checked: true });
};
//date picker
$scope.open = function($event) {
$event.preventDefault();
$event.stopPropagation();
$scope.opened = true;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.format = 'dd-MMMM-yyyy';
//end of date picker
});
<html>
<head>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<link href="https://cdn.datatables.net/1.10.15/css/dataTables.bootstrap.min.css" rel="stylesheet">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.angularjs.org/1.6.1/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<style>
.full button span {
background-color: limegreen;
border-radius: 32px;
color: black;
}
.partially button span {
background-color: orange;
border-radius: 32px;
color: black;
}
</style>
</head>
<div class="container">
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="row">
<div class="col-sm-3" style="background-color:yellow;">
<p>Department ID::{{did}}</p>
</div>
<div class="col-sm-3" style="background-color:skyblue;">
<p>Dept Name:{{dname}}</p>
</div>
<div class="col-sm-3" style="background-color:pink;">
<p>Supervisor name name:{{sp_name}}</p>
</div>
<div class="col-sm-3">
<p class="input-group">
<input type="text" class="form-control" uib-datepicker-popup="{{format}}"
ng-model="list.dt" is-open="opened" min-date="minDate" max-date="'2018-06-22'"
ng-model-options="{timezone: 'UTC'}"
datepicker-options="dateOptions" date-disabled="disabled(date, mode)"
ng-required="true" close-text="Close" />
<span class="input-group-btn">
<button type="button" class="btn btn-default" ng-click="open($event)">
<i class="glyphicon glyphicon-calendar"></i></button>
</span>
</p>
</div>
</div>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>Employee ID</th>
<th>name</th>
<th><label>Attendence</label><br><span id="selectall" ng-click="selectAll()"><input
type="checkbox">{{selectedText}}</span></th>
<th>comment</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="data in list" ng-if="$index">
<td> {{ data.eid }} </td>
<td> {{ data.ename }} </td>
<td> <input type="checkbox" value="{{ data.eid}}" ng-checked="data.checked" ng-model="data.checked"></td>
<td>
<input type="text" ng-model="data.cmnt" ></td>
</tr>
</tbody>
</table>
<pre>{{list}}</pre>
</div>
<button type="button" ng-click="saveAll()">Save all</button>
</div>
</html>

HTML
<table border="1">
<tr>
<td>Employee ID</td>
<td>Name</td>
<td>Attendance</td>
</tr>
<tr ng-repeat="employee in employees">
<td>{{employee.eid}}</td>
<td>{{employee.ename}}</td>
<td><input type="checkbox" name="check" ng-model="employee.att">
</td>
</tr>
</table>
<button ng-click="saveForm()">Save all</button>
<pre>{{employees}}</pre>
JS
var app = angular.module("myApp", []);
app.controller("myCtrl", function($scope, $http) {
//initial data to display on table.
$scope.employees = [
{eid:"10",ename:"nam1", att: false},
{eid:"20",ename:"nam2", att: false},
{eid:"30",ename:"nam3", att: false},
];
//on save
$scope.saveForm = function (){
$http({
method: 'POST',
url: '/ana/testone',
data: $.param({formData: angular.copy($scope.employees)}),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
console.log(response);
});
}
});
PHP
$data = $_POST['formData'];
echo json_encode($data);

Related

jquery DataTables parent and child rows posted to server as one record instead of two

I have a problem where jquery DataTables creates parent and child rows on resize (responsive DataTable) and I need to save values of inputs from child rows as well as from parent rows and post via ajax to controller action.
Responsive (resized) DataTable:
Normal (not resized) DataTable:
Currently I am using this jquery function to post data to the server:
$('#SaveItemButton').click(function (e) {
var arr = [];
var rows = $('#ItemTable').find('tbody').find('tr');
console.log(rows.length);
$.each(rows, function (index, item) {
var controls = $(this).find('input, select');
console.log(controls.length);
item = {
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price: controls.eq(3).val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
};
arr.push(item);
});
$.ajax({
url: '/Item/Add',
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function (result) {
//alert(result);
},
error: function (errormessage) {
}
});
return false;
});
but when the Datatable is resized it returns two rows which in turn gets posted to the server.
I am retrieving rows from a table via:
var rows = $('#ItemTable').find('tbody').find('tr');
How can I get all the related parent rows and child rows as one row so I can post that row to the server?
Parent row example:
<tr role="row" class="odd parent">
<td tabindex="0" style=""></td>
<td class="sorting_1"><input name="ItemType" class="form-control" type="text"></td>
<td style="display: none;"><select name="Unit" class="form-control defaultpicker"><option>dan</option><option>Komad</option><option>Sat</option>m<option>m2</option><option>m3</option><option>kg</option><option>lit</option><option>pak</option><option>reč</option></select></td>
<td style="display: none;"><input name="Quantity" class="form-control" type="number"></td>
<td style="display: none;"><input name="Price" class="form-control" type="text"></td>
<td style="display: none;"><input name="Total" class="form-control" type="text" readonly=""></td>
<td style="display: none;"><button type="submit" id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>
</td>
</tr>
Child row example:
<tr class="child">
<td class="child" colspan="2">
<ul data-dtr-index="0" class="dtr-details">
<li data-dtr-index="2" data-dt-row="0" data-dt-column="2">
<span class="dtr-title">Unit</span>
<span class="dtr-data">
<select name="Unit" class="form-control defaultpicker"><option>dan</option><option>Komad</option><option>Sat</option>m<option>m2</option><option>m3</option><option>kg</option><option>lit</option><option>pak</option><option>reč</option></select>
</span>
</li>
<li data-dtr-index="3" data-dt-row="0" data-dt-column="3">
<span class="dtr-title">Quantity</span>
<span class="dtr-data">
<input name="Quantity" class="form-control" type="number" value="3">
</span>
</li>
<li data-dtr-index="4" data-dt-row="0" data-dt-column="4">
<span class="dtr-title">Price</span>
<span class="dtr-data">
<input name="Price" class="form-control" type="text" value="1000">
</span>
</li>
<li data-dtr-index="5" data-dt-row="0" data-dt-column="5">
<span class="dtr-title">Total</span>
<span class="dtr-data">
<input name="Total" class="form-control" type="text" readonly="" value="">
</span>
</li>
<li data-dtr-index="6" data-dt-row="0" data-dt-column="6">
<span class="dtr-title"></span>
<span class="dtr-data">
<button type="submit" id="DeleteButton" class="fa fa-times select-row btn btn-secondary btn-sm" data-id=""></button>
</span>
</li>
</ul>
</td>
</tr>
Controller posted data, index 0 contains valid data:
Code Snippet:
var table = $('#ItemTable').DataTable({
"dom": '<"toolbar">frtip',
"paging": true,
"pagingType": "full_numbers",
"searching": false,
// Solution to responsive table losing data
'columnDefs': [{
'targets': [1, 2, 3, 4, 5, 6],
'render': function(data, type, row, meta) {
if (type === 'display') {
var api = new $.fn.dataTable.Api(meta.settings);
var $el = $('input, select, textarea', api.cell({
row: meta.row,
column: meta.col
}).node());
var $html = $(data).wrap('<div/>').parent();
if ($el.prop('tagName') === 'INPUT') {
$('input', $html).attr('value', $el.val());
if ($el.prop('checked')) {
$('input', $html).attr('checked', 'checked');
}
} else if ($el.prop('tagName') === 'TEXTAREA') {
$('textarea', $html).html($el.val());
} else if ($el.prop('tagName') === 'SELECT') {
$('option:selected', $html).removeAttr('selected');
$('option', $html).filter(function() {
return ($(this).attr('value') === $el.val());
}).attr('selected', 'selected');
}
data = $html.html();
}
return data;
}
}],
'responsive': true,
order: [1, 'asc']
});
// Solution to responsive table losing data
$('#ItemTable tbody').on('keyup change', '.child input, .child select, .child textarea', function(e) {
var $el = $(this);
var rowIdx = $el.closest('ul').data('dtr-index');
var colIdx = $el.closest('li').data('dtr-index');
var cell = table.cell({
row: rowIdx,
column: colIdx
}).node();
$('input, select, textarea', cell).val($el.val());
if ($el.is(':checked')) {
$('input', cell).prop('checked', true);
} else {
$('input', cell).removeProp('checked');
}
});
$('#SaveItemButton').click(function() {
var arr = [];
var rows = $('#ItemTable').find('tbody').find('tr');
console.log(rows.length);
$.each(rows, function(index, item) {
var controls = $(this).find('input, select');
console.log(controls.length);
item = {
ItemType: controls.eq(0).val(),
Unit: controls.eq(1).val(),
Quantity: controls.eq(2).val(),
Price: controls.eq(3).val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
};
arr.push(item);
});
$.ajax({
url: '/Item/Add',
data: JSON.stringify(arr),
contentType: 'application/json',
type: "POST",
dataType: "json",
success: function(result) {
//alert(result);
},
error: function(errormessage) {
}
});
return false;
});
<link href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css" rel="stylesheet" />
<link href="https://cdn.datatables.net/responsive/2.2.3/css/responsive.dataTables.min.css" rel="stylesheet" />
<table id="ItemTable" class="table table-hover table-secondary dataTable no-footer dtr-inline" style="width: 100%;" role="grid" aria-describedby="ItemTable_info">
<thead>
<tr role="row">
<th></th>
<th>ItemType</th>
<th>Unit</th>
<th>Quantity</th>
<th>Price</th>
<th>Total</th>
<th></th>
</tr>
</thead>
<tbody>
<tr role="row" class="odd parent">
<td tabindex="0" style=""></td>
<td class="sorting_1"><input name="ItemType" class="form-control" type="text"></td>
<td style="">
<select name="Unit" class="form-control defaultpicker">
<option>value1</option>
<option>value2</option>
<option>value3</option>
<option>value4</option>
<option>value5</option>
<option>value6</option>
<option>value7</option>
<option>value8</option>
<option>value9</option>
</select>
</td>
<td style=""><input name="Quantity" class="form-control" type="number"></td>
<td style=""><input name="Price" class="form-control" type="text"></td>
<td style=""><input name="Total" class="form-control" type="text" readonly=""></td>
<td style=""><button type="submit" id="DeleteButton" data-id=""></button></td>
</tr>
</tbody>
</table>
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/select/1.2.6/js/dataTables.select.min.js"></script>
<script src="https://cdn.datatables.net/responsive/2.2.3/js/dataTables.responsive.min.js"></script>
Well, you really cannot. At first DT inject and remove child rows and their content to and from the DOM, making them invisible to simple jQuery selectors. You can target open child rows, but that is all.
Secondly you cannot select multiple elements in pairs. You could have for example $('tr.parent, tr.parent ~ tr.child') or similar, but that would be equal to just $('tr'). I would go through the API:
table.rows().every(function() {
var $node = this.nodes().to$();
var item = {
ItemType: $node.find('input[name=ItemType]').val(),
Unit: $node.find('select[name=Unit]').val(),
Quantity: $node.find('input[name=Quantity]').val(),
Price: $node.find('input[name=Price]').val(),
Total: $node.find('input[name=Total]').val(),
InvoiceDate: $('#InvoiceDate').val(),
TransferDate: $('#TransferDate').val(),
TransferPlace: $('#TransferPlace').val(),
InvoiceDescription: $('#InvoiceDescription').val()
};
arr.push(item)
})
Completely untested. See JQuery Datatables search within input and select on how to update the DT internals when form controls is changing. Otherwise you will just get return default / original values.

How to get Array data wihile ng-change function in ng repeat for every iteration

var app = angular.module("myapp", []);
app.controller("ctrl", function($scope, $http, jsonFilter) {
$scope.loadcat = function() {
$http.get("cat_load.php")
.success(function(data, status, headers, config) {
$scope.CategoryArray = data;
});
}
$scope.GetProduct = function(categoryid, index) {
$http.post("product_load.php", {
'cat_id': categoryid
})
.success(function(data, status, headers, config) {
$scope.ProductsArray[index] = data;
});
}
$scope.GetSubCategory = function(categoryid, productname) {
$http.post("subcat_load.php", {
'cat_id': categoryid,
'productname': productname
})
.success(function(data, status, headers, config) {
$scope.subcatids = data;
});
}
/**********to add remove row start here **********/
$scope.remove_Row = function(name) {
var index = -1;
var comArr = eval($scope.data);
for (var i = 0; i < comArr.length; i++) {
if (comArr[i].name == name) {
index = i;
break;
}
}
if (index == -1) {
//alert( "Something gone wrong" );
}
$scope.data.splice(index, 1);
};
// dynamic row creation
$scope.data = [{}];
$scope.addFormField = function() {
//alert($scope.data);
$scope.data.push({});
}
/**********to add remove row End here **********/
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body class="no-skin" ng-app="myapp" ng-controller="ctrl">
<table ng-table="tableParams" class="display table table-striped table-bordered">
<thead>
<tr>
<th width="2%">Sr.No</th>
<th width="10%">Category Type <span class="error">*</span></th>
<th width="10%">Product <span class="error">*</span></th>
<th width="10%">Sub Category</th>
</tr>
</thead>
<tr ng-repeat="cap in data">
<td>{{$index+1}}</td>
<td data-title="'Category Type'" sortable="Category Type">
<select class="form-control" id="tags" type="text" ng-model="cap.categoryid" placeholder="Category Type" name="categoryid" required="" ng-init="loadcat()" ng-change="GetProduct(cap.categoryid,$index);GetSubCategory(cap.categoryid,cap.productname)">
<option value="">Select</option>
<option ng-repeat="cat in CategoryArray" value="{{cat.Category_Id}}">{{cat.Category_Name}}</option>
</select>
</td>
<td data-title="'Product'" sortable="Product">
<select class="form-control" type="text" name="productname" ng-model="cap.productname" placeholder="Enter Product Name" required ng-change="GetSubCategory(cap.categoryid,cap.productname)" />
<option value="">select</option>
<option ng-repeat="pro in ProductsArray[$index]" value="{{pro.ProductId}}">{{pro.ProductlName}}</option>
</select>
</td>
<td data-title="'Sub Category1'" sortable="Sub Category1">
<select class="form-control" type="text" name="subcategoryid" ng-model="cap.subcategoryid" id="subcategoryid">
<option value="">Select</option>
<option ng-repeat="subcatid in subcatids" value="{{subcatid.Sub_category_Id}}">{{subcatid.Sub_Category_Name}} </option>
</select>
</td>
<td>
<div class="pull-right">
<a ng-click="addFormField()" ng-if="data.length==$index+1" class='btn btn-default btn-xs' autofocus data-dismiss="modal"> <i class="glyphicon glyphicon-plus"></i></a>
<a ng-click="remove_Row($index)" class='btn btn-primary btn-xs' autofocus data-dismiss="modal"> <i class="glyphicon glyphicon-remove"></i></a>
</div>
</td>
</tr>
</table>
</body>
</html>
I'am getting CategoryArray data using ng-init="loadcat()" on ng-change="GetProduct(cap.categoryid)" of category fetching dynamic data in ProductsArray. And I like also on ng-change="GetSubCategory(cap.categoryid,cap.productname)" of productname to fetch the dynamic data in subcatids
But the problem is while I'am adding one more row, again selecting category the ProductsArray changing for previous row also.
Q: How could I get ProductsArray on every selecting category in ng repeat for every iteration?

AngularJS- some of my scope variables not displaying

I'm a new developer using Angular JS to create an orders page for an app I created in Ruby on Rails. I would like to get a few Angular variables to display:
order.id (displays)
order.user.email (does not display)
order.total (does not display)
order.product.name (displays)
Only 2 of the 4 variables display. When I put a string or integer into the {{}} Angular notation in place of order.total | currency, the string or integer displays. However, when I try the same with order.product.name, nothing happens.
Here is my relevant code:
View.html:
<div ng-controller="OrdersCtrl">
<h1>Orders</h1>
<div class="container">
<form class="form-inline" ng-submit="addOrder()">
<strong>Add Order: </strong>
<select ng-model="newOrder.product_id" class="form-control">
<option value="" disabled selected>Select a Product</option>
<option ng-repeat="product in products" value="{{product.id}}"> {{product.name}}</option>
</select>
<input type="number" step="1" class="form-control" placeholder="Total" ng-model="newOrder.total">
<input type="number" class="form-control" ng-model="newOrder.product_id">
<input type="submit" value="+" class="btn btn-success">
</form>
<table class="table table-hover">
<thead>
<td>Order ID</td>
<td>Total</td>
<td>Product</td>
<td></td>
</thead>
<tr ng-repeat="order in orders | orderBy:'-id':reverse">
<td>
{{order.id}}<small ng-show="order.user_id"><br>-{{order.user.email}}</small>
</td>
<td>
<strong>{{order.total | currency}}</strong>
</td>
<td>
{{order.product.name}}
</td>
<td>
<button ng-click="deleteOrder(order)" class="btn btn-danger btn-sm"><span class="glyphicon glyphicon-trash" aria-hidden="true"></span></button>
</td>
</tr>
</table>
</div>
Controller (app.js)
var app = angular.module('shop', ['ngResource']);
//Workaround to get Angular running
$(document).on('ready page:load', function() {
angular.bootstrap(document.body, ['shop'])
});
//factory for models
app.factory('models', ['$resource', function($resource){
var orders_model = $resource("/orders/:id.json", {id: "#id"});
var products_model = $resource("/products/:id.json", {id: "#id"});
var x = {
orders: orders_model,
products: products_model
};
return x;
}]);
//connect app to OrdersCtrl controller
app.controller('OrdersCtrl', ['$scope', 'models', function($scope, models){
// Here will be all code belonging to this controller
$scope.orders = models.orders.query();
$scope.products = models.products.query();
//add new orders
$scope.addOrder = function(){
//only orders with product id or zero total gets added
if(!$scope.newOrder.product_id || $scope.newOrder.total === ''){ return; }
//Order can be submitted if product_id and total are filled out
order = models.orders.save($scope.newOrder, function(){ //POST
recent_order = models.orders.get({id: order.id});
$scope.orders.push(recent_order);
$scope.newOrder = '';
});
}
//delete orders
$scope.deleteOrder = function(order){
models.orders.delete(order);
$scope.orders.splice($scope.orders.indexOf(order), 1);
};
}]);

Iterating over table using Angular

I'm new to angular and js. I did a table (just a header) and a button. When I click the button a new row line is added. Every cell of that row is a form text field. Everithing works fine. Now I'm trying to do a second button, when I click it must iterate over the rows and validate the fields. I'm not finding any documentation about that... so i'm not sure if this mettod (add a new row with a button) is appropiate. That's how I did it:
index.html this contains angular and my script, also contains the routes:
<html ng-app="assets">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="sources/js/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.10/angular-route.min.js"></script>
<script>
var assets = angular.module('assets', ['ngRoute']);
assets.config(function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'home.html'
}).
when('/:tipusactius', {
templateUrl: 'tipusactius.html',
controller: 'TipusActiusCtrl'
}).
when('/:tipusactius/alta', {
templateUrl: 'tipusactius-alta.html',
controller: 'AfegirTipusActiusCtrl'
}).
otherwise({
redirectTo: '/'
});
});
assets.controller('TipusActiusCtrl', function ($scope, $http){
$http.get('http://10.0.203.73/WS/ws.php/tipusactius/').success(function(data) {
$scope.tipus_actius = data;
});
// Ordena taula per id desc
$scope.sortField = 'idtipus_actius';
$scope.reverse = false;
});
assets.controller('AfegirTipusActiusCtrl', function ($scope, $http){
// Camps formulari text pla
$scope.nomAtribut = "<input type='text' name='firstname'>";
$scope.mida = "<input type='number' name='firstname'>";
$scope.obligatori = "<input type='checkbox' name='vehicle' value='yes'>";
// Construeix combo
$http.get('http://10.0.203.73/WS/ws.php/getCombo/1').success(function(data) {
$scope.options = data;
});
$scope.atributs = [];
$scope.addField = function() {
$scope.atributs.push($scope.atributs.length);
};
$scope.prioritat = $scope.atributs.length;
});
assets.directive('compile', compile);
function compile($compile)
{
return {
restrict: 'A',
replace: true,
link: linkFunction
};
function linkFunction(scope, element, attrs)
{
scope.$watch(
function (scope)
{
return scope.$eval(attrs.compile);
},
function (value)
{
element.html(value);
$compile(element.contents())(scope);
}
);
}
}
</script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css"
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
<div class="container" ng-view></div>
</body>
</html>
And this is the view where the table is(tipusactius-alta):
<div class="row">
<div class="col-md-8" ng-controller="AfegirTipusActiusCtrl">
<button ng-click="addField()">Nou atribut</button>
<div>
<table class="table">
<tr>
<td>Nom atribut</td>
<td>Tipus</td>
<td>Mida</td>
<td>Prioritat</td>
<td>Obligatori</td>
</tr>
<tr ng-repeat="atribut in atributs">
<td compile="nomAtribut"></td>
<td>
<select id="tipus">
<option ng-repeat="option in options" value="{{option.idvalors_combo}}">{{option.valor}}</option>
</select>
</td>
<td compile="mida"></td>
<td>
<select id="prioritat">
<option ng-repeat="p in prioritat" value="{{p}}">{{p}}</option>
</select>
</td>
<td compile="obligatori"></td>
</tr>
</table>
</div>
</div>
</div>
</div>
I'm not sure if this has been a good idea. I would like to find a way to iterate over the rows to read cell values, and if the values of all cells from all the rows is ok submit the values to the web service but I have no idea. Any help will be great.
You don't actually need to manipulate html directly. Just use ng-repeat over your data collection. Button should add new items to that collection and angular will create new table row in the document.
I've created small sample here: http://jsfiddle.net/Lvc0u55v/252/
var myApp = angular.module('myApp', []);
myApp.controller('tableCtrl', function($scope) {
$scope.dataTable = [{
"name": "Alex",
"lastName": "Karlov",
"age": 23,
"sex": 1
}];
$scope.options = [{
"value": 1,
"title": "Male"
}, {
"value": 2,
"title": "Female"
}];
$scope.addRow = function() {
var newItem = {
name: "",
lastName: "",
age: "",
sex: ""
}
$scope.dataTable.push(newItem);
};
});
And this is the html (I've created it based on yours code):
<div class="col-md-8" ng-controller="tableCtrl">
<button ng-click="addRow()">Add row</button>
<div>
<table class="table">
<tr>
<td>#</td>
<td>Name</td>
<td>Last Name</td>
<td>Age</td>
<td>Sex</td>
</tr>
<tr ng-repeat="item in dataTable">
<td>{{ $index + 1 }}</td>
<td>
<input type="text" ng-model="item.name" />
</td>
<td>
<input type="text" ng-model="item.lastName" />
</td>
<td>
<input type="text" ng-model="item.age" />
</td>
<td>
<select ng-options="option.value as option.title for option in options" ng-model="item.sex"></select>
</td>
</tr>
</table>
</div>
</div>
In that sample I've put all my data into dataTable variable. When I want to add one more row, I just need to add new empty object (or with predefined values) into dataTable collection. Angular will do the trick.

How to modify and update data table row in angular js?

I m learning of angular js and i have found i issue .
I m creating a new projects .
i have some button edit , add, remove,
if i click to my edit button than show all field but i want to show only current field than i click to update update this filed .
My code is here
Anguar
var app = angular.module('addApp', []);
app.controller('modifyCtrl', ['$scope', function($scope){
$scope.tabelsData= [
{'name':'rohit', 'dob':'15-august-1985', 'emailId':'rohit#rohit.com', 'phone':'9999999999', 'address':'Delhi Rohini', 'id':'0' },
{'name':'aman', 'dob':'26-july-1975', 'emailId':'haryanat#hr.com', 'phone':'9874563210', 'address':'Haryana Sonepat', 'id':'1' },
{'name':'devraj', 'dob':'27-march-1980', 'emailId':'punjab#punjab.com', 'phone':'7410258963', 'address':'Punjab AmritSar', 'id':'2' }
];
$scope.modify = function(tableData){
$scope.modifyField = true;
$scope.viewField = true;
};
$scope.update = function(tableData){
$scope.modifyField = false;
$scope.viewField = false;
};
}]);
HTML Code is
<div ng-app="addApp">
<div class="wraper" ng-controller="modifyCtrl">
<table>
<thead>
<tr>
<th>Name:</th>
<th>Date Of Birth</th>
<th>Email Id</th>
<th>Phone No.</th>
<th>Address</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tableData in tabelsData"><form>
<td>
<div ng-hide="viewField">{{tableData.name | uppercase}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.name" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.dob}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.dob" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.emailId}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.emailId" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.phone}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.phone" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.address}}</div>
<div ng-show="modifyField">
<textarea ng-model="tableData.address"></textarea>
</div>
</td>
<td>
<button ng-hide="viewField" ng-click="modify(tableData)">Modify</button>
<button ng-show="modifyField" ng-click="update(tableData)">Update</button>
<button ng-hide="viewField">Add</button>
<button ng-hide="viewField">Remove</button>
</td></form>
</tr>
</tbody>
</table>
</div>
</div>
var app = angular.module('addApp', []);
app.controller('modifyCtrl', ['$scope', function($scope){
$scope.tabelsData= [
{'name':'rohit', 'dob':'15-august-1985', 'emailId':'rohit#rohit.com', 'phone':'9999999999', 'address':'Delhi Rohini', 'id':'0' },
{'name':'aman', 'dob':'26-july-1975', 'emailId':'haryanat#hr.com', 'phone':'9874563210', 'address':'Haryana Sonepat', 'id':'1' },
{'name':'devraj', 'dob':'27-march-1980', 'emailId':'punjab#punjab.com', 'phone':'7410258963', 'address':'Punjab AmritSar', 'id':'2' }
];
$scope.modify = function(tableData){
$scope.modifyField = true;
$scope.viewField = true;
};
$scope.update = function(tableData){
$scope.modifyField = false;
$scope.viewField = false;
};
}]);
table td, table th{
border:solid 1px red;
padding:5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="addApp">
<div class="wraper" ng-controller="modifyCtrl">
<table>
<thead>
<tr>
<th>Name:</th>
<th>Date Of Birth</th>
<th>Email Id</th>
<th>Phone No.</th>
<th>Address</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tableData in tabelsData"><form>
<td>
<div ng-hide="viewField">{{tableData.name | uppercase}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.name" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.dob}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.dob" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.emailId}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.emailId" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.phone}}</div>
<div ng-show="modifyField"><input type="text" ng-model="tableData.phone" /></div>
</td>
<td>
<div ng-hide="viewField">{{tableData.address}}</div>
<div ng-show="modifyField">
<textarea ng-model="tableData.address"></textarea>
</div>
</td>
<td>
<button ng-hide="viewField" ng-click="modify(tableData)">Modify</button>
<button ng-show="modifyField" ng-click="update(tableData)">Update</button>
<button ng-hide="viewField">Add</button>
<button ng-hide="viewField">Remove</button>
</td></form>
</tr>
</tbody>
</table>
</div>
</div>
If you only want one row to show the inputs on clicking its respective modify button you have two options:
1) Attach booleans to each of the JSON indexes of the tabelsData array.
2) Make a mirror array that houses these booleans.
Having two separate booleans in this case is useless, because each one is being treated on a toggle basis:
Here is the core code for doing approach number two since I assume you want your data to remain the same:
JS:
$scope.editingData = {};
for (var i = 0, length = $scope.tabelsData.length; i < length; i++) {
$scope.editingData[$scope.tabelsData[i].id] = false;
}
$scope.modify = function(tableData){
$scope.editingData[tableData.id] = true;
};
$scope.update = function(tableData){
$scope.editingData[tableData.id] = false;
};
Html:
<tbody>
<tr ng-repeat="tableData in tabelsData">
<td>
<div ng-hide="editingData[tableData.id]">{{tableData.name | uppercase}}</div>
<div ng-show="editingData[tableData.id]"><input type="text" ng-model="tableData.name" /></div>
</td>
<td>
<div ng-hide="editingData[tableData.id]">{{tableData.dob}}</div>
<div ng-show="editingData[tableData.id]"><input type="text" ng-model="tableData.dob" /></div>
</td>
<td>
<div ng-hide="editingData[tableData.id]">{{tableData.emailId}}</div>
<div ng-show="editingData[tableData.id]"><input type="text" ng-model="tableData.emailId" /></div>
</td>
<td>
<div ng-hide="editingData[tableData.id]">{{tableData.phone}}</div>
<div ng-show="editingData[tableData.id]"><input type="text" ng-model="tableData.phone" /></div>
</td>
<td>
<div ng-hide="editingData[tableData.id]">{{tableData.address}}</div>
<div ng-show="editingData[tableData.id]">
<textarea ng-model="tableData.address"></textarea>
</div>
</td>
<td>
<button ng-hide="editingData[tableData.id]" ng-click="modify(tableData)">Modify</button>
<button ng-show="editingData[tableData.id]" ng-click="update(tableData)">Update</button>
<button ng-hide="viewField">Add</button>
<button ng-hide="viewField">Remove</button>
</td>
</tr>
</tbody>
I made an example:
http://plnkr.co/edit/lXq1WB
Here is an example in Angular2, (this will NOT work for AngularJS!)
fichier.html:
<ng2-toasty [position]="'top-left'"></ng2-toasty>
<label for="trainingInput" class="mr-2">{{ 'LABEL.FORMATION' | translate }} :</label>
<table class="table table-hover table-striped table-sortable table-bordered">
<thead>
<tr>
<th *ngFor="let column of columns" [class]="selectedClass(column.variable)" (click)="changeSorting(column.variable)" translate>
{{column.display}}
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let object of data | orderBy : convertSorting(); let rowIndex = index">
<td *ngFor="let column of columns" class="{{column.variable}}-td">
<div *ngIf="!toUpdates[object['id']]" >{{object[column.variable] | format: column.filter}}</div>
<div *ngIf="toUpdates[object['id']]"><input type="text" [(ngModel)]="object[column.variable]" ></div>
</td>
<td class="text-center">
<i *ngIf="!toUpdates[object['id']]" class="fa fa-pencil-square-o edit-formation" aria-hidden="true" (click) = "editFormation(object)"></i>
<i *ngIf="toUpdates[object['id']]" class="fa fa-check-square-o save-edit-form" (click)="updateFormation(object)"></i>
<i class="fa fa-times" aria-hidden="true" (click)="deleteFormation(object['id'])"></i>
</td>
</tr>
<tr [hidden]="isDisabled()">
<td><input type="text" class="form-control" placeholder="Année" #years></td>
<td><input type="text" class="form-control" placeholder="Formation" #label></td>
<td><input type="text" class="form-control" placeholder="Durée" #duration></td>
<td class="text-center align-middle">
<i class="fa fa-plus-circle fa-2x" (click)="addFormation(years.value, label.value, duration.value)"></i>
</td>
</tr>
</tbody>
</table>
fichier.ts:
import {Component, Injector, Input, OnChanges, OnInit} from '#angular/core';
import { Http, Headers, RequestOptions, URLSearchParams } from '#angular/http';
import DynamicComponent from '../dynamic-component';
import Formation from './formation';
import {ToastyService, ToastyConfig, ToastOptions, ToastData} from 'ng2-toasty';
#Component({
moduleId: module.id,
selector: 'formations-selector',
templateUrl: './formations-template.html',
styleUrls: ['./formations-template.css'],
})
export default class FormationsComponent{
candidate: any = null;
listFormations: any = null;
candidateDetails: any = null;
columns: any[];
sort: any;
data: any[];
toUpdates: {};
constructor(private injector: Injector, private http: Http,private toastyService: ToastyService, private toastyConfig: ToastyConfig) {
this.candidateDetails = this.injector.get('candidateDetails');
this.candidate = this.candidateDetails.candidate;
this.listFormations = this.candidateDetails.listFormations;
this.columns = this.listFormations.columns;
this.sort = this.listFormations.sort;
this.data = this.listFormations.data;
this.toastyConfig.theme = 'material';
this.toUpdates = {};
}
ngAfterViewInit(){
$(document).ready(function() {
/*
$('.edit-formation').click(function () {
var dad = $(this).parent().parent();
dad.find('td .duration-span').hide();
dad.find('td.duration-td').append('<input type="text" class="form-control" placeholder="Durée" value="'+dad.find('td .duration-span').html()+'" id = "duration-update" #durationu>');
dad.find('td .label-span').hide();
dad.find('td.label-td').append('<input type="text" class="form-control" placeholder="Formation" id="label-update" value="'+dad.find('td .label-span').html()+'" #labelu>');
dad.find('td .years-span').hide();
dad.find('td.years-td').append('<input type="text" class="form-control" placeholder="Année" id="years-update" value="'+dad.find('td .years-span').html()+'" #yearsu>');
dad.find('td.years-td').append('<i class="fa fa-check-square-o save-edit-form hidden" (click)="updateFormation(1, years.value, label.value, durationu)"></i>');
dad.find('td .edit-formation').addClass("hidden");
dad.find('td .save-edit-form').removeClass("hidden");
});
*/
/*
$('.save-edit-form').click(function () {
var dad = $(this).parent().parent();
dad.find('td .save-edit-form').addClass("hidden");
dad.find('td .edit-formation ').removeClass("hidden");
dad.find('td .duration-span').show();
$('#duration-update').remove();
dad.find('td .label-span').show();
$('#label-update').remove();
dad.find('td .years-span').show();
$('#years-update').remove();
});
*/
});
}
//Action déclenché lors d'un changement de société du candidat : on met à jour la liste des métiers associés
onChangeCompaniesInput(value) {
}
isDisabled(isDisabled) {
//return (isDisabled || !this.candidateDetails.isUserAuthorized) ? true : false;
}
selectedClass(columnName): string{
return columnName == this.sort.column ? 'sort-' + this.sort.descending : '';
}
changeSorting(columnName): void{
var sort = this.sort;
if (sort.column == columnName) {
sort.descending = !sort.descending;
} else {
sort.column = columnName;
sort.descending = false;
}
}
convertSorting(): string{
return this.sort.descending ? '-' + this.sort.column : this.sort.column;
}
onChangeMainFormaion(value): void{
console.log(value);
}
deleteFormation(idFormation): void{
let headers = new Headers('Content-Type', 'application/json');
let params: URLSearchParams = new URLSearchParams();
this.http.post('/api/formations/'+idFormation+'/deleteFormation', params).toPromise()
.then(
res =>
{
if(res.status == 200){
this.toastyService.success({
title: "Success",
msg: "La formation a etait supprmié avec Succès",
showClose: true,
timeout: 5000,
theme: 'default',
});
}else{
this.toastyService.error({
title: "Error",
msg: "Une erreur est survenue, veuillez réessayer ultérieurement",
showClose: true,
timeout: 5000,
theme: 'default',
});
}
}
).catch(this.handleError);
}
editFormation(tableData): void{
this.toUpdates[tableData['id']]= true;
}
updateFormation(tableData): void {
this.toUpdates[tableData['id']]= false;
console.log(tableData);
}
addFormation(years: string, label: string, durration: string, main: boolean = false): void{
let headers = new Headers('Content-Type', 'application/json');
let params: URLSearchParams = new URLSearchParams();
params.append('years', years);
params.append('label', label);
params.append('durration', durration);
params.append('main', main);
//let formation = new Formation(years, label, durration, false);
return this.http.post('/api/formations/'+this.candidate.id+'/addFormation', params).toPromise()
.then(
res =>
{
if(res.status == 200){
this.toastyService.success({
title: "Success",
msg: "La formation a etait ajouter avec Succès",
showClose: true,
timeout: 5000,
theme: 'default',
});
}else{
this.toastyService.error({
title: "Error",
msg: "Une erreur est survenue, veuillez réessayer ultérieurement",
showClose: true,
timeout: 5000,
theme: 'default',
});
}
}
).catch(this.handleError);
}
private handleError(error: any) {
let errMsg = (error.message) ? error.message : error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg);
return Promise.reject(errMsg);
}
}

Categories