so I'm new to Angular and JS and I've been trying to do something simple with no success.
I have a table with data, everytime this data gets changed I want to make a fade in fade out animation so it blinks. I assumed I could use $watch to watch if an element changes but it's not working.
This is what I got so far:
HTML:
<tbody md-body>
<tr md-row ng-repeat="item in info.data">
<td md-cell>{{item.name}}</td>
<td md-cell>{{item.id}}</td>
<td md-cell>{{item.thing2}}</td>
<td md-cell>{{item.thing3}}</td>
<td md-cell>{{item.thing4}}</td>
<td md-cell>{{item.thing5}}</td>
</tr>
</tbody>
JS:
$scope.info = {
"data": [
{
name: "ELI 0001",
id: "123",
thing1: "thing",
thing2: "thing",
thing3: "thing",
thing4: "thing",
thing5:"thing",
},
{
name: "ELI 0001",
id: "123",
thing1: "thing",
thing2: "thing",
thing3: "thing",
thing4: "thing",
thing5:"thing",
},
]
};
I added this function to watch the entire data set for changes, and when it does I made an alert. I also added the var initialising so it doesn't show up as soon as it loads.
var initializing = true
$scope.$watch('if',function(){
if (initializing) {
$timeout(function() { initializing = false; });
} else {
alert('hey')
}
})
My problem is, how can I get it to watch all cells and execute a class that does the animation only on the data that changed?
AS this thread https://groups.google.com/forum/#!msg/angular/xZptsb-NYc4/rKAxJ3dQhbMJ, what I ended up doing was this:
app.directive('highlightOnChange', function() {
return {
link: function($scope, element, attrs) {
attrs.$observe('highlightOnChange', function(val) {
var el = $(element);
el.removeClass('blink_me ');
_.defer(function() {
el.addClass('blink_me ')
});
});
}
};
});
That is, creating a directive observes the property. You can then use it like this:
<td md-cell highlight-on-change="{{item.name}}"></td>
...
suppose your css class be:
.blink_me {
animation: blinker 1s linear infinite;
}
#keyframes blinker {
50% {
opacity: 0;
}
}
I was working on a similar approach to #khateeb -- except I am using a $watch on the element's ng-model instead of using $observe on the directive attribute. Both work!
Plunker: https://embed.plnkr.co/rZVjPmDft997Kmny1LS4/
Snippet:
(function() {
"use strict";
var app = angular
.module('plunker', [])
.controller('MainCtrl', MainCtrl)
.directive('flashTd', flashTD);
function flashTD($timeout, $compile) {
return {
scope: {
ngModel: '='
},
link: function($scope, elem, attrs) {
// Set a watch on ng-model to wait for value change
$scope.$watch('ngModel', function(newVal, oldVal) {
if (newVal !== oldVal) {
// Flash row
// var row = angular.element(elem[0].parentNode.parentNode);
// Flash td
var td = angular.element(elem[0].parentNode);
// Using a timeout to simulate remote data change
$timeout(function() {
if (td.hasClass('flash')) {
td.removeClass('flash');
}
$timeout(function() {
td.addClass('flash')
})
}, 2000)
}
})
}
}
}
MainCtrl.$inject = ["$scope"];
function MainCtrl($scope) {
// Sample Data
$scope.info = {
"data": [{
name: "ELI 0001",
id: "123",
thing1: "thing",
thing2: "thing",
thing3: "thing",
thing4: "thing",
thing5: "thing",
}, {
name: "ELI 0001",
id: "1234",
thing1: "thing",
thing2: "thing",
thing3: "thing",
thing4: "thing",
thing5: "thing",
}]
};
}
})()
.editPencil:hover {
cursor: pointer;
}
/* https://stackoverflow.com/questions/14607695/flashing-table-row */
#keyframes flash {
from {
background-color: #ffbe76;
}
to {
background-color: inherit;
}
}
.flash {
animation: flash 1s 1;
}
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS - Flash TD on Change</title>
<link data-require="bootstrap#3.3.7" data-semver="3.3.7" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script data-require="bootstrap#3.3.7" data-semver="3.3.7" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="jumbotron text-center">
<h3>AngularJS - Flash TD on Change</h3>
</div>
</div>
<div class="col-xs-12 col-sm-12 col-md-12">
<form class="form">
<div class="form-group">
<table class="table">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>Id</th>
<th>Thing1</th>
<th>Thing2</th>
<th>Thing3</th>
<th>Thing4</th>
<th>Thing5</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="item in info.data">
<td class="editPencil glyphicon-pencil text-center" style="transform: rotate(45deg)" ng-click="editRow = !editRow"></td>
<td>
<span ng-hide="editRow">{{ item.name }}</span>
<input type="text" class="input-sm" ng-model="item.name" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.id }}</span>
<input type="text" class="input-sm" ng-model="item.id" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.thing1 }}</span>
<input type="text" class="input-sm" ng-model="item.thing1" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.thing2 }}</span>
<input type="text" class="input-sm" ng-model="item.thing2" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.thing3 }}</span>
<input type="text" class="input-sm" ng-model="item.thing3" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.thing4 }}</span>
<input type="text" class="input-sm" ng-model="item.thing4" ng-hide="!editRow" flash-td />
</td>
<td>
<span ng-hide="editRow">{{ item.thing5 }}</span>
<input type="text" class="input-sm" ng-model="item.thing5" ng-hide="!editRow" flash-td />
</td>
</tr>
</tbody>
</table>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Directive
In my demo, I'm flashing the td, but you can as easily change it to flash the target's table row by using the commented-out row variable instead of the td variable.
app.directive('flashTd', flashTD);
function flashTD($timeout, $compile) {
return {
scope: {
ngModel: '='
},
link: function($scope, elem, attrs) {
// Set a watch on ng-model to wait for value change
$scope.$watch('ngModel', function(newVal, oldVal) {
if (newVal !== oldVal) {
// Flash row
// var row = angular.element(elem[0].parentNode.parentNode);
// Flash td
var td = angular.element(elem[0].parentNode);
// Using a timeout to simulate remote data change
$timeout(function() {
if(td.hasClass('flash')) {
td.removeClass('flash');
}
$timeout(function() {
td.addClass('flash')
})
}, 2000)
}
})
}
}
}
HTML Element
<input type="text" class="input-sm" ng-model="item.thing2" ng-hide="!editRow" flash-td />
Related
Consider I have a list of objects like -
var configs = [{
id: "1",
name: "config1"
},
{
id: "2",
name: "config2"
}
];
I use the following to search through the config list and bind the selected config to another variable called changed_config.
<table style="width:900px;">
<tr>
<th style="width:500px; margin:50px">Config Name</th>
<th style="width:150px;">Config Value</th>
</tr>
<tr ng-repeat="changed_config in changed_configs">
<td>
<input type="text" class="form-control" ng-model="changed_config.id" list="names">
<datalist id="names">
<option ng-repeat="option in configs | filter:search | limitTo:30" ng-value="option.name"> {{option.name}}
</option>
</datalist>
<td>
<input type="text" class="form-control" ng-model="changed_config.value">
</td>
</tr>
</table>
<div class="row">
<button type="button" id="add-reward-grp-btn" ng-click="addConfig()"
class="btn btn-primary">Add Config
</button>
</div>
Controller Code(Not complete code, just relevant snippets):
var app = angular.module("drs_scheduler_app", []);
app.controller("CreateSchedulerJob", function ($scope, $http) {
$scope.changed_configs = [];
$scope.configs = [{
id: "1",
name: "config1"
},
{
id: "2",
name: "config2"
}
];
$scope.addConfig = function () {
var config = {
"id": "",
"value": ""
};
$scope.changed_configs.push(config);
console.log(config);
console.log(JSON.stringify($scope.changed_configs));
}
}
Currently the code displays and binds the name of the selected config to the changed_config variable. But I need the id to be bound to the changed_config variable and the name to be displayed in the html.
If I change the <option> to use id, then id will be displayed.
How do I bind one property to a variable but show another in the html??
Here is the solution you needed,
Procedure:
When an option is selected from datalist I m checking for that
change
That change is observed through input on which datalist is added
On that input change i,e when option is selected I m assigning that
id to id key of respective changed_config
That is inturn displayed in second textbox
It works for dynamic
// Code goes here
function cntryController($scope) {
$scope.LoadSessionData=function(val)
{
console.log(val);
};
$scope.changed_configs = [];
$scope.configs = [{
id: "1",
name: "config1"
},
{
id: "2",
name: "config2"
}
];
$scope.addConfig = function () {
var config = {
"id": "",
"value": ""
};
$scope.changed_configs.push(config);
console.log(config);
console.log(JSON.stringify($scope.changed_configs));
}
$scope.test = function(data, index){
console.log(data)
var newArray = $scope.configs.filter(function (config) {
return config.name == data;
});
console.log(newArray)
if(newArray.length){
var new_changed_config = $scope.changed_configs[index];
new_changed_config.id = newArray[0].id;
}
}
}
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<div ng-app="" ng-controller="cntryController">
<table cellspacing="10" cellpadding="10">
<tr>
<th>Config Name</th>
<th>Config Value</th>
</tr>
<tr ng-repeat="changed_config in changed_configs">
<td>
<input type="text" class="form-control" ng-model="changed_config.name" list="names" ng-change="test(changed_config.name, $index)">
<datalist id="names">
<option ng-repeat="option in configs | filter:search | limitTo:30" value={{option.name}}>{{option.name}}
</option>
</datalist>
</td>
<td>
<input type="text" class="form-control" ng-model="changed_config.id"/>
</td>
</tr>
</table>
<div class="row">
<button type="button" id="add-reward-grp-btn" ng-click="addConfig()" class="btn btn-primary">Add Config</button>
</div>
</div>
</html>
Please run the above snippet
Here is a working DEMO
I am new to angular coming from the Knockout world. I have hooked into a key-press event for tab in order to add a new in the last cell in the table.
My issue is that the focus then goes into information icon in the uri bar rather then next cell in the newly created row. I am sure the fix is simple I just can not find the solution, Can anyone help?
I am using Angularjs v1.59
var myApp = angular.module('myApp', []);
myApp
.factory('shippingItems', function () {
return {
data: [{
quantity: 1,
width: 1,
height: 1,
length: 1,
weight: 1,
details: 1
},
{
quantity: 2,
width: 2,
height: 2,
length: 2,
weight: 2,
details: 2
},
{
quantity: 3,
width: 3,
height: 3,
length: 3,
weight: 3,
details: 3
}]
};
})
.controller("userCtrl", ['$scope', 'shippingItems', function ($scope, shippingItems) {
$scope.shippingItems = shippingItems.data;
}])
.directive("myTab", ['shippingItems', function (shippingItems) {
return {
link: function (scope, element, attrs) {
scope.index = attrs.indexTracker;
element.bind("keydown keypress", function (event) {
if (scope.index == (shippingItems.data.length-1)) {
if (event.which === 9) {
var newItem = {
quantity: null,
width: null,
height: null,
length: null,
weight: null,
details: null
};
shippingItems.data.push(newItem);
element.next().focus();
}
}
});
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="userCtrl">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">lol</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Quantity</th>
<th>Width x Height x Length (cm)</th>
<th>Weight Per Item</th>
<th>Total Weight</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr class="table-input" ng-repeat="item in shippingItems">
<td><input type="text" ng-model="item.quantity" /></td>
<td><input type="text" ng-model="item.width" /> x <input type="text" ng-model="item.height" /> x <input type="text" ng-model="item.length" /></td>
<td><input type="text" ng-model="item.weight" />kg</td>
<td>{{ (item.weight|number) * (item.quantity|number)}}kg</td>
<td my-tab="checking" index-tracker="{{$index}}"><input type="text" ng-model="item.details" /></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
You don't need directive actually what you want is a service however in this sample you can see how to use angular.element with passing $event from your last input in li OR td.
var app = angular.module("app", []);
app.controller("ctrl", function($scope, $timeout) {
$scope.ul = [{}, {}, {}]
$scope.callService = function(event, index) {
if (event.keyCode === 13) {
var nextInext = index + 1;
if (angular.isUndefined($scope.ul[nextInext])) {
$scope.ul.push({});
}
$timeout(function() {
angular.element(event.target).closest(".parent").find(".child-" + nextInext + " input").select();
})
}
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<h5>auto focus on next input, auto push [press Enter on inputs]</h5>
<ol class="parent">
<li ng-repeat="li in ul" class="child-{{$index}}">
<input type="text" ng-keydown="callService($event, $index)" ng-model="li.input" />
</li>
</ol>
</div>
var myApp = angular.module('myApp', []);
myApp
.factory('shippingItems', function () {
return {
data: [{
quantity: 1,
width: 1,
height: 1,
length: 1,
weight: 1,
details: 1
},
{
quantity: 2,
width: 2,
height: 2,
length: 2,
weight: 2,
details: 2
},
{
quantity: 3,
width: 3,
height: 3,
length: 3,
weight: 3,
details: 3
}]
};
})
.controller("userCtrl", ['$scope', 'shippingItems', function ($scope, shippingItems) {
$scope.shippingItems = shippingItems.data;
}])
.directive("myTab", ['shippingItems', function (shippingItems,$timeout) {
console.log('CALLED')
return {
link: function (scope, element, attrs) {
element.bind("keydown", function (event) {
event.preventDefault();
scope.index = attrs.indexTracker;
if (scope.index == (shippingItems.data.length-1)) {
//if (event.keyCode === 81 && event.altKey) {
if (event.keyCode === 9) {
var newItem = {
quantity: null,
width: null,
height: null,
length: null,
weight: null,
details: null
};
shippingItems.data.push(newItem);
setTimeout(function(){
var tr_dom = element[0].closest('tr').nextElementSibling
var input = element[0].closest('tr').nextElementSibling.querySelector('input')
input.focus()
},10);
scope.$apply()
}
}
});
}
}
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="userCtrl">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">lol</h3>
</div>
<div class="panel-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Quantity</th>
<th>Width x Height x Length (cm)</th>
<th>Weight Per Item</th>
<th>Total Weight</th>
<th>Details</th>
</tr>
</thead>
<tbody>
<tr class="table-input" ng-repeat="item in shippingItems">
<td><input type="text" ng-model="item.quantity"/></td>
<td><input type="text" ng-model="item.width" /> x <input type="text" ng-model="item.height" /> x <input type="text" ng-model="item.length" /></td>
<td><input type="text" ng-model="item.weight" />kg</td>
<td>{{ (item.weight|number) * (item.quantity|number)}}kg</td>
<td ><input type="text" index-tracker="{{$index}}" ng-model="item.details" my-tab="checking"/></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
It is my code for angular js and html.Please help me about this.why it is not working with file if any error in syntax in html file or angular file?
I am trying to make a order table and I am doing it using angular js method and every time when I runs it on browser the Angular code is not working and Add button is also not working for me which is used to add the more entities in order.
angular.module('Commande', [])
.controller('commandeController', ['$scope', function($scope) {
$scope.articles = [
{ id: 1, reference: 123, titre: "MSI GTX 980ti", prixUnitaire: 666.63, quantite: 0, montantHT: 666.63, montantTTC: 799.95 },
{ id: 2, reference: 456, titre: "Intel Core i7-4770K", prixUnitaire: 324.96, quantite: 0, montantHT: 324.96, montantTTC: 389.95 },
{ id: 3, reference: 789, titre: "ASUS MAXIMUS VII RANGER", prixUnitaire: 134.96, quantite: 0, montantHT: 134.96, montantTTC: 161.95 }
];
$scope.PrixTotalTTC = function() {
var resultTTC = 0;
angular.forEach($scope.articles, function (article) {
resultTTC += article.montantTTC * article.quantite;
});
return resultTTC;
};
$scope.PrixTotalHT = function() {
var resultHT = 0;
angular.forEach($scope.articles, function (article) {
resultHT += article.montantHT * article.quantite;
});
return resultHT;
};
$scope.NombreArticle = function() {
var resultArticle = 0;
angular.forEach($scope.articles, function(article){
resultArticle += article.quantite;
});
return resultArticle;
};
$scope.AjouterArticle = function() {
$scope.articles.push({
id: '',
reference: '',
titre: '',
prixUnitaire: 0,
quantite: 0,
montantHT: 0,
montantTTC: 0
});
};
$scope.SupprimerArticle = function(index) {
$scope.articles.splice(index, 1);
};
}]);
<html lang="en-us">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<script src="//code.angularjs.org/1.6.6/angular.min.js">
</script>
<script src="app.js"></script>
</head>
<body ng-app="Commande" ng-controller="commandeController">
<h1>Bon de commande</h1>
<div class="content">
<div class="col-md-12">
<table class="table table-striped table-hover table-responsive">
<thead>
<tr>
<th>#</th>
<th>Référence</th>
<th>Titre</th>
<th>Prix unitaire HT/€</th>
<th>Quantité</th>
<th>Montant HT/€</th>
<th>Montant TTC/€</th>
<th>Supprimer</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="article in articles">
<th>
<input type="number" ng-model="article.id" class="form-control bfh-number" placeholder="Id" min=0>
</th>
<td>
<input type="number" ng-model="article.reference" class="form-control bfh-number" placeholder="Référence" min=0>
</td>
<td>
<input type="text" ng-model="article.titre" class="form-control" placeholder="Titre">
</td>
<td>
<input type="number" ng-model="article.prixUnitaire" class="form-control bfh-number">
</td>
<td>
<input type="number" ng-model="article.quantite" class="form-control bfh-number" min=0>
</td>
<td>
<input type="number" ng-model="article.montantHT" class="form-control bfh-number" min=0>
</td>
<td>
<input type="number" ng-model="article.montantTTC" class="form-control bfh-number" min=0>
</td>
<td>
<a href ng:click="SupprimerArticle($index)"><i class="fa fa-times delete"></i></a>
</td>
</tr>
<tr class="success">
<th class="success">TOTAL</th>
<td class="success"></td>
<td class="success"></td>
<td class="success"></td>
<td class="success">{{ NombreArticle() }} article(s)</td>
<td class="success" ng-style="PrixTotalHT() >= 1000 && {'font-weight': 'bold'}">{{ PrixTotalHT() | number:2 }} €</td>
<td class="success" ng-style="PrixTotalHT() >= 1000 && {'font-weight': 'bold'}">{{ PrixTotalTTC() | number:2 }} €</td>
<td class="success"></td>
</tr>
</tbody>
</table>
<a href ng:click="AjouterArticle()" class="btn btn-primary">Ajouter un article <i class="fa fa-plus"></i></a>
</div>
</div>
</body>
</html>
It is my code.
Sounds like you need a content management system (CMS), such as MAMP, XAMPP or similar. You basically need to run a local server for JavaScript code to work (as well as any PHP you might use). Simple solution, if just need JavaScript, is to use Node.js.
I want to print the values of a array based on the checkbox associated with it. Find the code below
Javascript:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= [{name:"John",selected:"false"},{name:"Anil",selected:"false"},{name:"Kumar",selected:"false"}];
$scope.lastName= "Doe";
$scope.name1=[],
$scope.addname=function(){
angular.forEach($scope.firstName, function(name,selected){
if(selected=="true") {
alert(name);
$scope.name1.push(name)
}
});
}
});
html:
<div ng-app="myApp" ng-controller="myCtrl">
<table >
<tr ng-repeat="first in firstName">
<td><input type="Checkbox" ng-model="first.selected">{{first.name}}</td>
</tr>
<tr><td><input type="Button" ng-click="addname()" value="Submit" ng-model="lastName"></td></tr>
<tr ng-repeat="nam in name1">{{nam}}</tr>
</table>
</div>
Keep selected value as Boolean than String
In forEach, first argument is Object, access the model associated with it using name.selected
Initialize name1 array in ng-click handler
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName = [{
name: "John",
selected: false
}, {
name: "Anil",
selected: false
}, {
name: "Kumar",
selected: false
}];
$scope.lastName = "Doe";
$scope.addname = function() {
$scope.name1 = [];
angular.forEach($scope.firstName, function(name, selected) {
if (name.selected) {
$scope.name1.push(name)
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table>
<tr ng-repeat="first in firstName">
<td>
<input type="Checkbox" ng-model="first.selected">{{first.name}}</td>
</tr>
<tr>
<td>
<input type="Button" ng-click="addname()" value="Submit" ng-model="lastName">
</td>
</tr>
<tr ng-repeat="nam in name1">{{nam}}</tr>
</table>
{{name1}}
</div>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.firstName= [{name:"John",selected:false},{name:"Anil",selected:false},{name:"Kumar",selected:false}];
$scope.lastName= "Doe";
$scope.name1=[];
$scope.addname=function(){
angular.forEach($scope.firstName, function(name){
if(name.selected === "true") {
$scope.name1.push(name);
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<table >
<tr ng-repeat="first in firstName">
<td><input type="Checkbox" ng-model="first.selected" ng-true-value="true" >{{first.name}}</td>
</tr>
<tr><td><input type="Button" ng-click="addname()" value="Submit" ng-model="lastName"></td></tr>
<tr ng-repeat="nam in name1"><td>{{nam}}</td></tr>
</table>
</div>
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.