I am trying to validate a number input using angularjs.
The page works as desired by itself, however it does not work when I call the page with ajax.
Any help or advice would be appreciated!
Working angularjs jlgtest3.jsp ...
<div ng-app="total">
<script>
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) { }]);
</script>
<form name="totalForm" ng-controller="totalController">
<input name="totalHours" ng-model="total" type="number" value="" />
<p ng-show="totalForm.totalHours.$error.number">Not valid number!</p>
</form>
</div>
</html>
Not working with ajax call (jlgtest4.jsp calling jlgtest3.jsp)...
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
function newajax() {
var xRequest1;
if(window.XMLHttpRequest)
{
xRequest1=new XMLHttpRequest();
} else {
xRequest1=new ActiveXObject("Microsoft.XMLHTTP");
}
xRequest1.onreadystatechange=function ()
{
if((xRequest1.readyState==4) && (xRequest1.status==200))
{
document.getElementById("test").innerHTML=xRequest1.responseText;
}
}
var urlencode = "jlgtest3.jsp";
xRequest1.open("post",urlencode,true);
xRequest1.send();
}
</script>
</head>
<input type="button" onclick="newajax()" value="button" />
<div id="test">
</div>
</html>
I attempted the angular ajax call as some people suggested, but I couldnt get it to work...
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<div ng-app="total">
<script>
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) {
$http.POST("jlgtest3.jsp").then(function(response) {
$scope.test = response.data;
});
}]);
</script>
<div ng-controller="totalController">
<input type="button" value="button" />
{{test}}
</div>
</div>
</html>
If you're using Angular, you should consider using the $http service or even the $resource service. These both abstract ajax requests into a much simpler form. So instead of
xRequest1.open("post",urlencode,true);
xRequest1.send();
...etc...
You might have something like:
$http.POST(urlencode).then(function(response) {
document.getElementById("test").innerHTML=response.data;
// do other stuff with the response
});
And that will encapsulate essentially your entire newajax function.
As for #messerbill 's answer, you should not be making $http calls in your controller. These are better utilized within a service or factory that you then inject into your controller. Controllers are for business logic and should not deal with fetching and sending data.
you also can use a standart Ajax call but better use the $http angular way. You should call it inside of your angular controller.
XMLHttpRequest is an object used by Ajax - https://en.wikipedia.org/wiki/XMLHttpRequest
https://docs.angularjs.org/api/ng/service/$http
updated answer
Why dont you use Angular in the way its meant to be used? You should send your post inside of you angular service or controller. Don't manipulate your DOM if you use AngularJS like you did here:
document.getElementById("test").innerHTML=response.data;
istead you should do it that way:
angular.module('total', [])
.controller('totalController', ['$scope', function($scope) {
$http.POST("yourURL").then(function(response) {
$scope.test = response.data;
});
}]);
//template
<input type="button" value="button" />
<div ng-controller="totalController">
{{test}}
</div>
</html>
I have not tested it yet, but it should work - next time create a fiddle ;)
I posted this question again, but a little bit more simplified and Moncef Hassein-bey was able to answer my question Use Ajax to put external angularjs element in html page
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script>
angular.module('myApp', [])
.controller('myController', ['$scope', function($scope) { }]);
</script>
<script>
function newajax() {
var xRequest1;
xRequest1=new XMLHttpRequest();
xRequest1.onreadystatechange=function ()
{
if((xRequest1.readyState==4) && (xRequest1.status==200))
{
document.getElementById("test").innerHTML=xRequest1.responseText;
angular.bootstrap(document.getElementById('test'), ['myApp']);
}
}
xRequest1.open("post","jlgtest.html",true);
xRequest1.send();
}
</script>
<input type="button" value="button" onClick="newajax()" />
<div id="test">
</div>
</div>
</html>
Basically I needed to add the angular.bootstrap line of code, and the angular.module(... script needed to be in my main page
this is the called page code...
<html>
<div ng-app="myApp">
<form name="myForm" ng-controller="myController">
<input name="numberField" ng-model="myModel" type="number" value="" />
<p ng-show="myForm.numberField.$error.number">Not valid number!</p>
</form>
</div>
</html>
Related
AngularJS is new to me (and difficult). So I would like to learn how to debug.
Currently I'm following a course and messed something up. Would like to know how to interpret the console error and solve the bug.
plnkr.co code
index.html
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form action="searchUser" ng-submit="search(username)">
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="submit" value="search">
</form>
<div>
<p>Username found: {{user.name + error}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
script.js
(function() {
var app = angular.module("githubViewer", []);
var MainController = function($scope, $http) {
var onUserComplete = function(response) {
$scope.user = response.data;
};
var onError = function(reason) {
$scope.error = "could not fetch data";
};
$scope.search = function(username) {
$http.get("https://api.github.com/users/" + username)
.then(onUserComplete, onError);
};
$scope.username = "angular";
$scope.message = "GitHub Viewer"; };
app.controller("MainController", MainController);
}());
The console only says
searchUser:1 GET http://run.plnkr.co/lZX5It1qGRq2JGHL/searchUser? 404
(Not Found)
Any help would be appreciated.
In your form, action you have written this
<form action="searchUser"
What this does is it will try to submit to a url with currentHostName\searchUser, so in this case your are testing on plunker hence the plunker url.
You can change the url where the form is submitted. Incase you want to search ajax wise then you dont even need to specify the action part. You can let your service/factory make that call for you.
Though not exactly related to debugging this particular error, there is a chrome extension "ng-inspector" which is very useful for angularJS newbies. You can view the value each of your angular variable scopewise and their value. Hope it helps!
Here is the link of the chrome extension: https://chrome.google.com/webstore/detail/ng-inspector-for-angularj/aadgmnobpdmgmigaicncghmmoeflnamj?hl=en
Since you are using ng-submit page is being redirected before the response arrives and you provided any action URL as searchUser which is not a state or any html file so it being used to unknown address, it is async call so it will take some time you can use input types as button instead of submit.
Here is the working plunker.
<!DOCTYPE html>
<html ng-app="githubViewer">
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>{{message}}</h1>
{{ username }}
<form >
<input type="search"
required placeholder="Username to find"
ng-model="username"/>
<input type="button" ng-click="search(username)" value="search">
</form>
<div>
<p>Username found: {{user.name + error}} {{user}}</p>
<img ng-src="http://www.gravatar.com/avatar/{{user.gravatar_id}}" title="{{user.name}}"/>
</div>
</body>
</html>
I have the following code:
app.controller('MatrixExpertCtrl', function($scope,$http){
$scope.PassedMatrix=[];
$scope.GetMatrixFromServer=function(){
$http.get("http://localhost:3000/getmatrixfromdb").success(function(resp){
alert("The matrix grabbed from the server is: " + resp[0].ans);
$scope.PassedMatrix.push(resp[0].ans);
});
};
$scope.DispSize=function(){
alert("testing");
alert("The size is "+$scope.PassedMatrix[0].size) ;
};
//$scope.GetMatrixFromServer();
});
Now, suppose, in HTML, I have something like this:
<div class="col-sm-3 col-md-3 col-lg-3">
<div class="text-center">
<h3>Example Survey</h3>
<p>example paragrah</p>
<p>More random text</p>
<p>ending the paragraphs</p>
<button id="updmat" ng-click="DispSize();" type="button" class="btn btn-default">Updates</button>
</div>
//Much more code
<div id="body2">
<div class="col-sm-6 col-md-6 col-lg-6" style="background-color:#ecf0f1;">
<div ng-controller="MatrixExpertCtrl" ng-app="app" data-ng-init="GetMatrixFromServer()">
<div class="text-center">
Meaning with this:
Is it possible to call a function that is defined inside a controller, from outside of the scope of that same controller?
I need this because the function is manipulating a shared object, owned by the controller in a very very simple fashion (for example, clicking on the button changes the color of a given element).
I am having trouble to make this work, any help will be appreciated.
I think that declaring some data structures as global would help me solving this problem, but, I would like to avoid doing that because, besides it being bad practice, it might bring me more problems in the future.
If i understand your problem correctly than what you basically do have is one utility function which will work on your shared object and do your useful things (i.e. clicking on the button changes the color of a given element) and now you do require the same behaviour in another controller outside of it's scope. You can achieve the same thing in 2 different ways :
1).Create a service and make it available in your controllers like this :
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.factory('myService', function() {
return {
changeColour: function() {
alert("Changing the colour to green!");
}
};
});
myApp.controller('MainCtrl', ['$scope', 'myService', function($scope,
myService) {
$scope.callChangeColour = function() {
myService.changeColour();
}
}]);
</script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="callChangeColour()">Call ChangeColour</button>
</body>
</html>
Pros&Cons: More angularistic way, but overhead to add dependency in every different controllers and adding methods accordingly.
2).Access it via rootscope
<!doctype html>
<html ng-app="myApp">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="http://code.angularjs.org/1.1.2/angular.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', []);
myApp.run(function($rootScope) {
$rootScope.globalChangeColour = function() {
alert("Changing the colour to green!");
};
});
myApp.controller('MainCtrl', ['$scope', function($scope){
}]);
</script>
</head>
<body ng-controller="MainCtrl">
<button ng-click="globalChangeColour()">Call global changing colour</button>
</body>
</html>
Pros&Cons: In this way, all of your templates can call your method without having to pass it to the template from the controller. polluting Root scope if there are lots of such methods.
try removing semicolon
ng-click="DispSize()"
because it binds ng-click directive to the function.
i am new to angularjs and i tried practicing some examples. In the below stated example I am trying to initialize a value and setting it in scope. it is working fine, if i initialize the controller and scope values as given in the commented lines . but instead of those commented lines of code, if i try to set a controller and initialize scope value , like a regular javascript constructor function, then my example is not working.. Please anyone kindly explain why it is not working ?
<html>
<head>
<title>My Practices</title>
<script type="text/javascript" src="lib/angular.min.js"></script>
<script type="text/javascript">
/*var myApp = angular.module('myApp', []);
myApp.controller('HelloController', ['$scope', function($scope){
$scope.value = "World";
}]);*/
var HelloController = function ($scope) {
$scope.value = 'World';
}
</script>
</head>
<body ng-app>
<div ng-controller="HelloController">
<input type="text" ng-model="value" placeholder="enter your name">
<div>Hi {{value}} !! </div> </div>
</body>
</html>
I have a simple two-way binding setup with angular, and I added a plain javascript function that updates the value based off of the "alt" tag of an image a user clicks on. The problem is that when I hit save, the data doesn't update until I click inside the textbox and add a space. What's the best way to get around this?
http://plnkr.co/edit/j6tPYYUqvRyvfs32mcrW?p=preview
angular.module('copyExample', [])
.controller('ExampleController', ['$scope',
function($scope) {
$scope.master = {};
$scope.update = function(user) {
// Example with 1 argument
$scope.master = angular.copy(user);
};
$scope.reset = function() {
// Example with 2 arguments
angular.copy($scope.master, $scope.user);
};
$scope.reset();
}
]);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
</head>
<body ng-app="copyExample">
<div ng-controller="ExampleController">
<form novalidate class="simple-form">
Name:
<input type="text" ng-model="user.name" id="name" />
<br />
<img src="http://placehold.it/100&text=John" onclick="changeText(alt)" alt="John" />
<br />
<button ng-click="reset()">RESET</button>
<button ng-click="update(user)">SAVE</button>
</form>
<pre>form = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
<script>
function changeText(value) {
document.getElementById('name').value = value
}
</script>
</body>
</html>
working fiddle - http://jsfiddle.net/lwalden/b2p7pu7g/
If you are already using Angular then don't write a plain vanilla javascript function for the image click event - use Angular.
Also it's recommended not to use the alt attribute in this way. You could use a data- attribute instead.
Additional attributes within a tag to pass values to a function
So I'm having an issue with my ng-repeat in my displayCtrl. I'm able to add objects to my $scope.votes array on an ajax call as intended, but that's not being automatically updated in the view. Thoughts? Here's my script:
var glassCongress = angular.module('glassCongress', []).run(function($rootScope){
$rootScope.votes = [];
}).controller('searchCtrl', function($scope, $rootScope, $http){
$(document).ready(function() {
$('#sendstuff').on('submit',function(event) {
event.preventDefault();
$.ajax({
url: '/search/' + $('#input').val(),
type: 'GET',
dataType: 'json'
}).done(function(data){
for(var voteIndex = 0; voteIndex < data.data.length; voteIndex++){
$rootscope.votes.push({
"voteValue": (data.data[voteIndex].option.value)
})
}
})
})
})
}).controller('displayCtrl', function($scope, $rootScope){
})
And here's my html:
<html ng-app="glassCongress">
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.min.js"> </script>
<script src="script.js"></script>
</head>
<body>
<div id="search" ng-controller = "searchCtrl">
<div>
<form id='sendstuff' action='senddata' method='get'>
<input id='input' type='text'/>
<input type="submit" value="Submit" />
</form>
</div>
</div>
<div id="display" ng-controller = "displayCtrl">
<div>
<ul>
<li ng-repeat="vote in votes"><span>{{vote}}</span></li>
</ul>
</div>
</div>
</body>
</html>
Thanks guys!
Your $.ajax call runs out of the angularjs scope. Becouse of that, anglarjs don't update the view automaticly.
There is tow possible solutions.
1 - use the $http module. You can replace the $.ajax call by $http call. Read the doc to get more information.
2 - after change your model in ajax callback, call the method $acope.apply() to force angularjs update your view.
Inset use $rootScope, you should use $scope.