I have this index.html which has a navbar in the which is seen on all pages of my single page application. The navbars container div is using the ng-controller="LoginCtrl" value, so I will also include that controller from my angular application (app.js)
For some reason, the variables username and password which are bound via ng-model are showing as undefined when doLogin() is called via ng-click directive? That is after I type values into the text boxes that are bound to my controllers variables.
index.html
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="username">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="./app/app.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js">
</body>
</html>
app.js
...
myApp.controller('LoginCtrl', function($rootScope, $location, AuthService, AuthToken) {
$rootScope.doLogin = function() {
console.log($rootScope.username);
console.log($rootScope.password);
}
});
...
An inputModel primitive property will be created on that ng-controller's scope when you type into the text field. input model is generated in the current scope, not the rootScope.
var app = angular.module('myApp', []);
app.controller('LoginCtrl', function($scope, $http) {
$scope.doLogin = function() {
console.log($scope.username);
console.log($scope.password);
}
});
Check it out on Plunker
Use model rather than using primitive types.
You should use $rootScope.user.name (ng-model will be user.name) rather than using $rootScope.username and $rootScope.user.password(ng-model will be user.password) instead of $rootScope.password
This problem actually happens for javascript's prototypical model. And if you want to know it's applicability in angularjs, you can go through this article. This will definitely help :)
Edit: As you are running into problem making that code work, I've made a working copy of your code. Please have a look at it:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="stylesheet.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.min.js"></script>
<base href="/">
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.9/ngStorage.js"></script>
<script src="https://cdn.socket.io/socket.io-1.3.5.js"></script>
</head>
<body>
<div ng-controller="LoginCtrl">
<nav class="navbar navbar-default">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="#">TriviaAttack!</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<form ng-if="!loggedIn" id="loginForm" class="navbar-form navbar-right">
<div class="form-group">
<input type="text" placeholder="Email" class="form-control" ng-model="user.name">
</div>
<div class="form-group">
<input type="text" placeholder="Password" class="form-control" ng-model="user.password">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success" ng-click="doLogin()">Sign In</button>
</div>
</form>
</div>
</div>
</nav>
<div ng-view></div>
</div>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
<script>
var myApp = angular.module("myApp", []);
myApp.controller('LoginCtrl', function ($scope, $location) {
$scope.user = { name: "", password: "" };
$scope.doLogin = function () {
console.log($scope.user.name);
console.log($scope.user.password);
}
});
</script>
use $scope instead of $rootScope for getting the ng-model in controller.
I found the answer to my own question after some frustration. Adding username and password arguments to my doLogin() function, then using the directive ng-click="doLogin(user.name, user.pass)" works as I wanted. No clue why it wasn't working the way I was trying, but oh well.
Related
I'm new to AngularJS, currently I am trying to create a spa for tracking expenses as a simple project but I have some problems with my code.
I managed to do the most of the function but I got stuck at the edit button and edit function. I am trying to make an inline edit function because I already have a form input.
Here is the html and js code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Expenses Tracker</title>
<link rel="stylesheet" href="bootstrap.min.css">
<link href="style.css" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container">
<div class="navbar-header">
<span class="navbar-brand"><img src="logo.png" class="brand" height="40" />
Simple Expenses App Tracker</span>
</div>
</div>
</nav>
<div class="main" ng-app="myList" ng-controller="myListController">
<img src="logo.png" class="logo">
<form ng-submit="newItem()" class="form">
<input required type="number" placeholder="Amount" ng-model="amount">
<input required type="text" placeholder="Description" ng-model="description">
<input type="submit" value="Submit" class="btn btn-success">
</form>
<ul>
<li ng-repeat="item in items">
<span class="pull-left"> {{item.amount}} den.</span> {{item.description}}
<span class="buttons">
<input type="button" value="Edit" class="btn btn-primary" >
<input type="button" ng-click="deleteItem($index)" value="Delete" class="btn btn-danger">
</span>
</li>
<br>
<li><span class="total">{{totalPrice()}} den.</span> <span class="expense"> Total Expenses</span></li>
</ul>
</div>
<script src="bootstrap.min.js"></script>
<script src="angular.min.js"></script>
<script src="angular-route.min.js"></script>
<script src="app.js"></script>
</body>
</html>
var myApp = angular.module("myList", []);
myApp.controller("myListController", function($scope) {
$scope.items = [];
$scope.newItem = function() {
$scope.items.push({description:$scope.description, amount: $scope.amount});
$scope.description = '';
$scope.amount = 0
};
$scope.deleteItem = function(index) {
$scope.items.splice(index, 1);
}
$scope.totalPrice = function() {
var total = 0;
for(count=0; count<$scope.items.length;count++){
total += $scope.items[count].amount;
}
return total;
};
});
You could try something like:
$scope.editItem = function(index) {
$scope.amount = $scope.items[index].amount;
$scope.description = $scope.items[index].description;
$scope.deleteItem(index);
}
I also recommend you read this book:
https://www.newline.co/ng-book/modern-ng1/
Try to move away from using $scope for bindings and user components. Unless you really don't care where this project goes.
ui-view is not working and there is no error shown. What did I miss? Please help me out and make this work.
This is my index.html which is the main template.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script
src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script
src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="LoginPage.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
</html>
Here LoginPage.js which I have included in the script tag is the controller for LoginPage.html
app.js is the config file which contains the states.
var Project = angular.module('Project', [ 'ui.router' ]);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login',{
url : '/login',
templateUrl : 'LoginPage.html',
controller : 'LoginCtrl'
})
});
The following is the LoginPage.html which I'm trying to load/render using ui-view in index.html
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50"required>
</div>
</div>
ngRoute and ui.router are different libraries.
You should be importing the right script:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
(Instead of /angular-route.js)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.js"></script>
</head>
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<div class="row">
<div ui-view></div>
</div>
</div>
<script type="text/ng-template" id="LoginPage.html">
<div class="row">
<div class="col-md-3">
<label>Username : </label>
</div>
<div class="col-md-9">
<input class="form-control" type="text" id="username" ng-model="user.username" name="username" maxlength="50" required>
</div>
</div>
</script>
<script>
var Project = angular.module('Project', ['ui.router']);
Project.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: 'LoginPage.html'
})
});
</script>
</body>
</html>
Notice that you also load up ui-router in addition to loading Angular:
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.8/angular-ui-router.min.js"></script>
When creating a link with UI-Router, you will use ui-sref:for example:
<body ng-app="Project">
<div class="mainbox">
<div class="loginmsg">
<div class="row text-center">
<p id="title">
<b>Movie Baba</b>
</p>
</div>
</div>
<ul>
<li><a ui-sref="login">login</a></li>
</ul>
<div class="row">
<div ui-view></div>
</div>
</div>
</body>
The href will be generated from this and you want this to point to a certain state of your application.
I have 2 html page and one app.js
my search-movie.html code as the following :
<!DOCTYPE html>
<html ng-app="adphorusWork">
<head lang="en">
<meta charset="UTF-8">
<title>Search Movie</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="scripts/jquery-1.9.1.min.js"></script>
<script src="app/app.js"></script>
</head>
<body ng-controller="searchMovieController">
<div class="navbar navbar-default navbar-fixed-top" style="margin-top: 20px;">
<div class="container-fluid">
<ul>
<li>
OMDb Api
</li>
</ul>
</div>
</div>
<div class="container" style="margin-top: 50px;">
<div class="bs-docs-section" id="">
<div class="row">
<div class="col-lg-12">
<div class="page-header">
<h2>My Github</h2>
</div>
<div class="bs-component">
<form class="well form-search" id="search-movie" onsubmit="return false;">
<fieldset>
<legend>Search Movie</legend>
</fieldset>
<div>
<label class="control-label" for="movie-name">Movie Name : </label>
<input type="text" id="movie-name" class="input-small" style="margin-left: 10px;">
<button id="btn-search-movie" type="button" class="btn-sm btn-primary" style="margin-left: 10px;" ng-click="searchMovie()">
<span class="glyphicon glyphicon-search"> Search</span>
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
and my result-movie.html code as the following :
<!DOCTYPE html>
<html>
<head ng-app="adphorusWork">
<meta charset="UTF-8">
<title>Search Movie</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="scripts/angular.min.js"></script>
<script src="scripts/angular-route.min.js"></script>
<script src="app/app.js"></script>
<script src="scripts/jquery-1.9.1.min.js"></script>
</head>
<body ng-controller="resultMovieController">
<div class="navbar navbar-default navbar-fixed-top" style="margin-top: 20px;">
<div class="container-fluid">
<ul>
<li>
OMDb Api
</li>
</ul>
</div>
</div>
<div class="container" style="margin-top: 50px;">
<div class="bs-docs-section" id="">
<div class="row">
<div class="col-lg-12">
<div class="page-header">
<h2>My Github</h2>
</div>
<div class="bs-component">
<fieldset>
<legend>Result for Search Movie</legend>
</fieldset>
<div>
<button id="btn-result-movie" type="button" class="btn-sm btn-primary" style="margin-top: 40px;" ng-click="backtohome()">
<span class="glyphicon glyphicon-circle-arrow-left"> Home</span>
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
and my app.js as the following :
(function (angular) {
'use strict';
var app = angular.module('adphorusWork', []);
app.controller('searchMovieController', function ($scope) {
$scope.searchMovie = function () {
alert("come")
}
});
app.controller('resultMovieController', function ($scope) {
$scope.backtohome = function () {
alert("home")
}
});
})(angular);
My search button is working (in search-movie.html) but my 'Home' button not working(in result-movie.html)
I'm using the same ng-app in two html page. I want to work on other button(so Home button)
Where am I doing wrong ? or How can I fix this error ?
you need to use Angular Ui router for this. And #Lex is correct you are not following the angular SPA framewrok.
This is a good read :https://github.com/angular-ui/ui-router
this link can provide a brief detail about angular ui router https://scotch.io/tutorials/angular-routing-using-ui-router
You don't have:
<script src="app/app.js"></script>
in your result-movie.html page. The bigger question, though, is why are you structuring it like this? Angular is designed as a single page application (SPA) framework. The way you are buidling it I think you are going to end up with a lot of issues long term.
I have noticed that you not include in result-movie.html page
<script src="app/app.js"></script>
as for best approach is you can use ngRoutefor data passing between controllers
I am new to Angular.js and was trying to create a link that displays a form when clicked on, but it doesn't seem to work.
this my index.html
<!DOCTYPE>
<html ng-app="MyApp">
<head>
<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">
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div>
<input type="text" ng-model="login.email">
<input type="text" ng-model="login.password">
<button type="button" ng-click="">Login</button>
<a ui-sref="signUp">Create An Account</a>
</div>
</div>
</nav>
<div ui-view></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-rc.0/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.js"></script>
<script src="app.js"></script>
</body>
</html>
This is the form- signup.html*(registration form and takes only email and password)*
<div class="row">
<div class="col-sm-6">
<div class="row">
Email Address
<input type="text" ng-model="newUser.email" class="form-control">
</div>
<div class="row">
Password
<input type="text" ng-model="newUser.password" class="form-control">
</div>
<button ng-click="createUser()">Submit</button>
</div>
</div>
and this is the controller-app.js
<!-- language: lang-js -->
var MyApp = angular.module('MyApp', ['ui.router']);
MyApp.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
$stateProvider
.state('signUp', {
url: "/signup",
templateUrl: "signup.html",
})
}
]);
<!-- end snippet -->
the idea is to display the form after the user clicks the 'Create An Account', the ui-router doesnt seem to work even when trying to load any state, could there be anything i am missing or should change or remove?
please and thank you.
I am learning angularJS and i am using the book, "Learning Web Development with Bootstrap and AngularJs" and i am trying to create a ng-click functionality to a button. but nothing happens when i click it. this is my controller.js...
function AppCtrl($scope){
$scope.clickHandler = function(){
window.alert('Clicked!');
};
}
this is my view...
<html ng-controller="AppCtrl">
<head>
<meta charset="utf-8">
<title>Contacts Manager</title>
<link rel="stylesheet" href="css/bootstrap.min.css">
<script type="text/javascript" src="js/angular.min.js"></script>
<script src="js/jquery-2.1.4.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/controller.js"></script>
</head>
<body>
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#nav-toggle">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Contacts Manager</a>
</div>
<div class="collapse navbar-collapse" id="nav-toggle">
<ul class="nav navbar-nav">
<li class="active">Browse</li>
<li>Add Contact</li>
</ul>
<form class="navbar-form navbar-right" role="search">
<input type="text" class="form-control" placeholder="Search">
</form>
</div>
</nav>
<div class="col-sm-8">
<button ng-click="clickHandler()">Click Me</button>
</div>
</body>
</html>
what am i doing wrong???
You need to create a module, and make the controller on the module. You then need to tell angular to bootstrap the module as the root of the application (using ng-app directive). I would reccomend taking another look at the exaple you are following.
Here's a short snippet setting up a button with a click-handler:
angular.module('myApp', [])
.controller('AppCtrl', function($scope){
$scope.clickHandler = function(){
window.alert('Clicked!');
};
}
);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="AppCtrl">
<button ng-click="clickHandler()">Click Me</button>
</div>
Inject $window, and call it. You have not dome that