I am making a simple program, where if a person types a word 'alpha', the form gets all its elements states ng-prestine/ng-touched/ng-valid/ng-invalid all to their initial states. I think I am doing it correctly but getting an error in console.
HTML
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl">
<form name="form1">
<input type="text" ng-model="person">{{person}}
<button ng-click="click()">Click</button>
</form>
<script>
//Module Declaration
var app = angular.module('myApp',[]);
//Controller Declaration
app.controller('myCtrl',function($scope){
$scope.click = function(){
if ($scope.person = "alpha"){
form1.$rollbackViewValue();
}
}
});
</script>
</body>
</html>
Error
Reference
https://docs.angularjs.org/api/ng/type/form.FormController
Can someone help me out?
The form form1 isn't a defined variable in your controller. You have to use $scope.form1.$...
But be aware that $rollbackViewValue might not do what you expect. It would be easier to set the state you want your form to be in manually.
Related
I want to make the AngularJS form field dirty by using JavaScript code,
Here is the HTML Code
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="">
<p>Try writing in the input field:</p>
<form name="myForm">
<input name="myInput" ng-model="myInput" required>
</form>
<p>The input's valid state is:</p>
<h1>{{myForm.myInput.$valid}}</h1>
</body>
</html>
I tried using
document.querySelector('input[name="myInput"]').value="123",
clicking, focusing but none of them seems to work/override it. Please guide me on how to do that without using AngularJS functions and by using plain JavaScript.
I want to change the input's valid state to true
To interact with angular App from console you need to use
var scope = angular.element(document.getElementById('yourElementId')).scope();
this will bring you the required scope, then to set element as dirty you can use
scope.myForm.myInput.$setViewValue(scope.myForm.myInput.$viewValue);
Use:
var $body = angular.element(document.body);
var $scope = $body.data().$scope;
$scope.myForm.myInput.$setDirty();
$scope.$apply();
The DEMO
setTimeout(function() {
var $body = angular.element(document.body);
var $scope = $body.data().$scope;
$scope.myForm.myInput.$setDirty();
$scope.$apply();
}, 1000);
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<body ng-app="">
<p>Watch dirty state flash from false to true</p>
<form name="myForm">
<input name="myInput" ng-model="myInput" required>
</form>
<p>The input dirty state is:</p>
<h1>{{myForm.myInput.$dirty}}</h1>
</body>
</html>
I have a simple page that shows the hash of a string as someone types it into the page. I found that the page had a JavaScript error
Error: [$rootScope:infdig] http://errors.angularjs.org/1.2.26/$rootScope/infdig?p0=10&p1=%5B%5B%22sha1…75651%2C1080464653%2C-772792499%5D%2C%5C%22sigBytes%5C%22%3A20%7D%22%5D%5D
A very simplified version of the page is
<html lang="en">
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
<script>
function MyCtrl($scope) {
$scope.sha1 = function(pwd) {
return CryptoJS.SHA1(pwd);
};
}
</script>
</head>
<body>
<div class="app" ng-app ng-controller="MyCtrl">
<span ng-bind="sha1('bar')"></span>
</div>
</body>
</html>
which is available as Plunker http://plnkr.co/edit/vmBtH8B2EKsdcfZVGlMH.
What I am trying to do in the original page is recalculate the hash as someone types into the form field, and the input field definition looked like this
<input id="password" ng-model="password" type="text" placeholder="Password">
and the ng-bind is really ng-bind="sha1(password)", but the simple static case in the Plunker exhibits the same behavior.
I gather that the infdig error has to do with too many $digest cycles, but I don't see how that would happen here. It looks like the hash computation triggers the error, because returning a static string from the sha1 function causes no error.
Providing ng-bind="sha1('bar')" makes the digest cycle unstable, everytime sha1 function returns a different object (reference is different) and your digest cycle has to run again to stabilize it and every digest cycle again evaluates the ng-bind function expression and it goes on till it reaches the max limit set (10). You can also easily replicate this issue by just doing return [] in your scope method. This is just a side effect of not so good practice of binding a function expression to ng-bind as it runs every digest cycle, if at all used it should be carefully evaluated.
One simple solution is to bind ng-change/ng-blur event on your password or any other trigger and just bind ng-bind to a property instead of a function expression.
angular.module('app',[])
.constant('Crypto', window.CryptoJS);
function MyCtrl($scope, Crypto) {
$scope.encrypt = function() {
$scope.encrypted = Crypto.SHA1($scope.password);
};
}
<html lang="en" ng-app="app">
<head>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/sha1.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
</head>
<body>
<div class="app" ng-app ng-controller="MyCtrl">
<input id="password" ng-model="password" type="password" placeholder="Password" ng-change="encrypt()">
<span ng-bind="encrypted"></span>
</div>
</body>
</html>
For better usage of DI i have placed crpto in a constant and inject it where needed.
I've got the following code:
<!DOCTYPE html>
<html>
<body>
<div ng-app="">
<p>Name: <input type="text" ng-model="name"></p>
<p ng-bind="name">{{$http.get('https://api.themoviedb.org/3/movie/now_playing?api_key=b4e5192d902f5add71f4a431c004d734').success(successCallback);}}</p>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script>
$http.get('https://api.themoviedb.org/3/movie/now_playing?api_key=b4e5192d902f5add71f4a431c004d734').success(successCallback: 'JSON_CALLBACK');
</script>
</body>
</html>
But it is not returning anything, how do I make it so I can at least just display everything in that API? I would like to assign it to an variable and be able to explode it for manipulation.
You need to first define an app and a controller, and call $http inside it. In your HTML you can display the data that gets passed into the callback. Something like this:
<!DOCTYPE html>
<html>
<body>
<div ng-app="App" ng-controller="Ctrl">
<p>Name: <input type="text" ng-model="name"></p>
<p>{{ data }}</p>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script>
angular.module('App', []).
controller('Ctrl', function($scope, $http) {
$http.get('https://api.themoviedb.org/3/movie/now_playing?api_key=b4e5192d902f5add71f4a431c004d734').success(function(data) {
$scope.data = data;
});
});
</script>
</body>
</html>
You have a syntax error in your $http.get call. The options inside of .success need to be surrounded with curly braces, as they're an object.
Also, you're trying to use $http before it's been defined.
The http call should be made in a controller. Angular services are not accessible directly in the html or immediately in a script block. I'm sure if you checked the console window you would see at least a couple of errors in what you have put here.
Basically when the data is returned the controller can assign the returned data onto a variable on the scope.
I'm going to guess your new to angular in which case there are many great resources online to guide you though making these first basic steps. Checkout https://egghead.io/articles/new-to-angularjs-start-learning-here.
<html>
<head>
<script>
function calledHere(value) { console.log(value); }
</script>
</head>
<body>
<form name="test">
<input type="button" value="click!" onclick="calledHere(test);" >
</form>
</body>
</html>
From the above code, in the onclick call passed wrongly the form name without quotes. But, the output displays the whole form DOM element. Don't know how it got the form element.
Any help will be more useful for my learning on javascript side.
Thanks in Advance!!!
You've already got the form element in your 'value' variable. The reason you're seeing the element's html logged is because console.log calls the .toString() method on the element.
This code demonstrates that 'value' references the form element:
<html>
<head>
<script>
function calledHere(value) { value.style.backgroundColor = "red" }
</script>
</head>
<body>
<form name="test">
<input type="button" value="click!" onclick="calledHere(test);" >
</form>
</body>
</html>
http://jsfiddle.net/John_C/KZ3KR/
This answer explains the scope of the variable; why you can pass the form name to the function: https://stackoverflow.com/a/1416157/1588990
I'm trying to update scope value on parent window from a child popup.But whenever I try to access the parent window scope,it returns undefined. As it involves two window, I couldn't create a fiddle for this. Code sample is pasted below.
Main page (main.html)
<!doctype html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
$scope.name = 'Superhero';
}
</script>
</head>
<body ng-app="myApp">
<div id="ctrl" ng-controller="MyCtrl">
Hello, {{name}}!
<input type="button" value="Open popup!!" onclick="window.open('child.html');"/>
</div>
</body>
</html>
Child window (child.html)
<!doctype html>
<html >
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script>
function change(){
var e = window.opener.document.getElementById('ctrl');
var ae = angular.element(e);
var s = ae.scope();
s.name="New Superhero";
s.$apply();
}
</script>
</head>
<body>
<input type="button" value="Update parent scope!" onclick="change();"/>
</body>
</html>
Here whenever I try to access scope from the angular element , as shown above in change method, it returns undefined [ae.scope()].But when the same code moved to a function in parent window [only difference in how 'ctrl' element is being accessed], it worked fine and I was able to update the scope variable. Can anyone point out what actually is going wrong here? Thanks
Use the angular reference from the opener:
function change() {
var s = window.opener.angular.element('#ctrl').scope();
s.name="New Superhero";
s.$apply();
}
I had a similar need and had the same problem accessing the scope using angular.element. I was was able to solve it as follows though:
In your main/parent controller do something like this:
$scope.food = 'Mac & Cheese';
window.$windowScope = $scope;
$window.open('views/anotherWindow.html', '_blank','menubar=yes,toolbar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes,personalbar=yes');
Then in the child window controller you can access $windowScope like this:
$scope.parentWindow = window.opener.$windowScope;
console.log($scope.parentWindow.food);
An alternative to putting data directly into the scope would be to use $window scope to broadcast and/or emit events, which is the preferred way of cross-controller communication in angular.