ng-click does not work in AngularJS custom directive - javascript

I created a directive, everything is working well except that "ng-click" does not work from my controller. Nothing happens when i click the button. What am I getting wrong?
Here is my app.js
var app = angular.module('mainApp',[ 'ui.router' ]);
app.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('login', {
url: '/login',
controller: 'LoginPageCtrl',
});
}])
app.directive('loginPage', function loginPage() {
return {
restrict: 'EA',
templateUrl: 'app/partial/login.html',
}
})
app.controller('LoginPageCtrl', function($scope) {
$scope.login = function() {
alert("You Clicked Me")
}
})
Then in my login.html I have
<button ng-click="login()" type="submit" class="btn btn-default">Sign in</button>
EDITED -- JUST ADDED CODES BELOW
Am using directive because of the login am using to use specific css for different page layout (login page & user page). It might sound awkward though.
Here is my index.html
<!DOCTYPE html>
<html lang="en" ng-app="BlurAdmin">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Admin</title>
<link ng-if="!$authPage" rel="stylesheet" href="styles/app-b6796b3788.css">
<link ng-if="$authPage" rel="stylesheet" href="styles/auth-a200a050c1.css">
</head>
<body>
<page-content ng-if="!$authPage"></page-content>
<login-page ng-if="$authPage"></login-page>
<script src="scripts/app-5a80256787.js"></script>
</body>
</html>

The problem was solved by adding <div ui-view></div> which was ommited. Now I can now call the templateUrl in the login state to load in the ui-view
Here is the new layout.html
<div ui-view></div>
Then the directive now changed in the app.js
app.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('login', {
url: '/login',
controller: 'LoginPageCtrl',
templateUrl: 'app/pages/login.form.html',
});
}])
app.directive('loginPage', function loginPage() {
return {
restrict: 'EA',
templateUrl: 'app/partial/layout.html',
}
})

Related

How to use Multiple buttons with different controller in angularjs for redirecting

I wrote the program that is having 3 buttons and if i click on the particular button it should redirect to corresponding page mentioned in app.js
my requirement is each button should have a controller and it should redirect properly and it should show a console message that which button is clicked
i'm sharing my code but it is not working
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Test</title>
<link data-require="bootstrap-css" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<!-- Le javascript
================================================== -->
<script data-require="jquery" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="bootstrap" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.9/angular-route.min.js"></script>
<script>var myItemsApp = angular.module('myItemsApp', ['ngRoute']);</script>
</head>
<body ng-app="myItemsApp">
<div>
<h3>Test</h3>
<div class="row">
<div class="col-md-4">
<button href="/test1" ng-click="submit1()">Button1</button>
<button href="/test2" ng-click="submit2()">Button2</button>
<button href="/test3" ng-click="submit3()">Button3</button>
</div>
</div>
</div>
</div>
<script src="app.js"></script>
</body>
<script src="testcntrl.js"></script>
</html>
#app.js
myItemsApp.config(['$routeProvider',function($routeProvider) {
$routeProvider
.when('/test1', {
templateUrl : 'test.html',
controller : 'button1Controller'
})
.when('/test2', {
templateUrl : 'test1.html',
controller : 'button2Controller'
})
.when('/test3', {
templateUrl : 'test2.html',
controller : 'button3Controller'
})
.otherwise({
redirectTo: '/'
});
}]);
testcntrl.js
myItemsApp.controller('button1Controller', ['$scope','$location', function($scope,location){
$scope.submit1 = function() {
console.log("I clicked on submit button1Controller");
location.path('/test1');
}
}]);
myItemsApp.controller('button2Controller', ['$scope','$location', function($scope,location){
$scope.submit2 = function() {
console.log("I clicked on submit button2Controller ");
location.path('/test2');
}
}]);
myItemsApp.controller('button3Controller', ['$scope','$location', function($scope,location){
$scope.submit3 = function() {
console.log("I clicked on submit button3Controller");
location.path('/test3');
}
}]);
test1.html
<h1>hello</h1>
You should add ng-view to render template. and add # to url in the href.
also you don't need ng-click when time using <a> tag.and you injected service into controller incorrectly. you should inject $location instead of location
if you want to remove # from url so enable html mode.
<div class="col-md-4">
<a href="#/test1" >Button1</a>
<a href="#/test2" >Button2</a>
<a href="#/test3" >Button3</a>
</div>
<div ng-view=""></div>
</div>
Demo
Your idea is ok, it should work but:
No need href in button.
Instead of button you can simply use anchor with #/test1 #/test2
If you still want this way you need another controller "main controller"
This can work:
// Code goes here
var myItemsApp = angular.module('myItemsApp', ['ngRoute']);
myItemsApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/test1', {
templateUrl: 'test1.html',
controller: 'button1Controller'
})
.when('/test2', {
templateUrl: 'test2.html',
controller: 'button2Controller'
})
.when('/test3', {
templateUrl: 'test3.html',
controller: 'button3Controller'
})
.otherwise({
redirectTo: '/'
});
}]);
myItemsApp.controller('initialController', ['$scope', '$location', function($scope, location) {
$scope.submit1 = function() {
console.log("I clicked on submit button1Controller");
location.path('/test1');
}
$scope.submit2 = function() {
console.log("I clicked on submit button2Controller ");
location.path('/test2');
}
$scope.submit3 = function() {
console.log("I clicked on submit button3Controller");
location.path('/test3');
}
}]);
myItemsApp.controller('button1Controller', ['$scope', '$location', function($scope, location) {
}]);
myItemsApp.controller('button2Controller', ['$scope', '$location', function($scope, location) {
}]);
myItemsApp.controller('button3Controller', ['$scope', '$location', function($scope, location) {
}]);
Plunker demo

AngularJs Controller in External file and using route

I have had a look through SO and nothing has helped.
This is my app.js
var app = angular.module("qMainModule", ["ngRoute"])
.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/anonHome/anonHome.html',
controller: 'templates/anonHome/anonHomeController'
})
.when("/about", {
templateUrl: 'templates/anonHome/anonAbout.html',
controller: 'templates/anonHome/anonAboutController'
})
.when("/services", {
templateUrl: 'templates/anonHome/anonServices.html',
controller: '/templates/anonHome/anonServicesController'
})
.when("/contact", {
templateUrl: 'templates/anonHome/anonContact.html',
controller: '/templates/anonHome/anonContactController'
})
.when("/register", {
templateUrl: 'templates/anonHome/anonRegister.html',
controller: '/templates/anonHome/anonRegisterController'
})
.when("/login", {
templateUrl: 'templates/anonHome/anonLogin.html',
controller: '/templates/anonHome/anonLoginController'
})
$locationProvider.html5Mode(true);
})
app.controller("qMainController", function ($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
});
The routing works as expected and the partial templates are being shown but the partial templates controllers are not being recognised as a function.
The Layout Template looks like this
<!DOCTYPE html>
<html ng-app="qMainModule">
<head ng-controller="qMainController">
<base href="/" />
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="">
<title>Qiao :: {{Title}}</title>
<!-- Bootstrap Core CSS -->
<link href="css/bootstrap.min.css" rel="stylesheet">
<link href="../css/modern-business.css" rel="stylesheet" />
<!-- Custom Fonts -->
<link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css">
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
<script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
<![endif]-->
<script src="/scripts/angular.js"></script>
<script src="../scripts/angular-route.js"></script>
<script src="/app/app.js"></script>
<script src="templates/anonHome/anonHomeController.js"></script>
<!-- <link href="../styles/qiao.css" rel="stylesheet" /> -->
</head>
<body ng-controller="qMainController">
<div ng-include="qNavigationTemplatePath">
</div>
<!-- Page Content -->
<div class="container">
<ng-view></ng-view>
</div>
<!-- Footer -->
<footer>
<div class="row">
<div class="col-lg-12" ng-controller="qMainController">
Copyright © {{copyrightMessage}} {{copyrightYear | date:'yyyy'}}
</div>
</div>
</footer>
<div >
<!-- jQuery -->
<script src="js/jquery.js"></script>
<!-- Bootstrap Core JavaScript -->
<script src="js/bootstrap.min.js"></script>
<!-- Script to Activate the Carousel -->
<script>
$('.carousel').carousel({
interval: 5000 //changes the speed
})
</script>
</div>
</body>
</html>
The partial template looks like this:
<script src="anonHomeController.js"></script>
<div ng-controller="anonHomeController">
<h1>{{Title}}</h1>
</div>
and its controller is this
function anonHomeController($scope) {
$scope.Title = " Welcome to Qiao";
$scope.qNavigationTemplatePath = "/templates/topMenu/anonTopNavigation.html";
$scope.copyrightMessage = "Qiao ";
$scope.copyrightYear = new Date();
};
The Question: How do I get Angular to recognise and use the partial template's controller?
While defining a controller, don't use any directory paths.
From the docs - https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
controller – {(string|Function)=} – Controller fn that should be associated with newly created scope or the name of a registered controller if passed as a string.
Note that the registered controller never has the entire path, it is the function definition itself or the function's name (a string). You may need module names, if you have exported like that, but that's different from a directory path.
All you need is just use <script> tags in index.html, which will include all your functions. Now if your functions are just plain javascript, and you don't intend using angular.module('app').controller there, use it in the app.js, Just angular.module('app').controller('anonHomeController', anonHomeController); Note that your definition can still remain in the Javascript file /some/path/totemplate/anonHomeController.js. I suggest you try that and see if it works.
app.js
app.config(function ($routeProvider, $locationProvider) {
$routeProvider
.when("/", {
templateUrl: 'templates/main/main.html',
controller: 'MainCtrl'
})
index.html
<script src="controllers.js"></script>
controllers.js
function MainCtrl ($scope) {
$scope.name = 'World';
}
A working plnkr here
You have created your controller for each view as a regular JS function, which is incorrect. It should be like
app.controller("anonHomeController", function ($scope) {
$scope.Title = " Welcome to Qiao";
// rest of the controller code
});
and the file should be anonHomeController.js at the path you have defined in the config. you also do not need to include the scipt tag in the header of the view. Check for some example here
You don't need to add complete path in your app.js for defining controllers.
If you're controllers are defined in the same file, then this should do the job:
$routeProvider
.when("/", {
templateUrl: 'templates/anonHome/anonHome.html',
controller: 'xyzController'
});
app.controller("xyzController", function ($scope) {
// controller function here
});
If you want your controllers to be in an external file, you'll have to do the following:
1. Define the controllers module:
angular.module('app.controllers', [])
.controller("homeController", function(){....})
Name this file as controllers.js
2. Now your main app.js should include this:
angular.module('app', [
'app.controllers',
])
Include controllers.js in your main html file

AngularJS dynamically load template and js file

I want to dynamically add menu JavaScript file and html to content.html, but it can't do.
I created simple example
demo
I try move "<script src="menu.js"></script>" to menu.html
Your code moves away from the whole idea of writing single page app with angular. I have updated it to give you basic idea of how you would do the routes and share templates and use controller.
Check out the plunkr
html
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="menu.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8"></script>
<script data-require="ui-router#*" data-semver="0.2.15" src="https://cdn.rawgit.com/angular-ui/ui-router/805e69bae319e922e4d3265b7ef565058aaff850/release/angular-ui-router.js"></script>
<script src="menu.js"></script>
<script src="index.js"></script>
</head>
<body>
<div id="menu" ng-include="'menu.html'"></div>
<div ui-view></div>
</body>
</html>
js
angular.element(document).ready(function() {
angular.bootstrap(document, ["app"]);
});
angular.module('app',['moduleContent', 'moduleMenu', 'ui.router']);
var app = angular.module('app');
app.config(function($stateProvider) {
$stateProvider
.state('index', {
url: "",
templateUrl: "first.html",
controller: 'firstCtrl'
})
.state('second', {
url: "/second",
templateUrl: "second.html"
})
});
app.controller('firstCtrl', ['$scope', function($scope) {
$scope.page = "first";
}]);
//Conttent module
angular.module('moduleContent',[])
.controller('contentCtrl', contentCtrl);
function contentCtrl(shareData)
{
shareData.currentPage = 0;
}

Angular ui-router : Links are not clickable

I try to run angular-ui-router to handle my views but i have a problem.
The two links of the following view are not clickable.
Angular change variable with link label but i can't click on.
I have this view :
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<meta charset="utf-8">
</head>
<body>
<h1>App</h1>
<nav>
<a ui-shref="app">{{link.home}}</a>
<a ui-shref="app.front.signin">{{link.signin}}</a>
</nav>
<div ui-view="content">
</div>
</body>
</html>
I use this code. It do not returns errors
. All modules (localStorage ... are included) but links are not clickable.
/**
* Declaration of MyAppControllers module
*/
MyAppControllers = angular.module('MyAppControllers',[]);
/**
* Declaration of MyApp Application
*/
MyApp = angular.module('MyApp', ['MyAppControllers','LocalStorageModule','ui.router']);
MyApp.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/");
//
// Now set up the states
$stateProvider
.state('app', {
url: "/",
views: {
"content": {templateUrl: "views/front/home-1.0.html"}
}
})
.state('app.front.signin', {
url: "/signin",
views: {
"content": {templateUrl: "views/front/home-1.0.html", controller: "signinCtrl"}
}
});
}
]);
Can someone help me ?
You messed up in type it should be ui-sref instead of ui-shref
<body>
<h1>App</h1>
<nav>
<a ui-sref="app">{{link.home}}</a>
<a ui-sref="app.front.signin">{{link.signin}}</a>
</nav>
<div ui-view="content">
</div>
</body>
Your second link should be app.signin instead of app.front.signin because you don't have parent route front
.state('app.signin', {
url: "/signin",
views: {
"content": {
templateUrl: "views/front/home-1.0.html",
controller: "signinCtrl"
}
}
});

AngularJS v1.3.13 ng-view not triggering controller to render template

Having an issue using the ng-view to render a template from my controller.
The index.html file is initially served to the client and looks like.
<!doctype html>
<html lang="en" ng-app="hlmApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title></title>
<link rel="stylesheet" href="#Model.Root.Resource/bower_components\\/bootstrap/dist/css/bootstrap.css">
#RenderSection("BootScript")
<!-- app.js will load the angular module -->
<script src="#Model.Root.Resource/bower_components/angular/angular.js"></script>
<script src="#Model.Root.Resource/bower_components/angular-route/angular-route.js"></script>
<script src="#Model.Root.Resource/app/app.js"></script>
<script src="#Model.Root.Resource/app/controllers/controllers.js"></script>
</head>
<body>
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li>A link here</li>
</ul>
</div>
</div>
<div ng-view></div>
#*<div ng-controller="tempController">{{Heading}}</div>*#
</div>
#RenderBody()
</body>
</html>
the server pushes down my app.js and controllers.js file along with the deps.
/// ap.js ///
var hlmApp = angular.module('hlmApp', ['ngRoute', 'MyTempControllers']);
hlmApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/Holdings', {
templateUrl: 'templates/temp.html',
controller: 'controllers/tempController'
});
}]);
the controller is pretty simple and is as follows
var MyTempControllers = angular.module('MyTempControllers', []);
MyTempControllers.controller('tempController', ['$scope', function () {
console.log("stuff happening");
$scope.Heading = "Hello World";
}]);
then the html template is as follows
<div>
<h3>{{Heading}}</h3>
</div>
When I use the ng-view nothing ever renders. the controller is never triggered in the debugger. If I specifically call out the controller via the ng-controller then everything shows up. can someone point out my error here?
You need these 3 changes:
1) add $scope as a parameter in your controller function
MyTempControllers.controller('tempController', ['$scope', function ($scope) {
...
}]);
2.
Change
controller: 'controllers/tempController'
to
controller: 'tempController'
FYI, the naming convention for a controller is to begin with a capital letter for Controller.
3. In addition, you should add a
.otherwise({
template: templates/temp.html,
controller: 'tempController'
});
so that when no route matches, it goes to default-page-name.html. This is what's happening in your case, when you first load the page, no route matches. If you want to see temp.html, you have to 1) either click on a link that goes to #/Holdings, or 2) use '/Holdings' as the "otherwise" route, as indicated above.
Try this:
hlmApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/Holdings', {
templateUrl: 'templates/temp.html',
controller: 'tempController' // just the name
});
}]);
and also $scope is missing in parameters:
MyTempControllers.controller('tempController', ['$scope', function ($scope) {
console.log("stuff happening");
$scope.Heading = "Hello World";
}]);

Categories