angularjs - Update ng-model value from controller? - angularjs

View 1:
<div ng-controller="ctrl1">
<button ng-click="goToExtendedForm({'name':'aaa'})">
</button>
</div>
ctrl1:
$scope.selectedList = {
name: ""
};
$scope.goToForm = function(e) {
$scope.selectedList.name = e.name;
$state.go('view2');
console.log(e); // prints updated value
};
View 2:
<div ng-controller="ctrl1">
<input
id="name"
name="name"
type="text"
ng-model="selectedList.name"
ng-readonly="true"
/>
</div>
But the input box is always empty, even though to get to the view the goToForm() is called. Why doesn't it update the HTML value?
Views are changed with ui.router's $state.

From your description, your code is supposed to work. Check if you are passing the right parameter into the function. Here is a working demo:
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.selectedList = {
name: ""
};
$scope.goToForm = function(e) {
$scope.selectedList.name = e.name;
console.log(e); // prints updated value
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<button ng-click="goToForm({'name':'aaa'})">Change</button>
<br>
<input type="text" ng-model="selectedList.name" ng-readonly="true" />
</div>

Try adding $scope.$apply() at the end of your $scope.goToForm function

Try this ;
HTML Code
<div ng-app>
<div ng-controller="ClickToEditCtrl">
<input
id="name"
name="name"
type="text"
ng-model="selectedList.name"
ng-readonly="true"
/>
<button ng-click="goToForm(testUserDetails)" >Go To</button>
</button>
</div>
</div>
Define controller like this;
function ClickToEditCtrl($scope) {
$scope.selectedList = {
name: ""
};
$scope.testUserDetails ={
name: "nimal"
}
$scope.goToForm = function(e) {
$scope.selectedList.name = e.name;
console.log(e); // prints updated value
};
}

Related

ng-show not watching variable change

I have a progress bar I want to show after I click a button.
I set my variable to true on click, yet it's not working.
The ng-show in question is on the bottom of the html, and the button i click is on a different html page but i didn't include because it uses the successOnClick function in this same controller. I console logged the isEmailing variable inside the onclick and it is assigned true. Doesn't work for ng-if either
What gives?
module.exports = app => {
app.controller('ContactController', ($scope, $http) => {
$scope.isEmailing = false;
$scope.email = (e) => {
$scope.isEmailing = true;
const requestBody = {};
const id = e.target.id;
requestBody.name = document.getElementById(`${id}-name`).value;
requestBody.email = document.getElementById(`${id}-email`).value;
requestBody.subject = document.getElementById(`${id}-subject`).value;
requestBody.body = document.getElementById(`${id}-body`).value;
$http.post('/email', JSON.stringify(requestBody), {
'Content-Type': 'application/json'
})
.then(res => {
console.log('Success!');
document.getElementById(`${id}-name`).value = '';
document.getElementById(`${id}-email`).value = '';
document.getElementById(`${id}-subject`).value = '';
document.getElementById(`${id}-body`).value = '';
$scope.isEmailing = false;
})
.catch(err => {
console.log('Error!');
$scope.isEmailing = false;
})
}
$scope.successOnClick = () => {
$scope.isEmailing = true;
}
})
}
<footer class="footer" ng-controller="ContactController">
<div class="footer__block social-media-container">
<div class="social-media">
<img src="http://i.imgur.com/bVqv5Kk.png" alt="fb-icon">
<img src="http://i.imgur.com/sJWiCHV.png" alt="twitter-icon">
<img src="http://i.imgur.com/o7yTVyL.png" alt="insta-icon">
</div>
</div>
<div class="footer__block">
<form class="footer__form" ng-submit="email($event)" id="footer">
<textarea placeholder="Message" id="footer-body" required></textarea>
<input type="text" placeholder="Name" id="footer-name" required>
<input type="email" placeholder="Email" id="footer-email" required>
<input type="text" placeholder="Subject" id="footer-subject" required>
<input type="submit" placeholder="Email">
</form>
</div>
<div class="footer__block mailing-list">
<span>Join our Mailing List!</span>
<form>
<input type="email" placeholder="Email" required>
<input type="submit">
</form>
</div>
<!-- <div class="grey-screen">
<div class="success">
<h1>Success!</h1>
</div>
</div> -->
<div class="progress-bar" ng-show="isEmailing">
</div>
</footer>
If you have several controller of same type it is not mean, that they all are same the instance. AngularJS creates controllers not via singleton pattern. You should synchronize them by yourself by means of events:
angular.module('app', [])
.controller('MyController', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.$on('Changed', function(event, data){
$scope.isEmailing = data;
})
$scope.successOnClick = function(){
$scope.$emit('Changed', !$scope.isEmailing);
}
}]);
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController">
<h3 ng-style="{'background-color' : isEmailing ? 'red' : 'white'}">First controller</h3>
<input type='button' ng-click='successOnClick()' value='Change color'/>
</div>
<div ng-controller="MyController">
<h3 ng-style="{'background-color' : isEmailing ? 'red' : 'white'}">Second controller</h3>
<input type='button' ng-click='successOnClick()' value='Change color'/>
</div>
</div>
If one controller located inside another you can try to use $scope.$parent.isEmailing(where .$parent can be typed several times, depending on nesting level), but it is very uncomfortable. If your controllers located at different routes, you should pass data from one controler to another via route parameters or custom AngularJS service or $rootScope.

How set default value for dynamic input ng-repeat?

I try to set default value for some input.
When i try in ionic framework to set a default value with
ng-value
that work but when i submit the form, i ll never get the default value. I get undefined.
I think it's because i cannot initiate my objet before render my form.
But with dynamic input name i can't find the way.
This is my controler :
function MyCtrl($scope) {
$scope.frequences = [];
$scope.medicaments = {
15:{dose : 10,frequence :"matin", name:"test1"},
16:{dose : 15,frequence :"matin", name:"test2"},
17:{dose : 19,frequence :"matin", name:"test3"},
};
$scope.genererDate = function(form) {
console.log($scope.frequences)
}
And my HTML
<ion-item ng-repeat="(key, value) in medicaments " >
<span class="">{{key}} - {{value.name}}</span>
<input type="text" ng-model="frequences[key]['dose']" ng-init="frequences.key['dose'] = value.dose" >
<input type="text" ng-model="frequences[key]['frequence']" ng-init="frequences[key]['frequence'] = value.frequence">
</ion-item>
i have a Fiddle, ng-value doesn't work here, so i have try with ng-init.
http://jsfiddle.net/hwunpm5q/2/
Use {} to define $scope.frequences = {}; not an array []
And it should be access through frequences[key]['dose'] not frequences.key['dose']
var myApp = angular.module('myApp',[]);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.frequences = {};
$scope.medicaments = {
15:{dose : 10,frequence :"matin", name:"test1"},
16:{dose : 15,frequence :"matin", name:"test2"},
17:{dose : 19,frequence :"matin", name:"test3"},
};
$scope.genererDate = function(form) {
console.log($scope.frequences)
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp">
<div ng-controller="MyCtrl">
<form name="myform" novalidate="" ng-submit="genererDate(myForm)" >
<ion-item ng-repeat="(key, value) in medicaments " >
<span class="">{{key}} - {{value.name}}</span>
<input type="text" ng-model="frequences[key]['dose']" ng-init="frequences[key]['dose'] = value.dose" >
<input type="text" ng-model="frequences[key]['frequence']" ng-init="frequences[key]['frequence'] = value.frequence">
<br/>
</ion-item>
<br/>
<button class="button button-full buttonValiderTraitement" type="submit" ng-click="Submit">Submit</button>
</form>
</div>
</body>

Angularjs array push UI does not get's refreshed

I want to show a list of movies and add a new movie by adding it to the array.
The html file:
<!-- FOREACH the movies -->
<div ng-controller="homeController" ng-repeat="movie in movies | orderBy : order">
<div class="movie-wrapper">
<h1>{{movie.name}}</h1>
<p>IMDB: IMDB</p>
</div>
</div>
<!-- ADD a new movie to the array -->
<div ng-controller="homeController">
<h3>Add new movie:</h3>
<form name="movieForm" ng-submit="addMovie(movieInfo)">
<div class="form-group new-movie">
<label for="Title">Title:</label>
<input type="text" class="form-control" name="title" ng-model="movieInfo.title">
</div>
<div class="form-group new-movie">
<label for="IMDB">IMDB:</label>
<input type="text" class="form-control" name="imdb" ng-model="movieInfo.imdb">
</div>
<button type="submit" class="btn btn-primary">Add movie</button>
</form>
</div>
The javascript file:
var app = angular.module('movie-app', ["ngRoute"]);
app.controller("homeController", function($scope) {
$scope.movies = getMovies();
// Method to add a new movie
$scope.addMovie = function(movieInfo) {
$scope.movies.push({
name : movieInfo.title,
imdb_url: movieInfo.imdb
});
console.log("Movie added");
}
});
function getMovies() {
return [{
name: 'Inception',
imdb_url: 'http://www.imdb.com/title/tt1375666/'
}];
}
After pressing the submit button, in the console I did not get any error message, but somehow the UI does not get's refreshed.
I think that somehow the controller does not get a reference/bind to the same array or dom element when I'm pushing the new entry.
First of all, i'm pretty sure you should have an error in your console
You make 3 mistakes :
1. You have an error in your getMovies() function (missing curly brackets {})
function getMovies() {
return [{
name: 'Inception',
imdb_url: 'http://www.imdb.com/title/tt1375666/'
}];
}
Why curly brackets are important ?
name and imdb_url are properties object. In JavaScript, an object must have curly brackets before and after. But your function getMovies returns and array of 1 element, so you have to surround your object with brackets []
2. You also have an error when you call console.log (missing quote ")
console.log("Movie added);
3. And the last one : you have to remove the parenthesis }) (the line after console.log)
The result :
angular.module('movieApp', [])
.controller("homeController", function($scope) {
$scope.movies = getMovies();
// Method to add a new movie
$scope.addMovie = function(movieInfo) {
$scope.movies.push({
name: movieInfo.title,
imdb_url: movieInfo.imdb
});
console.log("Movie added");
};
});
function getMovies() {
return [{
name: 'Inception',
imdb_url: 'http://www.imdb.com/title/tt1375666/'
}];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="movieApp" ng-controller="homeController">
<!-- FOREACH the movies -->
<div ng-repeat="movie in movies | orderBy : order">
<div class="movie-wrapper">
<h1>{{movie.name}}</h1>
<p>IMDB: IMDB
</p>
</div>
</div>
<!-- ADD a new movie to the array -->
<div>
<h3>Add new movie:</h3>
<form name="movieForm" ng-submit="addMovie(movieInfo)">
<div class="form-group new-movie">
<label for="Title">Title:</label>
<input type="text" class="form-control" name="title" ng-model="movieInfo.title">
</div>
<div class="form-group new-movie">
<label for="IMDB">IMDB:</label>
<input type="text" class="form-control" name="imdb" ng-model="movieInfo.imdb">
</div>
<button type="submit" class="btn btn-primary">Add movie</button>
</form>
</div>
</div>

validate dynamic form before submitting angular

I'm dynamically creating forms with ng-repeat and they have some validation attributes (simplified version):
<div class="row" ng-repeat="defect in model.defects">
<form name="form_{{defect.id}}" novalidate>
<input ng-model="defect.name" required/>
<input type="submit" ng-click="saveDefect(defect)"/>
</form>
</div>
Basically what I want to do is this:
$scope.saveDefect = function (defect) {
if ($scope.<how to get the form name here>.$invalid) {
return;
}
}
Since the form name has been created dynamically with an id how do I access it? Other ways of doing the same are also welcome ofcourse :)
You can use the bracket notation to access it :
$scope["form_"+defect.id]
What I advise you to do is :
var app = angular.module("App", []);
app.controller("Ctrl", function($scope) {
$scope.forms = {};
$scope.list = [{id: 1}, {id: 2}];
$scope.save = function(item) {
if ($scope.forms["form_" + item.id].$invalid) {
alert("error on form_" + item.id);
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="App" ng-controller="Ctrl">
<div class="row" ng-repeat="item in list">
<form name="forms.form_{{item.id}}" novalidate>
<input ng-model="item.name" required/>
<input type="submit" ng-click="save(item)" />
</form>
</div>
</body>

Angular - 2+ ng-app directives in the same html

I need to add a controller with a function and another function to replace the { with [[ (I need to use Jekyll).
I have two ng-app:
myApp
invoice
Two files Javascript:
myApp.js
invoice.js
The following content for each file:
myApp.JS
var myApp = angular.module('myApp', []);
myApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
HTML myApp:
<div ng-app="myApp" ng-init="qty=1;cost=2">
<b>Invoice:</b>
<div>
Quantity: <input class="form-control" type="number" min="0" ng-model="qty">
</div>
<div>
Costs: <input class="form-control" type="number" min="0" ng-model="cost">
</div>
<div>
<b>
Total:
</b> [[qty * cost | currency]]
</div>
</div>
HTML invoice:
<div ng-app="invoice1" ng-controller="InvoiceController as invoice">
<form class="form-horizontal" id="frm_basic">
<b>Invoice:</b>
<div>
Quantity: <input type="number" min="0" ng-model="invoice.qty" required >
</div>
<div>
Costs: <input type="number" min="0" ng-model="invoice.cost" required >
<select ng-model="invoice.inCurr">
<option ng-repeat="c in invoice.currencies">[[c]]</option>
</select>
</div>
<div>
<b>Total:</b>
<span ng-repeat="c in invoice.currencies">
[[invoice.total(c) | currency:c]]
</span>
<button class="btn" ng-click="invoice.pay()">Pay</button>
</div>
</form>
</div>
invoice.js:
var invoice1 = angular.module('invoice1', [], function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
invoice1.controller('InvoiceController', function() {
this.qty = 1;
this.cost = 2;
this.inCurr = 'EUR';
this.currencies = ['USD', 'EUR', 'CNY'];
this.usdToForeignRates = {
USD: 1,
EUR: 0.74,
CNY: 6.09
};
this.total = function total(outCurr) {
return this.convertCurrency(this.qty * this.cost, this.inCurr, outCurr);
};
this.convertCurrency = function convertCurrency(amount, inCurr, outCurr) {
return amount * this.usdToForeignRates[outCurr] / this.usdToForeignRates[inCurr];
};
this.pay = function pay() {
window.alert("Thanks!");
};
});
It doesn't seem work properly. It is not replacing the { with [.
What is the mistake?
The error appear when I use both the html components in the page (myApp and invoice). If I disable "myApp" the second one works properly.
RESOLVED
I could not have more than 1 angular instance in the same html. AngularJS applications cannot be nested within each other.
According to the docs you have to use invoic1.config(....
The example works fine - provide a plunker with your code so we can help you.
var customInterpolationApp = angular.module('App', []);
customInterpolationApp.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('//');
$interpolateProvider.endSymbol('//');
});
customInterpolationApp.controller('DemoController', function() {
this.label = "This binding is brought you by // interpolation symbols.";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.js"></script>
<div ng-app="App" ng-controller="DemoController as demo">
//demo.label//
</div>

Resources