I am developing an Web Application using Angular JS. I am a beginner to AngularJS. In my app, I need to dynamically add and remove elements. I use directive for it. Adding and removing elements is working fine. But I am having a problem with retrieving each model value of added inputs.
My scenario is below.
This is my app
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angularjs popup</title>
<link href="http://localhost:8888/angular/bootstrap.css" rel="stylesheet">
<script src="http://localhost:8888/angular/angular-js.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller='myCtrl'>
<div>
<button class="btn btn-success" ng-click="addRow()">Add row</button>
<hr />
<div id="rowsContainer">
</div>
<button class="btn btn-primary" ng-click="submitForm()">Submit</button>
</div>
</div>
</body>
<script type="text/javascript">
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($rootScope,$scope,$compile){
$rootScope.getContacts = function()
{
var list = [{contactId: 1,contactType: 'Mobile'} , {contactId: 2,contactType: 'Office'} , {contactId: 3,contactType: 'Home'}];
return list;
}
$scope.contactType = [];
$scope.contactValue = [];
$scope.submitForm = function(){
alert($scope.contactType)
//I want to retrieve ContactValue and ContactType here. All values by looping throgh
};
$scope.addRow = function() {
var divElement = angular.element(document.querySelector('#rowsContainer'));
var appendHtml = $compile('<dynamic-Row contact-type="contactType"></dynamic-Row>')($scope);
divElement.append(appendHtml);
}
});
app.directive('dynamicRow', function() {
return {
restrict: "E",
scope: {
contactType: "=contactType",
contactValue : "=contactValue"
},
templateUrl:'http://localhost:8888/angular/dynamic/row.html',
controller: function($rootScope, $scope, $element) {
$scope.contacts = $rootScope.getContacts();
$s
cope.contactType.push($scope.contact_type)
$scope.contactValue.push($scope.contact_value)
$scope.deleteRow = function(e){
$element.remove();
$scope.$destroy();
}
}
}
});
</script>
</html>
I commented what I want to do in the above code.
this is the row.html
<div class="row">
<div class="col-md-5">
<select name="ContactType" class="form-control" ng-model="contact_type" >
<option ng-repeat="contact in contacts" value="{{contact.contactId}}"> {{contact.contactType}} </option>
</select>
</div>
<div class="col-md-5">
<input ng-model="contact_value" class="form-control">
</div>
<div class="col-md-2">
<button ng-click="deleteRow($event)" class="btn btn-danger">X</button>
</div>
</div>
How can I get the each value of all dynamically added input controls in submitForm function?
Here is the answer based on the requirement,
You Isolated the scope using scope: {}, so you cannot access those model values.
Try to bind the scope,
scope: {
contact_type: "=contact_type"
contact_value: "=contact_value"
}
Controller and Directive,
var app = angular.module('myApp',[]);
app.controller('myCtrl',function($rootScope,$scope,$compile){
$rootScope.getContacts = function()
{
var list = [{contactId: 1,contactType: 'Mobile'} , {contactId: 2,contactType: 'Office'} , {contactId: 3,contactType: 'Home'}];
return list;
}
$scope.contactType = [];
$scope.contactValue = [];
$scope.submitForm = function(){
alert($scope.contactType)
//I want to retrieve ContactValue and ContactType here. All values by looping throgh
};
$scope.addRow = function() {
var divElement = angular.element(document.querySelector('#rowsContainer'));
var appendHtml = $compile('<dynamic-Row contact-type="contactType" contact-value="contactValue"></dynamic-Row>')($scope);
divElement.append(appendHtml);
}
});
app.directive('dynamicRow', function() {
return {
restrict: "E",
scope: {
contactType: "=contactType",
contactValue : "=contactValue"
},
templateUrl:'row.html',
controller: function($rootScope, $scope, $element) {
console.log($scope.contactType)
$scope.contacts = $rootScope.getContacts();
// $s
$scope.update = function()
{
$scope.contactType.push($scope.contact_selected)
}
$scope.contactValue.push($scope.contact_value_selected)
$scope.deleteRow = function(e){
$element.remove();
$scope.$destroy();
}
}
}
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Angularjs popup</title>
<!-- <link href="http://localhost:8888/angular/bootstrap.css" rel="stylesheet"> -->
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
</head>
<body>
<div ng-app="myApp" ng-controller='myCtrl'>
<div>
<button class="btn btn-success" ng-click="addRow()">Add row</button>
<hr />
<div id="rowsContainer">
</div>
<button class="btn btn-primary" ng-click="submitForm()">Submit</button>
</div>
</div>
</body>
</html>
Here is your row.html,
<div class="row">
<div class="col-md-5">
<select name="ContactType" class="form-control" ng-model="contact_selected" ng-change="update()">
<option ng-repeat="contact in contacts" value="{{contact.contactId}}"> {{contact.contactType}} </option>
</select>
</div>
<div class="col-md-5">
<input ng-model="contact_value_selected" class="form-control">
</div>
<div class="col-md-2">
<button ng-click="deleteRow($event)" class="btn btn-danger">X</button>
</div>
</div>
Related
Please find my my controller javascript file below -
angular.module('myApp', []);
angular.module('myApp').factory('myFactory', function () {
var myFactory = {};
myFactory.list = [];
myFactory.add = function (message) {
myFactory.list.push({ id: myFactory.list.length, text: message });
//return myFactory;
};
return myFactory;
});
angular.module('myApp').controller('Controller1', function (myFactory) {
var myVar = this;
myVar.myList = myFactory.List;
});
angular.module('myApp').controller('Controller2', function (myFactory) {
var myVar = this;
myVar.newMessage = 'Hello World!';
myVar.addMessage = function (message) {
myFactory.add(message);
myVar.newMessage = '';
};
});
And also my HTML file below -
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body ng-app="myApp">
<div>
<h1>Services</h1>
<div' ng-controller="Controller1">
<p ng-repeat="m in myList">{{ m.id }}: {{ m.text }}</p>
</div'>
</div>
<div ng-controller="Controller2 as post">
<form ng-submit="post.addMessage(post.newMessage)">
<input type="text" ng-model="post.newMessage">
<button type="submit"
ng-click="post.addMessage(post.newMessage)">
Add Message
</button>
</form>
</div>
</body>
</html>
<script src="Scripts/angular.min.js"></script>
<script src="Scripts/bootstrap.min.js"></script>
<script src="Scripts/angular.js"></script>
I can't see the data returning by the 'Controller1'
When I run the code I can't see the result which is coming from Controller1, which means the list is not binding with the ng-controller in .html page
Please tell me where I am wrong.
You are not referencing your list properly:
<p ng-repeat="m in myList">{{ m.id }}: {{ m.text }}</p>
If you are going to use myVar to store your list, you should use Controller as syntax so that your template has a reference to the variable:
<div ng-controller="Controller1 as myVar">
<p ng-repeat="m in myVar.myList">{{ m.id }}: {{ m.text }}</p>
</div>
I have a problem with custom defined directive - which uploads file - in AngularJS when using with ngRoute and ngView. It works well when section with <input>field is in home.html, but when I put it to loaddata.html it doesn't work (as below), despite the fact that functions loadtrans() and uploadF() work - $scope.file is null. How can I fix it?
directive:
app.directive('uploadFile', function($parse){
return {
restrict: 'A',
link: function(scope,element,attrs){
var model = $parse(attrs.uploadFile),
modelSetter= model.assign;
element.bind('change', function(){
scope.$apply(function (){
modelSetter(scope,element[0].files[0]);
});
});
}
}
});
home.html
<!DOCTYPE html>
<html lang="en" ng-app="app">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link href="webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body ng-controller="AppCtrl">
<nav>
<ul class="nav nav-tabs">
<li role="presentation" class="active"><a href="#" data-toggle="tab" >GPW</a></li>
<li role="presentation" ><a href="#!/stocks" data-toggle="tab" >Load data</a></li>
<li role="presentation" ><a href="#!/chart" data-toggle="tab" >Chart</a></li>
</ul>
</nav>
<div class="row">
<div class="col-md-3">
<button class="button btn-block btn-primary" ng-click="getData()">
GetData()
</button>
<input type="number" ng-model="dayFrom"/>
</div>
<div class="col-md-3">
<a class="button btn-block btn-primary" href="/new-wallet.html"> <button class="button btn-block btn-primary">
Create your wallet
</button></a>
</div>
</div>
<div ng-view></div>
<script src="webjars/jquery/3.1.1-1/jquery.min.js" type="application/javascript"></script>
<script src="webjars/angularjs/1.6.0/angular.min.js" type="application/javascript"></script>
<script src="webjars/angularjs/1.6.0/angular-resource.min.js" type="application/javascript"></script>
<script src="webjars/moment/2.17.1/moment.js" type="application/javascript"></script>
<script src="webjars/Chart.js/2.3.0/dist/Chart.js" type="application/javascript"></script>
<script src="webjars/angular-chart.js/1.1.1/dist/angular-chart.js" type="application/javascript"></script>
<script src="webjars/angular-route/1.6.0/angular-route.js" type="application/javascript"></script>
<script src="js/app.js" type="application/javascript"></script>
</body>
</html>
loaddata.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div class="row">
<div class="col-md-4 col-md-offset-4">
<button class="btn btn-block btn-primary btn-lg" ng-click="loadTrans()">
Load your transactions()
</button>
<div ng-show='filefield' >
<!-- <label class="btn btn-default">-->
Browse..
<input type="file" upload-file="file" >
<!-- </label>-->
<button class="btn btn-default " ng-click="uploadF()">
Submit
</button>
</div>
</div>
</div>
</body>
</html>
Functions:
$scope.loadTrans=function(){
$scope.filefield=true;
}
$scope.uploadF=function(){
console.log("upload");
console.log($scope.file);
var fileFormData = new FormData();
fileFormData.append('file', $scope.file);
console.log($scope.file);
$http.post("http://localhost:8080/loadfile", fileFormData, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}})
.then(function(data){
var t = angular.fromJson(data.data.trans);
for (var key in t)
{
for(var k in t[key])
{
$scope.labels.push(k);
$scope.data.push(t[key][k]);
}
}
$scope.chartDataService.status = 'Done';
console.log($scope.data);
$scope.chartDataService.data = $scope.data;
$scope.profit = data.data.success;
$scope.trans = data.data.trans;
$scope.uploadSuccess=true;
$scope.time = moment().fromNow();
},
function(status){
console.log('errors');
});
};
EDIT:
Modified directive which work:
app.directive('uploadFile', function($parse){
return {
restrict: 'A',
scope:false,
link: function(scope,element,attrs){
var model = $parse(attrs.uploadFile),
modelSetter= model.assign;
console.log("directive");
console.log(model);
element.bind('change', function(){
scope.$apply(function (){
modelSetter(scope.$parent,element[0].files[0]);
console.log(element[0].files[0]);
});
});
}
}
});
But as I assume it is not universal solution.. eg. when I use this directive not within ng-view.
EDIT2:
I solved this problem as below. If you have any better solutions, please share with me.
app.directive('uploadFile', function($parse){
return {
restrict: 'A',
link: function(scope,element,attrs){
var model = $parse(attrs.uploadFile),
modelSetter= model.assign;
console.log("directive");
console.log(model);
element.bind('change', function(){
scope.$apply(function (){
if(scope.$parent === scope.$root)
modelSetter(scope,element[0].files[0]);
else
modelSetter(scope.$parent,element[0].files[0]);
console.log(element[0].files[0]);
console.log(scope);
});
});
}
}
});
This solved my problem:
app.directive('uploadFile', function($parse){
return {
restrict: 'A',
link: function(scope,element,attrs){
var model = $parse(attrs.uploadFile),
modelSetter= model.assign;
element.bind('change', function(){
scope.$apply(function (){
if(scope.$parent === scope.$root)
modelSetter(scope,element[0].files[0]);
else
modelSetter(scope.$parent,element[0].files[0]);
});
});
}
}
});
This is my code
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.name = fname;
$scope.lastName = lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{name}}<br>
Last Name {{lastName}}
</div>
</body>
</html>
values are coming while typing into textbox but i want values only after clicking the button.Please help me.
I tried in both ways simple as well as by using service or factory method but no success
You must separate the ng-models of the input texts and destination field. They are updating real-time because of having the same models.
I have created the correct version for you:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<script>
var myApp = angular.module('myApp', []);
myApp.controller('myController', function ($scope) {
$scope.getName = function () {
$scope.nameToSet = $scope.name;
$scope.lastNameToSet = $scope.lastName;
};
})
</script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name"/> <br>
<input type="text" ng-model="lastName" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>
UPDATE: Here is another version with using a factory:
var myApp = angular.module('myApp', []);
myApp.factory('container', function() {
var model = {
name: '',
lastName: ''
};
return {
model: model,
setName: function(nameToSet) {
model.name = nameToSet;
},
setLastName: function(lastNameToSet) {
model.lastName = lastNameToSet;
}
};
});
myApp.controller('myController', function ($scope, container) {
$scope.$watch('name', function(newvalue,oldvalue) {
container.setName(newvalue);
});
$scope.$watch('lastName', function(newvalue,oldvalue) {
container.setLastName(newvalue);
});
$scope.onNameType = function(value) {
container.setName(value);
};
$scope.onLastNameType = function(value) {
container.setLastName(value);
};
$scope.getName = function () {
debugger;
$scope.nameToSet = container.model.name;
$scope.lastNameToSet = container.model.lastName;
};
})
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
</head>
<body ng-app="myApp" >
<div >
<input type="text" ng-model="name" ng-change="onNameType(name)"/> <br>
<input type="text" ng-model="lastName" ng-change="onLastNameType(lastName)" />
</div>
<div ng-controller="myController">
<input type="button" value="click" ng-click="getName()" />
<br>
Hello FirstName {{nameToSet}}<br>
Last Name {{lastNameToSet}}
</div>
</body>
</html>
I have a view where the user gives an input and display it in another view.
view 1:
<ion-content ng-controller="controller">
<input type="text" ng-model="name">
<button ng-click="save()">Save</button>
Controller:
$scope.save = function () {
$scope.displayName = $scope.name;
$state.go('app.viewTwo');
}
View 2:
<ion-content ng-controller="controller">
{{displayName}}
</ion-content>
Its known, that whenever a view is loaded the controller is initialized fresh every time. So how to display the value from the first view, in another view.
You need to use a service or factory to use the variable across the controllers.
DEMO:
var app = angular.module("clientApp", [])
app.controller("TestCtrl",
function($scope,names) {
$scope.names =[];
$scope.save= function(){
names.add($scope.name);
}
$scope.getnames = function(){
$scope.names = names.get();
}
}
);
app.factory('names', function(){
var names = {};
names.list = [];
names.add = function(message){
names.list.push({message});
};
names.get = function(){
return names.list;
};
return names;
});
<!doctype html>
<html >
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="clientApp">
<div ng-controller="TestCtrl">
<input type="text" ng-model="name">
<button ng-click="save()" > save</button>
</div>
<div ng-init="getnames()" ng-controller="TestCtrl">
<div ng-repeat="name in names">
{{name}}
</div>
</div>
</body>
</html>
You can also use $rootScope , but it is not a recommended way.
I want to add data at the time of onclick event. Need to load image at the time of onclick event, after a small time interval add data. But my image is continuously loading. Any body give any suggestion.
My code is:
<!DOCTYPE html>
<head>
<title>Learning AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js" type="text/javascript"></script>
<script language="javascript">
function ContactController($scope) {
$scope.contacts = [];
$scope.items = [ ];
$scope.add = function() {
setTimeout(function() {
$scope.$apply(function() {
$scope.items[0].lateLoader = ' xxxx ';
});
}, 1000);
$scope.count=$scope.count+1;
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
}
}
</script>
</head>
<body >
<div ng-app="" ng-controller="ContactController">
<p>{{items.lateLoader}}
<i ng-hide="items.lateLoader"><img src="Filling broken ring.gif"></i>
</p>
{{ contacts.length }}
Content:<input type="text" ng-model="newcontact" />
<button ng-click="add()">Add</button>
<ul style="list-style-type: none;">
<li ng-repeat="contact in contacts"> <input name="" type="checkbox" value="">{{ contact }}</li>
</ul>
</div>
</body>
</html>
In your example I found a lot of mistakes. The HTML tag is not defined at the top, wrong use of angularJs and Angular module is not created properly etc.
I fixed all the mistakes. I hope it can help you.
Plunkr link: http://plnkr.co/edit/no8WOHdEc9wc3dHzzITv?p=preview
<!DOCTYPE html>
<html ng-app="app">
<head>
<title>Learning AngularJS</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<script >
angular.module("app",[]).controller('ContactController',['$scope',
function($scope) {
$scope.contacts = [];
$scope.items = [];
$scope.add = function() {
setTimeout(function() {
$scope.$apply(function() {
$scope.items.lateLoader = 'xxxx ';
});
}, 1000);
//$scope.count=$scope.count+1;
$scope.contacts.push($scope.newcontact);
$scope.newcontact = "";
}
}
]);
</script>
</head>
<body >
<div ng-controller="ContactController">
<p>{{items.lateLoader}}
<i ng-hide="items.lateLoader">
<img src="https://encrypted-tbn1.gstatic.com
/images?q=tbn:ANd9GcQTaHe0F0J39SXbiRF43pz2wtyfD6kypCMrLxhWPkq9EACNgwO0iaMbJFM">
</i>
</p>
{{contacts.length}}
Content:<input type="text" ng-model="newcontact" />
<button ng-click="add()">Add</button>
<ul style="list-style-type: none;">
<li ng-repeat="contact in contacts">
<input name="" type="checkbox" value="">{{ contact }}
</li>
</ul>
</div>
</body>
</html>
And for more detail of angularJs please visit these links:(https://angularjs.org/)
(http://www.w3schools.com/angular/default.asp)