Show parts of the page with ng-show like virginamerica website - angularjs

in my project i've to do something very similar to virginamerica.com ux logic.
I've to set my page in 3 parts, and set them visible depending on the routeParams. So, imagine this:
A list of items [visible on the root]
Detail of the item with some variations [visible on the root/item]
Item editor page [visible on the root/item/var]
I'm trying to set up an angular application to do this, but i've some problems, i'm doing something like this:
in my index.html i've this code:
<!DOCTYPE html>
<html ng-app="box">
<head lang="en">
<meta charset="utf-8">
<title>Box loader</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="box.js"></script>
<!-- <base href="/"> -->
</head>
<body ng-controller="boxCtrl">
<section id="box-chooser">
<ul>
<li ng-repeat="box in boxes">
{{box.boxname}}
</li>
</ul>
</section>
<div ng-show="detailVisible">
<section ng-controller="boxDetailCtrl">
<h1>detail {{boxcode}}</h1>
</section>
</div>
</body>
</html>
this is the angularjs part:
var app = angular.module('box', []);
app.config(function($routeProvider /*$locationProvider*/) {
$routeProvider
.when('/', {} )
.when('/:boxid', {
})
//$locationProvider.html5Mode(true);
});
app.controller('boxCtrl', function($scope, $route, $location) {
$scope.$on('$routeChangeSuccess', function() {
var path = $location.path();
console.log(path);
$scope.detailVisible = false;
if(path === '/123') {
$scope.detailVisible= true;
}
});
$scope.boxes = [{'boxid':'123', 'boxname': 'name1'}, {'boxid':'189', 'boxname': 'name2'}, {'boxid':'156', 'boxname': 'name3'}]
});
app.controller('boxDetailCtrl', function($scope, $route, $location){
$scope.boxcode = $location.path();
console.log('secondo:' + $location.path())
});
Problem is that boxcode on the second controller works only after a page refresh on localhost/#/123 and ng-show works on the path change.
Any better idea to doing this?
Thanks in advance :)

Related

Angular loading Controllers and Services

I am using Angularjs for my application.I am having one common page which has header and footer which i am making common for all pages.Thats y i am placing it in one common html.Only contents code i am placing in other html pages.
As i am using one common page i am loading all controllers and all Services that i am using in the application.
Here is my commonpage.html
<!DOCTYPE html>
<html lang="en" data-ng-app="adminApp">
<head>
</head>
<body>
<!--Here is header code-->
<div class="LeftMenu">
<ul class="navbar">
<a href="#!/admindashboardhome" title="Dashboard"><li>
<span>Dashboard</span></li>
</a>
<a href="#!/examinationhalltickets" title="Declaration"><li>
<span>Examination Form</span></li>
</a>
<a href="#!/collegedetails" title="Declaration"><li>College
Details</li>
</a>
</ul>
</div>
<!--followed by footer code-->
<div data-ng-view> <!--ng-view-->
</div>
<!--Here i am loading all controllers and services related to application-->
<script
src="resources/angular/controller/admin/AdminExamController.js">
</script>
<script src="resources/angular/service/admin/AdminExamService.js">
</script>
<!-- And many more in same fashion-->
</body>
</html>
The doubt i am having is,is it necessary to place all controllers and services like i am doing because i am facing performance issue even though i am connected to strong internet it loads very slow.As i am placing all in one page it is loading all controllers and services everytime.If i place controllers in their respective html then i am getting error like ExamController.js or any .js Controller not defined.Is there any other way that i can load all controllers and services so that i can increase the performance of the application?
I think this is what your looking for
app.js
/* Module Creation */
var app = angular.module ('adminApp', ['ngRoute']);
app.config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider){
/*Creating a more synthesized form of service of $ controllerProvider.register*/
app.registerCtrl = $controllerProvider.register;
function loadScript(path) {
var result = $.Deferred(),
script = document.createElement("script");
script.async = "async";
script.type = "text/javascript";
script.src = path;
script.onload = script.onreadystatechange = function (_, isAbort) {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
if (isAbort)
result.reject();
else
result.resolve();
}
};
script.onerror = function () { result.reject(); };
document.querySelector("head").appendChild(script);
return result.promise();
}
function loader(arrayName){
return {
load: function($q){
var deferred = $q.defer(),
map = arrayName.map(function(name) {
return loadScript(name+".js");
});
$q.all(map).then(function(r){
deferred.resolve();
});
return deferred.promise;
}
};
}
$routeProvider
.when('/view2', {
templateUrl: 'view2.html',
resolve: loader(['Controller2'])
})
.when('/bar',{
templateUrl: 'view1.html',
resolve: loader(['Controller1'])
})
.otherwise({
redirectTo: document.location.pathname
});
}]);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<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.min.js"></script>
</head>
<body ng-app="adminApp">
<!--Here is header code-->
<div class="LeftMenu">
<ul class="navbar">
<a href="#!/admindashboardhome" title="Dashboard"><li>
<span>Dashboard</span></li>
</a>
<a href="#!/examinationhalltickets" title="Declaration"><li>
<span>Examination Form</span></li>
</a>
<a href="#!/collegedetails" title="Declaration"><li>College
Details</li>
</a>
</ul>
</div>
<!--followed by footer code-->
<div data-ng-view> <!--ng-view-->
</div>
<!--Here i am loading all controllers and services related to application-->
<script
src="app.js">
</script>
<!-- And many more in same fashion-->
</body>
</html>
Controller 1.js
(function(val){
'use strict';
angular.module('Controller1App', [])
.controller('Controller1', ['$http','$rootScope','$scope','$window', function($http,$rootScope, $scope, $window){
//Your code goes here
}])
})(this);
Controller 2.js
(function(val){
'use strict';
angular.module('Controller2App', [])
.controller('Controller2', ['$http','$rootScope','$scope','$window', function($http,$rootScope, $scope, $window){
//Your code goes here
}])
})(this);
Refer https://plnkr.co/edit/cgkgG5PCwJBVOhQ1KDW2?p=preview

Why do I keep getting the $[injector:modulerr] uncaught error when all dependencies have been injected?

Below is my index.html page which has two buttons which links to 2 different views which i intend to show using angular routing.
Below is my
HTML
<!DOCTYPE html>
<html>
<head>
<title>PR_APP</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular-route.js"></script>
<script src="js/main.js"></script>
<script src="js/services.js"></script>
</head>
<body ng-app="new_pr_app">
<h2>Please select an option</h2><br>
<div ng-controller="view_controller">
<button id="view_details" ng-click="view()">View Details</button>
</div>
<div ng-controller="update_controller">
<button id="update_details" ng-click="update()">Update Details</button>
</div>
<div ng-view>
</div>
</body>
Below is my main.js file which houses both above mentioned controller and logic for angular routing.
main.js
var app = angular.module('new_pr_app', ['ngRoute']);
app.config('$routeProvider','$locationProvider', function($routeProvider,$locationProvider){
$routeProvider.when("/update",
{
templateUrl:"update.html",
controller: "update_controller"
})
.when("/view",
{
templateUrl: "view.html",
controller: "view_controller"
});
});
app.controller("view_controller",function($scope, $location, http_factory){
$scope.view = function(){
$location.path("/view");
}
$scope.result =[];
http_factory.get_request().then(function(response){
$scope.result = response.data;
});
});
app.controller("update_controller",function($scope, $location, http_factory){
$scope.update_details = function(){
$location.path("/update");
}
$scope.names = [];
http_factory.get_request().then(function(response){
$scope.names = response.data;
});
});
I have another file called services.js which has a service factory to get details from a json file using an http get.
My only problem seems to be in the above main.js which gives the error below everytime index.html loads
angular.js:88 Uncaught Error: [$injector:modulerr]
Your config is wrong. You pass in a string as the first (and second argument), while the .config(..) function, expects a function to be passed in (or an array).
In your code, you simply forgot to wrap the arguments in an array. Here's how it should look:
app.config(['$routeProvider','$locationProvider',
function($routeProvider,$locationProvider){
$routeProvider.when("/update",
{
templateUrl:"update.html",
controller: "update_controller"
})
.when("/view",
{
templateUrl: "view.html",
controller: "view_controller"
});
}]);
Note the [ and ] wrapping the content
You can check with below code.
<!DOCTYPE html>
<html>
<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.js/1.6.5/angular-route.js"></script>
<body ng-app="new_pr_app">
<h2>Please select an option</h2><br>
<div ng-controller="view_controller">
<button id="view_details" ng-click="view()">View Details</button>
</div>
<div ng-controller="update_controller">
<button id="update_details" ng-click="update_details()">Update Details</button>
</div>
<div ng-view>
</div>
<script>
var app = angular.module('new_pr_app', ['ngRoute']);
app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider){
$routeProvider.when("/update",
{
template:"update template"
// controller: "update_controller"
})
.when("/view",
{
template: "view template"
// controller: "view_controller"
});
}]);
app.controller("view_controller",function($scope, $location){
$scope.view = function(){
$location.path("/view");
}
});
app.controller("update_controller",function($scope, $location){
$scope.update_details = function(){
$location.path("/update");
}
});
</script>
</body>
</html>

Angularjs - $routerProvider's 'when' function and 'templateUrl' navigate to 'wrong' path?

My dir's structure is like:
---/public
|
---index.html
---shop.html
|
---/js
|
---index.js
---index_controller.js
---/lib
---/css
---/plugins
|
---...
my index.html:
<!doctype html>
<html class="signin no-js" lang="">
<head>
<meta charset="utf-8">
<meta name="description" content="Flat, Clean, Responsive, application admin template built with bootstrap 3">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<title>Index</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/themify-icons.css">
<link rel="stylesheet" href="css/animate.min.css">
<link rel="stylesheet" href="css/skins/palette.css">
<link rel="stylesheet" href="css/fonts/font.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/lib/angular/angular.js"></script>
<script src="js/lib/angular/angular.min.js"></script>
<script src="js/lib/angular/angular-route.js"></script>
<script src="js/lib/angular/angular-route.min.js"></script>
<script src="js/index_controller.js"></script>
<script src="js/index.js"></script>
<script src="plugins/modernizr.js"></script>
</head>
<body class="bg-primary" ng-app="myApp.index">
<div class="cover" style="background-image: url(img/cover3.jpg)"></div>
<div class="overlay bg-primary"></div>
<div class="center-wrapper">
<div class="center-content">
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4">
<section class="panel bg-white no-b">
<ul class="switcher-dash-action">
<li class="active">Index</li>
</ul>
<div class="p15" ng-controller="IndexCtrl">
<form role="form" >
<div >
<button class="btn btn-primary btn-lg btn-block" ng-click='testRoute()'>
TestRoute
</button>
</div>
</form>
</div>
</section>
<p class="text-center">
Copyright ©
<span id="year" class="mr5"></span>
</p>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var el = document.getElementById("year"),
year = (new Date().getFullYear());
el.innerHTML = year;
</script>
</body>
</html>
And shop.html renders the following: (only for test use):
SHOP
And index_controller.js is :
function IndexCtrl($scope, $http, $location, $route, $window) {
$scope.testRoute = function() {
console.log(">>>TestRoute>>>");
$location.url('/shop');
}
}
function ShopCtrl() {
console.log("ShopCtrl");
}
And index.js:
'use strict';
//Angular-js
var module = angular.module('myApp.index', ['ngRoute']);
module.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/shop', {templateUrl: 'shop.html', controller: ShopCtrl
});
}]);
/*My Controllers*/
module.
controller('IndexCtrl', ['$scope', '$http', '$location', '$route', '$window', IndexCtrl]);
module.
run([
'$rootScope', '$location',
function($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
var nextTemplate = next.templateUrl;
var nextController = next.controller;
console.log("location.path:" + $location.path());
console.log('Template Starting to leave %s to go to %s\n', "", nextTemplate);
console.log('Controller Starting to leave %s to go to %s\n', "", nextController);
});
}
]);
And when I type "http://localhost:6001/index.html" in Chrome's address bar, it renders:
After clicking Test Route button, it changes to:
Only the url address changes, and it seems strange:
"http://localhost:6001/index.html#/shop"
Whereas I need
"http://localhost:6001/shop"
Chrome's console shows:
My problem is: how to render shop.html and how to navigate to /guoguo path properly, using code like:
$routeProvider.when('/shop', {templateUrl: 'shop.html', controller: ShopCtrl
});
I am pretty new to Angular. Maybe I am not thinking in the angularjs approach. Thanks for your points.
It is a mix of issues for your .html# being shown. Try this.
1: Add in the first line of head tags
<head><base href="/">
...
</head>`
2: Use this $locationProvider.html5Mode(true);
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/',{
templateUrl: 'views/home.html',
controller:'homeCtrl'
})
.when('/about',{
templateUrl: 'views/about.html',
controller:'aboutCtrl'
})
.otherwise({
redirectTo: '/home'
});
$locationProvider.html5Mode(true);
});
This should remove the # from the page. But in your server make index.html as the default file serving for the path http://localhost:6001/ then it will load http://localhost:6001/index.html as http://localhost:6001/
I finaly get to know that AngularJS is a SPA(Single Page App) based framwork. If I simply jump to another html, the page will load another ng-app, which has no relation to origin app(the bootstrap has been restarted).
What solution I take is to use ng-view inside the index html. It allows to load different ng-view(which is in '<div></div>' from other html file), and config the routeProvider by declaring template url and controller.
I will paste the complete code later, thanks for you all !!!

angular ng-click on list item not firing

Still learning angular, I would like to tap on an item from a list and show alert with the name of the item that was tapped.
In mainMenu.html ng-click is registered with the list element ng-click="mainMenuSelection(item.name), but the alert(name) is not being called in controllers.js
What am I doing wrong? Thanks
I also noticed the Google Chrome Sources does not show the views folder which contains mainMenu.html as per the second image.
//---app.js-----------------------------------------------
(function () {
'use strict';
angular
.module('angApp', ['ngRoute'])
.config(['$routeProvider', routeProvider]);
})();
function routeProvider ($routeProvider) {
$routeProvider.when('/list', {
templateUrl: 'views/mainMenu.html',
controller: 'MainMenuCtrl'
}).otherwise({ //home page
redirectTo: '/list'
});
}
angular.element(document).ready(function () {
angular.bootstrap(document, ['angApp']);
});
//---controllers.js-----------------------------------------------
angular
.module('angApp')
.controller('MainMenuCtrl', ['$scope', '$http', MainMenuCtrl]);
function MainMenuCtrl ($scope, $http) {
$http.get('js/mainMenu.json').then(
function (response) {
$scope.menuItems = response.data;
},
function (error) {
alert("http error");
}
)
$scope.mainMenuSelection = function(item) {
alert(item);
}
}
//---headerCtrl.js-----------------------------------------------
angular
.module('angApp')
.controller('HeaderCtrl', ['$scope', HeaderCtrl]);
function HeaderCtrl() {
var vm = this;
vm.title = "Tap left menu \u2630";
vm.headerTitle = setHeaderTitle;
function setHeaderTitle(title) {
vm.title = title;
}
}
//---index.html-----------------------------------------------
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/index.css">
<base href="http://localhost:63342/an1/">
<script src="angular.js"></script>
<script src="angular-route.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers/controllers.js"></script>
<script src="js/controllers/headerCtrl.js"></script>
<meta name="viewport" content="width=device-width" />
</head>
<body>
<main ng-view></main>
</body>
</html>
//---mainMenu.html-----------------------------------------------
<section class="mainMenu">
<ul>
<li ng-repeat="item in menuItems" ng-click="mainMenuSelection(item.name)">
<image src="images/{{item.image}}.png"></image>
{{item.name}}
</li>
</ul>
</section>
I created a fiddle with a working example close to what you want.
Obviously, I have a much pared down version for the sake of brevity.
http://jsfiddle.net/frishi/U3pVM/21624/
(function () {
'use strict';
angular
.module('angApp', [])
.controller("MainMenuCtrl", MainMenuCtrl)
})();
function MainMenuCtrl ($scope, $http) {
$scope.menuItems = [{
name:"Tom"},
{name: "Harry"},
{name: "Wiley"}
]
$scope.mainMenuSelection = function(item) {
alert(item);
}
}
Markup:
<div ng-app="angApp">
<section class="mainMenu" ng-controller="MainMenuCtrl">
<ul>
<li ng-repeat="item in menuItems" ng-click="mainMenuSelection(item.name)">
<image src="images/{{item.image}}.png" />
{{item.name}}
</li>
</ul>
</section>
</div>
I used a hard-coded JSON array of objects.
I also don't bootstrap the app the way you do.
There is too little information that your question provides, as to what could be the fault. Follow the example as specified in the fiddle, and if that doesn't work, reply with more details.
Here is my version in Plunker. I was trying to follow your file structure.
Make sure that <body ng-app="angApp"> is there, thats only one thing that I've added (I now it looks too trivial...)
EDIT: adding Git repo
Git repo with working code => clone => cd to directory => npm instal = npm start => files will be served on port:63342 (serving file using node sever in order to replicate environment where issue is happening)

Busy Icon keeps running - AngularJS

I have implemented a code to show a busy icon and this is it
angular.module("app", [])
.controller('UploadCtrl', function ctrl ($scope, $timeout) {
$scope.busy = false;
$scope.submit = function () {
$scope.busy = true;
// pretend to make an http call...
$timeout(function () {
$scope.busy = false;
}, 10000);
};
});
This is the index.html file
<!DOCTYPE html>
<html>
<head>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet" type="text/css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.14/angular.min.js"></script>
<script src="app.js"></script>
<meta charset="utf-8">
<title>Busy Runner</title>
</head>
<body ng-app="app" ng-controller="ctrl">
<button ng-disabled="busy" ng-click="submit()">Submit <i class="fa fa-spinner fa-spin" ng-show="busy"></i></button>
</body>
</html>
When I run the code the busy loader keeps running. Please what could be wrong.
This is the plunk I have made.
view plunk
You reference a controller which not exists. Fix the HTML code
<body ng-app="app" ng-controller="UploadCtrl">
angular.module("app", [])
.controller('UploadCtrl', function ctrl ($scope, $timeout) {
$scope.busy = false;
In the above code you have name your controller as 'UploadCtrl' ,where as, in HTML file
<body ng-app="app" ng-controller="ctrl">
controller is 'ctrl' , due to which it can't load the controller hence the angular part is not executed.
Change your app.js to
angular.module("app", [])
.controller('ctrl', function ($scope, $timeout) {..}
View plunkr
Also I removed ng-disabled from <button ng-disabled="busy" ng-click="submit()">Submit since you are already using $scope.busy = false; as soon as script loads.
Checkout ngController .

Resources