Page routing not exactly how I intended - angularjs

I have following code below where I used Angular Routing to direct users to new registration forms. The app works like this. The user sees a webpage which asks them to make a choice between a "digital quote" or "screen quote" by clicking the appropriate button. Once the button is clicked it should direct it to another page which shows the appropriate registration form. In terms of the different registration forms, I have that all built. But I have one big problem in terms of functionality. When the user clicks the button it should load the registration in a different page. I am not sure how to do that. Right not I am using an ng-view directive which means that the buttons and the initial questions still remain. My objective is that once you click the button, all you see are the corresponding/different registration pages. Any help or direction would be greatly appreciated. I don't believe Angular can solve this.
Thank you
the main page-> index.html
<html ng-app="myHome">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home Page</title>
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.css"/>
<link rel="stylesheet" href="/css/redirect.css"/>
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"> </script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script><!--This is to call Angular JS-->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.js"></script>
<script src="/js/redirect.js"></script>
</head>
<body>
<div class="container">
<div class="row" id="rotate">
<div class="col-md-6 col-md-offset-3">
<img src="/css/Logo_75.png">
</div>
</div>
<div class="row">
<h1>WHAT TYPE OF QUOTE ARE YOU REQUESTING:</h1><br>
<h1>DIGITAL OR SCREEN QUOTE?</h1>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<button type="button" class="btn btn-success">DIGITAL QUOTE</button>
<button type="button" class="btn btn-success">SCREEN QUOTE</button>
</div>
</div>
</div>
<div class="container">
<div ng-view></div>
</div>
</body>
The angular JS file or the redirect.js file looks like this:
var app = angular.module('myHome', [ngRoute]);
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', { templateUrl: '/index.html' })
.when('/digital', { templateUrl: '/digital.html' })
.when('/screen', { templateUrl: '/screen.html' })
.otherwise({ redirectTo: '/' });
}]);
where digital.html is the registration form for the digital option and screen.html is the screen registration form option. If anyone wants to see those registration forms, I can paste those files as well. Thank you so much for your help.

When the user clicks the button it should load the registration in a
different page
Probably you can solve it in the next way.
Just get on button click new page from server.(remove # from href="#/digital") and create new route(/digital) in your server side application.

The only way to do that is to use anchor tag with target="blank". Angular is total SPA, so it will (ng-view) will never allow you to open the page in a new window (which I think you trying to do). It is better you use the <a> tag for your current need.

Related

How to use the same AngularJS controller across multiple MVC script files?

I have created an MVC project and added AngularJS-Material and all required files. I put the AngularJS App on the _Layout.cshtml page as I want to be able to display a toolbar throughout the project.
For each view I was planning on using a different controller but when I reference the controller in a new script file I get an error that says the controller is undefined.
The code below works fine and the only problems I get are when I try to add another view in the #RenderBody() section of the code. On each individual chstml file I am defining a new controller but keeping the same app.
Here is my layout file:
<!DOCTYPE html>
<html ng-app="bPST" ng-controller="layoutCtrl">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - My ASP.NET Application</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<link href="~/Content/angular-material.min.css" rel="stylesheet" />
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-animate.js"></script>
<script src="~/Scripts/angular-aria.js"></script>
<script src="~/Scripts/angular-messages.js"></script>
<script src="~/Scripts/angular-material/angular-material.js"></script>
<script src="~/Ang_Scripts/bpst.js"></script>
</head>
<body>
<div layout="column" layout-fill>
<md-toolbar>
<div class="md-toolbar-tools">
<span>Title </span>
<!-- fill up the space between left and right area -->
<span flex></span>
<md-button ng-click="sideBarFunctions()">Menu</md-button>
</div>
</md-toolbar>
<md-sidenav ng-cloak class="md-sidenav-left md-whitefram-z2" md-component-id="left" md-is-open="sideBarOpen">
<div layout="column" layout-align="space-around stretch">
<md-toolbar>
<h2 style="text-align: center;">Menu</h2>
</md-toolbar>
<md-content layout-padding layout="column" layout-align="start">
</md-content>
</div>
</md-sidenav>
<md-content>
<div class="container body-content">
#RenderBody()
</div>
</md-content>
</div>
<hr />
<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>
#Scripts.Render("~/bundles/jquery")
#*#Scripts.Render("~/bundles/bootstrap")*#
#RenderSection("scripts", required: false)
login.js:
var bApp = angular.module('bPST', ['ngMaterial']);
bApp.controller('loginCTRL',function($scope) {
$scope.message = "Login";
});
So the problem was more with the way that I was creating the application in the js file.
I was doing this.
var bPSTApp = angular.module('bPST', ['ngMaterial']);
Then creating the controller like this.
bPSTApp.controller('layoutCtrl', function ($scope) {
//Add coding here
};
when I changed it up to this, it started working.
angular.module('bPST').controller('layoutCtrl', function ($scope) {
//Add coding here
});
Now all I need to do is reference the App in each controller file instead of trying to reference the variable that I was setting in the main JS file.
Also, since I am using the login.js on the login cshtml file, it was only being referenced in that view.
I do get that AngularJS and AngularJS Material is good for Single Page Applications, but there are functions that I want to use that make my application look good and function the way I want.
Got to love newbie mistakes.

Directing to right form based on whcih button is clicked

I am trying to use the MEAN stack for the following assignment.
I have created several registration forms which work fine. One registration page is index.html(which through Angular loads several views/tabs within it, so they are multi-paged) and another one, index2.html.
There is also a main webpage that I have created which is a simple page that
has the company's logo, name and two buttons.
Clicking on each button will direct you to a different registration
form(either index.html or index2.html).
This last functionality is where I am having problems. How do I connect the main page to the different registration forms? In other words, how do I redirect the user to the right registration page when they click the corresponding buttons? Should I use node to route to the correct registration page or use Angular Route? As you can see, currently I am attempting to use Angular Route but am unsure if that is the right tool for this purpose. Any help and direction would be greatly appreciated.
Thank you
Here is the code that I have for the main page(home.html):
<html ng-app="myHome">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Home Page</title>
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/css/bootstrap.min.css" />
<link rel="stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.css"/>
<link rel="stylesheet" href="/css/redirect.css"/>
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"> </script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script><!--This is to call Angular JS-->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular-route.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.5/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.8.3/ng-table.min.js"></script>
<script src="/js/redirect.js"></script>
</head>
<body>
<div class="container">
<div class="row" id="rotate">
<div class="col-md-6 col-md-offset-3">
<img src="/css/Logo_75.png">
</div>
</div>
<div class="row">
<h1>WHAT TYPE OF QUOTE ARE YOU REQUESTING:</h1><br>
<h1>DIGITAL OR SCREEN QUOTE?</h1>
</div>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<button type="button" class="btn btn-success">DIGITAL QUOTE</button>
<button type="button" class="btn btn-success">SCREEN QUOTE</button>
</div>
</div>
</div>
</body>
This is the angular JS file:
var app = angular.module('myHome', [ngRoute]);
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/digital', {
templateUrl: '/index.html'
}).
when('/screen', {
templateUrl: '/index2.html'
}).
otherwise({
redirectTo: '/home.html'
});
}]);
where index.html is the registration form for the "digital" option and index2.html is the registration form for the "screen" option. If anyone needs to see the code for those registration forms, please let me know
Thanks
You need to use ng-view directive.
Change your container to look like this
<div class="container">
<div ng-view></div>
</div>
Place the content you had in there into template index.html and rename your index.html to digital.html and index2.html to screen.html to correspond with route names (well it's a recommendation since it makes a lot of sense I believe)
And change the routing to this
var app = angular.module('myHome', [ngRoute]);
.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', { templateUrl: '/index.html' })
.when('/digital', { templateUrl: '/digital.html' })
.when('/screen', { templateUrl: '/screen.html' })
.otherwise({ redirectTo: '/' });
}]);

Why are the DOM plain html elements rendered only after my Angular APP is done loading?

I am trying to display a plain html/css loading spinner on first load in my Angular APP. The spinner code is included in my index.html.
However, the dom seems not to be rendered until my angularjs APP starts kicking in, causing a very lengthy display of a white screen until this finally happens. Is there any way to prevent that?
I would like to understand how to load my plain html/css spinner right after the css code in the head is done loading so as to improve user experience.
Test on webpagetest.org seem to confirm this diagnosis (the /settings, /introductions, /menus lines are all calls to an external API done by an AngularJS service before render):
Here is a simplified version of my build code:
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<title ng-bind="($title || 'Home') + ' - WalktheChat'">WalktheChat</title>
<link rel="stylesheet" href="styles/lib.css">
<link rel="stylesheet" href="styles/app.css">
</head>
<body>
<div id="base-container" ng-controller="Shell as main">
<div ng-include="'app/layout/header.html'"></div>
<div id="content" ui-view ng-cloak autoscroll="true"></div>
<div ng-include="'app/layout/footer.html'"></div>
</div>
<!-- This is the spinner I would like to display on first load -->
<div ng-show="::false" class="spinner-container">
<div class="spinner sk-spinner sk-spinner-pulse"></div>
</div>
<script src="js/lib.js"></script>
<script src="js/app.js"></script>
</body>
</html>
whatever the complexity of your application,all your controllers are within the same angular application, all scopes within the same application inherits from the same root, whatever you define on the $rootScope will be available to all child scopes.
we have two ways to resolve this problem:
use $broadcast(), $emit() and $on() that facilitate event driven publisher-subscriber model for sending notifications and passing data between your controllers.(professional solution)
declare $rootScope variable and watching changement.(simple way)
It turns out the problem was coming from "render-blocking javascript", I had to add the "async" tag to my JS to fix it.
When adding async to both my lib.js and app.js, I had an issue with app.js loading before angular scripts were loaded (thus causing the APP to throw an error). In order to solve this issue, I combined my lib.js and app.js into one single file and then added the async tag.
My final build code looks like that (the magic happens on the final "script" tag):
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1" />
<title ng-bind="($title || 'Home') + ' - WalktheChat'">WalktheChat</title>
<link rel="stylesheet" href="styles/lib.css">
<link rel="stylesheet" href="styles/app.css">
</head>
<body>
<div id="base-container" ng-controller="Shell as main">
<div ng-include="'app/layout/header.html'"></div>
<div id="content" ui-view ng-cloak autoscroll="true"></div>
<div ng-include="'app/layout/footer.html'"></div>
</div>
<!-- This is the spinner I would like to display on first load -->
<div ng-show="::false" class="spinner-container">
<div class="spinner sk-spinner sk-spinner-pulse"></div>
</div>
<!-- This app.js now also contains lib.js from my question !-->
<script src="js/app.js" async></script>
</body>
</html>

templateUrl for AngularJS (routing)/MVC application never loads templates

We are attempting to create a MVC/AngularJS mini-SPA site using various links found on tutorial sites and others like: AngularJS routing in MVC application with templates. However, clicking on the links appear to load the whole page every time, and the templates are never loaded. I am sure I'm missing something simple, but can't figure it out.
My _Layout.cshtml looks like:
<!DOCTYPE html>
<html ng-app="registrationModule">
<head>
<meta charset=" utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
#Scripts.Render("~/bundles/jquery")
<script src="~/Scripts/angular.min.js"></script>
<script src="~/Scripts/angular-resource.min.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<script src="~/GrextScripts/registration-module.js"></script>
<script src="~/GrextScripts/user-repository.js"></script>
<script src="~/GrextScripts/user-controller.js"></script>
#RenderSection("SectionInHeader", required: false)
</head>
<body>
<header>
<div class=" content-wrapper">
<div class="float-left">
<p class="site-title">
GREXT
</p>
</div>
<div class="float-right">
<nav>
<ul id="menu">
<li>Home</li>
<li>Users</li>
</ul>
</nav>
</div>
</div>
</header>
#RenderBody()
#RenderSection("scripts", required: false)
</body>
</html>
The ControlPanel/Index.cshtml (the {{5+5}} renders properly as a "10" on the page, this was just to see if the AngularJS was working
#{
}
<div ng-view>
{{5+5}}
</div>
registration-module.js
var registrationModule = angular.module("registrationModule", ["ngRoute", "ngResource"])
.config(function($routeProvider, $locationProvider) {
$routeProvider.when("/ControlPanel/Users", {
templateUrl: "/templates/users/all.html",
controller: "userController"
});
$locationProvider.html5Mode(true);
});
user-controller.js
registrationModule.controller("UserController", function($scope, userRepository, $location) {
$scope.users = userRepository.get();
});
And last, the template: /templates/users/all.html
{{1+1}}
<table>
<tr><td>User Name</td></tr>
<tr ng-repeat="user in users">
<td>{{user.UserName}}</td>
</tr>
</table>
As mentioned, when I click on the Users link in the page, the whole page reloads and the template all.html is not loaded as I expect it.
#aaronfrost's comment made me re-check my javascript console more thoroughly and found that I need to include a
<base href="/" />
in the < head> tag of my document. Adding this causes everything to work.
Not sure, but the problem may be that you declared the controller as "UserController" with a capital "U", but in the routeProvider you specified it with a lowercase "u" as "userController".
I am guessing that you have an error in the console, so you might want to check there.
Change the routeProvider to use "UserController" instead of "userController" and it should work.

implementing a list view as native app with ionic framework angularjs and cordova

Hello I'm trying to implement a listview application for mobile devices via cordova angularjs and ionic framework.
The application should show a clickable list view for example for cars. If the user clicks one of the items of the list, a details view with details of the specific car should be opened.
My index.html looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="js/app.js"></script>
</head>
<body ng-app="starter">
<ion-pane>
<ion-header-bar class="bar-stable">
<h1 class="title">Order spare parts:</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<a href="#detailsView:1">
<div class="item item-button-right">
Audi A4
</div>
</a>
<a href="#detailsView:2">
<div class="item item-button-right">
BMW 320
</div>
</a>
<a href="#detailsView:3">
<div class="item item-button-right">
Mercedes CLA
</div>
</a>
</div>
</ion-content>
</ion-pane>
</body>
</html>
My app.js:
var app = angular.module('starter', ['ionic']);
app.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
});
In the detailsview it should show up a checkboxlist similar to this:
<ul class="list">
<li class="item item-checkbox">
<label class="checkbox">
<input type="checkbox">
</label>
Wheels
</li>
</ul>
The data is for example given in json format:
var cars = [
{"id":"1", "name":"Audi", "spareParts":[{"id":"1", "name": "wheel"}, {"id":"2", "name": "Steuergerät"}]},
...
];
My problem is that some page navigation things that are working on the browser simulation are not working in my iOS simulator. I tried the recommend way with <script id="detailsView.html" type="text/ng-template"> tags and routing configurations in the controller but couldn't get it to work on the iOS simulator.
I tried a lot of codepen examples to bring the routing to work but it always fails hard. For example the codepen: http://codepen.io/mhartington/pen/CAxFG only shows my a white screen on my browser simulation and iOS simulator. I copied the code one on one but it seems that I am doing something wrong. The only code that I could bring to work in the iOS simulator is the index.html above.
So how to do this the right way if the app should be a native application build with ionic in the end?
you are missing the ui-router code here.
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: "/home",
templateUrl: "home.html"
})
.state('details', {
url: "/details/:id",
templateUrl: "details.html",
controller :function($stateParams, $scope) {
$scope.params = $stateParams;
}
});
$urlRouterProvider.otherwise("/home");
})
A complete sample is posted here
http://codepen.io/aaronksaunders/pen/xbjOor?editors=101

Resources