Define and get values from angularJS table - javascript

Here is my angularjs code to get values in a table and save. If I put some data in table and save, Its working fine but if I click save without entering any data in table it shows error as
TypeError: $scope.item is undefined
Here is my code and please help me. I am a newbie in angularJS
<div ng-app="Myapp">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-route.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-messages.js"></script>
<script>
var Myapp = angular.module('Myapp', ["ngRoute"]);
</script>
<div ng-controller="orderFormController">
<table id="item_table">
<thead>
<tr class="headings">
<th class="column-title">Item </th>
<th class="column-title">Rate</th>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="text" name="item" ng-model='item[0]'>
</td>
<td>
<input type="text" name="rate" ng-model='rate[0]'>
</td>
</tr>
<tr>
<td>
<input type="text" name="item" ng-model='item[1]'>
</td>
<td>
<input type="text" name="rate" ng-model='rate[1]'>
</td>
</tr>
</tbody>
</table>
<button type="button" ng-click='saveorder()' >SAVE ORDER</button>
</div>
<script>
Myapp.controller('orderFormController', ['$scope', '$http', function ($scope, $http) {
var data = {};
data['item'] = [];
$scope.saveorder = function () {
var rowCount = 3;
for (i = 1; i < rowCount; i++) {
data['item'][i] = {'item': $scope.item[i], 'rate': $scope.rate[i]}
}
alert(data);
}
}]);
</script>

$scope.item is not defined anywhere except for in that for loop, if there are no values in the table, then $scope.item will remain undefined. You could simply declare it prior to the for loop, and set some init values, which could be done in the controller, or by using the ng-init directive.
Also, I would recommend using the ng-repeat directive for your table rows, it will create a template per item from a collection, which makes your code easier to manage. Here's the documentation: ngRepeat

modify your html to only include this not 2 rows of input
<td>
<input type="text" name="item" ng-model='item'>
</td>
<td>
<input type="text" name="rate" ng-model='rate'>
</td>
and modify your saveOrder
$scope.saveorder = function () {
if (!($scope.item.length && $scope.rate.length)){
alert('can\'t be empty');
return;
}
data['item'].push({'item': $scope.item, 'rate': $scope.rate});
$scope.item = "";
$scope.rate = "";
console.log(data['item'][data['item'].length - 1]);
alert(data);
}

Related

Can't print the Array in view using ng-repeat in angular JS

I have designed the dynamic table with the various type of the input field.We can add and delete the row as per the requirement.
Here is my HTML view code:
<body>
<div ng-app="appTable">
<div ng-controller="Allocation">
<button ng-click="add()"> Add </button>
<button ng-click="remove()">remove</button>
<table>
<th>
<td>Date</td>
<td>Project</td>
<td>Release</td>
<td>Feature</td>
<td>Module name</td>
<td>Hours spent</td>
<td>Comment</td>
</th>
<tr ng-repeat="data in dataList">
<td><input type="checkbox" ng-model="data.isDelete"/></td>
<td>
<input type="text"
datepicker
ng-model="data.date" />
</td>
<td><input type="text" ng-model="data.dept"/></td>
<td>
<select ng-model="data.release" ng-options="x for x in range">
</select>
</td>
<td>
<select ng-model="data.feature" ng-options="x for x in feature">
</select>
</td>
<td>
<input type = "text" ng-model = "data.modulename">
</td>
<td>
<select ng-model="data.hours" ng-options="x for x in hours">
</select>
</td>
<td>
<input type = "text" ng-model = "data.comment">
</td>
</tr>
</table>
<button ng-click="Submit()">Submit</button>
<tr ng-repeat="data in dataList">
<p>{{data.date}}</p>
<p>{{test}}</p>
</tr>
</div>
</div>
</body>
Here my angularJS script:
<script>
var app = angular.module("appTable", []);
app.controller("Allocation", function($scope) {
$scope.hours = ["1", "2", "3"];
$scope.range = ["1", "2", "3"];
$scope.feature = ["UT", "FSDS", "Coding/Devlopment", "QA"];
$scope.dataList = [{
date: '17/07/2016',
dept: 'OneCell',
release: '1',
feature: "UT",
modulename: "Redundancy",
hours: "1",
comment: "Add extra information"
}];
$scope.add = function() {
var data = {};
var size = $scope.dataList.length - 1;
data.date = $scope.dataList[size].date;
data.dept = $scope.dataList[size].dept;
data.release = $scope.dataList[size].release;
data.feature = $scope.dataList[size].feature;
data.modulename = $scope.dataList[size].modulename;
data.hours = $scope.dataList[size].hours;
data.comment = $scope.dataList[size].comment;
$scope.dataList.push(data);
};
$scope.Submit = function() {
$scope.test = "Submit is pressed...";
};
$scope.remove = function() {
var newDataList = [];
angular.forEach($scope.dataList, function(v) {
if (!v.isDelete) {
newDataList.push(v);
}
});
$scope.dataList = newDataList;
};
});
app.directive("datepicker", function () {
function link(scope, element, attrs, controller) {
// CALL THE "datepicker()" METHOD USING THE "element" OBJECT.
element.datepicker({
onSelect: function (dt) {
scope.$apply(function () {
// UPDATE THE VIEW VALUE WITH THE SELECTED DATE.
controller.$setViewValue(dt);
});
},
dateFormat: "dd/mm/yy" // SET THE FORMAT.
});
}
return {
require: 'ngModel',
link: link
};
});
</script>
I have taken the dataList array(list) to store the rows the of table.Every time when row will be added or deleted then respective element in the dataList array will be added and delete.
I have put the "submit" button in my view.When this button will be pressed then all the dataList element will be printed as shown here,
<button ng-click="Submit()">Submit</button>
<tr ng-repeat="data in dataList">
<p>{{data.date}}</p>
<p>{{test}}</p>
</tr>
But some how the dataList elements are not printed.However I am able to print the value of the test string.Please help.
Here you are using plain <tr> element for ng-repeat, this will not work, as it require proper structure of table.
E.g.:
<table>
<tr ng-repeat="data in dataList">
<td>
<p>{{data.date}}</p>
</td>
</tr>
</table>
P.S. : Your submit button is doing nothing. Just printing one statement. Above code of ng-repeat will work on each add and delete statement. i.e. it will print data simultaneously.

Sorting,Filtering and Pagination in AngularJS

I am new to mean stack and for the first time writing code in AngularJS, I am trying to implement Sorting, Paging and Filtering in below index.html file. Something isn't right how I am trying to implement, please help
Here is my index.html file -
<!DOCTYPE>
<html ng-app="myApp">
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<title>eAPI Test Execution Portal</title>
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<h1>eAPI Test Execution Portal</h1>
<table class="table table-fluid">
<thead>
<tr>
<th>runId
<th>apiName
</th>
</th>
<th>runTime
</th>
<th>Report
</th>
<th>numOfTestExecuted
</th>
<th>numOfTestFailed
</th>
<th>status
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<input type="text" ng-model="search.runId" placeholder="Search by runId" />
</td>
<td>
<input type="text" ng-model="search.apiName" placeholder="Search by apiName" />
</td>
<td>
<input type="text" ng-model="search.runTime" placeholder="Search by runTime" />
</td>
<td>
<input type="url" ng-model="search.Report" placeholder="Search by Report URL" />
</td>
<td>
<input type="text" ng-model="search.numOfTestExecuted" placeholder="Search by numOfTestExecuted" />
</td>
<td>
<input type="text" ng-model="search.numOfTestFailed" placeholder="Search by numOfTestFailed" />
</td>
<td>
<input type="text" ng-model="search.status" placeholder="Search by status" />
</td>
</tr>
<tr ng-repeat="contact in contactlist">
<td>{{contact.runId}}</td>
<td>{{contact.apiName}}</td>
<td>{{contact.runTime}}</td>
<td>{{contact.Report}}</td>
<td>{{contact.numOfTestExecuted}}</td>
<td>{{contact.numOfTestFailed}}</td>
<td>{{contact.status}}</td>
</tr>
<tr ng-repeat="contact in contactlist | orderBy:predicate:reverse | filter:paginate| filter:search" ng-class-odd="'odd'">
<td>{{user.runId}}</td>
<td>{{user.apiName}}</td>
</tr>
</tbody>
</table>
<pagination total-items="totalItems" ng-model="currentPage" max-size="5" boundary-links="true" items-per-page="numPerPage" class="pagination-sm">
</pagination>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<script src="controllers/controller.js"></script>
</body>
</html>
Here is the controller.js file - (If you want to try in your local, using mean stack)
var myApp = angular.module('myApp', []);
myApp.controller('AppCtrl', ['$scope', '$http',
function($scope, $http) {
console.log("Hello World from controller");
var refresh = function() {
$http.get('/contactlist').success(function(response) {
console.log("I got the data I requested");
$scope.contactlist = response;
$scope.contact = "";
});
};
refresh();
$scope.addContact = function() {
console.log($scope.contact);
$http.post('/contactlist', $scope.contact).success(function(response) {
console.log(response);
refresh();
});
};
$scope.remove = function(id) {
console.log(id);
$http.delete('/contactlist/' + id).success(function(response) {
refresh();
});
};
$scope.edit = function(id) {
console.log(id);
$http.get('/contactlist/' + id).success(function(response) {
$scope.contact = response;
});
};
$scope.update = function() {
console.log($scope.contact._id);
$http.put('/contactlist/' + $scope.contact._id, $scope.contact).success(function(response) {
refresh();
})
};
$scope.deselect = function() {
$scope.contact = "";
}
}
]);
You may use this to insert data in your local Mongo -
db.contactlist.insert({"runId" : "1212","apiName" : "transactions","runTime" : "DateAndTime","Report" : "URL","numOfTestExecuted" : "3","numOfTestFailed" : "3","status" : "Passed"})
It would be cool, if you can tell me whats not working in your example, perhaps it would be better to drill down your problems a bit into three issues:
Sorting, Paging and Filtering.
Create a example for each of it and try to implement it and then ask the direct question what is not working.
-> because each of the problems could be solved independently and then its easier for you to understand how the hole thing works together.
you could create a stand alone directive for each of your Problems.

Custom validation plugin fails with multiple table rows

Trying to self create a validation that compares Gross and Tare values in the table using jQuery validation plugin. Tare should always be smaller than Gross.
Here is the JS code:
$.validator.addMethod('lessThan', function (value, element, param) {
if (this.optional(element)) return true;
var i = parseInt(value);
var j = parseInt($(param).val());
return i <= j;
}, "Tare must less than Gross");
$('#myForm').validate({rules: {tare: {lessThan: ".gross"}}});
And my HTML:
<form id="myForm">
<table id="lineItemTable">
<thead>
<th>
<tr>
<td>Gross</td>
<td>Tare</td>
</tr>
</th>
</thead>
<tbody>
<tr>
<td><input type="text" name='gross' class="gross"/></td>
<td><input type="text" name='tare' class="tare"/></td>
</tr>
<tr>
<td><input type="text" name='gross' class="gross"/></td>
<td><input type="text" name='tare' class="tare"/></td>
</tr>
</tbody>
</table>
</form>
This code works fine when only have one row involved.
When comes two table rows, it compares the 2nd row tare value with the 1st row gross value. Apparently I want it to compare 2nd row tare value with 2nd row gross value. Also for some reason the error message shows up at the 1st row.
Here is one screen shot:
Please advise how do I change my code to make it working properly.
And here is the CDN that I am using:
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
Looking for $('.gross').val() will always retrieve the value of the first matched element (in the whole document).
Instead, look only in the row containing the element being validated:
var j = parseInt($(element).closest('tr').find(param).val());
$.validator.addMethod('lessThan', function(value, element, param) {
console.log(element);
if (this.optional(element)) return true;
var i = parseInt(value);
var j = parseInt($(element).closest('tr').find(param).val());
return i <= j;
}, "Tare must less than Gross");
$('#myForm').validate({
rules: {
tare: {
lessThan: ".gross"
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.14.0/jquery.validate.min.js"></script>
<form id="myForm">
<table id="lineItemTable">
<thead>
<th>
<tr>
<td>Gross</td>
<td>Tare</td>
</tr>
</th>
</thead>
<tbody>
<tr>
<td>
<input type="text" name='gross' class="gross" />
</td>
<td>
<input type="text" name='tare' class="tare" />
</td>
</tr>
<tr>
<td>
<input type="text" name='gross' class="gross" />
</td>
<td>
<input type="text" name='tare' class="tare" />
</td>
</tr>
</tbody>
</table>
</form>

AngularJS: post data to server

I want to add data to my database using AngularJS. First I have to choose a category from a list of categories which I get from my server. After that a user can add a product to the database. I tried accomplishing this using:
AngularJS
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
$scope.product = function($scope, $http, $catID){
$http.post(serviceBase + 'productadd/3/1/Icetealemon/5').then(function(results){
});
}
});
});
HTML
<table id="app2" ng-app="categories" ng-cloak="" class="table table-hover">
<tr >
<th colspan="5">Add product</th>
</tr>
<tr ng-form name="addproductForm" novalidate ng-controller="category">
<td colspan="1">
<select class="form-control m-b-10">
<option ng-repeat= "c in categories">{{c.categoryName}}</option>
</select>
</td>
<td colspan="1">
<select class="form-control m-b-10">
<option>Antwerpen</option>
<option>Leuven</option>
</select>
</td>
<td colspan="1">
<input type="text" class="form-control" placeholder="Name" ng-model="catID"></input>
</td>
<td colspan="1">
<input type="text" class="form-control" placeholder="Price" width="10%"></input>
</td>
<td colspan="1">
<input type="submit" class="btn btn-success" ng-click="product()"></input>
</td>
</tr>
</table>
I am not even using the ng-models to use the data of my html. It's still hard coded because it doesn't even work then. I am getting en error:
TypeError: Cannot read property 'post' of undefined
What am i doing wrong with my $http.post?
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
$scope.product = function($scope, $http, $catID){
// NOTE: This '$http' is $scope.product function parameter
// variable `$http` not angular '$http'
$http.post(serviceBase + 'productadd/3/1/Icetealemon/5').then(function(results){
});
}
});
});
Remove $http parameter from $scope.product function.
Also, look at https://docs.angularjs.org/tutorial/step_05 about angular dependency issue during minification and how to solve it.

Add/remove input boxes to the table row in Angular dynamically

Somehow I can't get my head around this in angular- I have a Table and want to add the row on-click, but this row should have empty input boxes and a button to remove itself.
<tbody>
<tr>
<th>Test 1</th>
<th>200</th>
<th>Add new row</th>
</tr>
//I want to Add this part dynamically everytime when I click on Add new row
<tr>
<td>
<input type="text" placeholder="Please Enter the Address">
</td>
<td>
<input type="text" placeholder="Number of Quantity">
</td>
//On Delete it should delete just that particular row
<td>Delete</td>
</tr>
</tbody>
I have created plunker http://plnkr.co/edit/DDj5Z99tw1QuN8xlxZ7V?p=preview just for showing what I am trying to achieve. If anyone would be able to give a hint or link me to tutorial would be great!
Please have look at this plunker.
http://plnkr.co/edit/ogvezWz6WDwDhCnm2bDU
Idea is to use a row at the end whose visibility can be controlled. And using ngRepeat you can iteratively display your added product items.
<tr ng-repeat="row in rows">
<td>
{{row.product}}
</td>
<td>
{{row.quantity}}
</td>
<td>
<button ng-click="deleteRow($index)">Delete</button>
<button ng-click="addNewRow()">New</button>
</td>
</tr>
<tr ng-show="addrow">
<td>
<input type="text" placeholder="Please Enter the Address" ng-model="product"/>
</td>
<td>
<input type="text" placeholder="Number of Quantity" ng-model="quantity"/>
</td>
<td><button ng-click="save()">Save</button> <button ng-click="delete()">Delete</button></td>
</tr>
And the Controller code
angular.module('AddRow', [])
.controller('MainCtrl', [
'$scope', function($scope){
$scope.rows = [ { "product": "Test 1", "quantity": "200"}];
$scope.addrow = false;
$scope.addNewRow = function(){
$scope.addrow = true;
};
$scope.deleteRow = function(index){
//delete item from array
$scope.rows.splice(index,1);
};
$scope.save = function(){
//add item to array
$scope.rows.push({"product": $scope.product, "quantity": $scope.quantity});
//reset text input values
$scope.product = "";
$scope.quantity = "";
//hide the add new row
$scope.addrow = false;
};
$scope.delete = function(){
$scope.addrow = false;
};
}]);

Categories

Resources