Add login page to existing angularjs metronic theme - html

I am using metronic angularjs theme for creating a web app. But that theme doesn't have a login page and I want to create one for user login through facebook and normal login.
I was wondering how can I add a login page to an existing theme as I am new to angularjs.
I have tried creating a login master file at the same path where index file exists but I think I am doing something wrong.
This theme is using index file as a core for all the views and hence have header, footer and sidebar defined in the same for all the html files but I don't want to use index file as core for login page as we don't header and all for login screen.
index.html code:-
<!DOCTYPE html>
<html lang="en" data-ng-app="MetronicApp">
<!-- BEGIN HEAD -->
<head>
<title data-ng-bind="'abc | ' + $state.current.data.pageTitle"></title>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<meta content="" name="description"/>
<meta content="" name="author"/>
<!-- BEGIN GLOBAL MANDATORY STYLES -->
<link href="http://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700&subset=all" rel="stylesheet" type="text/css"/>
<link href="../../../assets/global/plugins/font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
<link href="../../../assets/global/plugins/simple-line-icons/simple-line-icons.min.css" rel="stylesheet" type="text/css"/>
<link href="../../../assets/global/plugins/bootstrap/css/bootstrap.min.css" rel="stylesheet" type="text/css"/>
<link href="../../../assets/global/plugins/uniform/css/uniform.default.css" rel="stylesheet" type="text/css"/>
<!-- END GLOBAL MANDATORY STYLES -->
<!-- BEGIN DYMANICLY LOADED CSS FILES(all plugin and page related styles must be loaded between GLOBAL and THEME css files ) -->
<link id="ng_load_plugins_before"/>
<!-- END DYMANICLY LOADED CSS FILES -->
<!-- BEGIN THEME STYLES -->
<!-- DOC: To use 'rounded corners' style just load 'components-rounded.css' stylesheet instead of 'components.css' in the below style tag -->
<link href="../../../assets/global/css/components.css" id="style_components" rel="stylesheet" type="text/css"/>
<link href="../../../assets/global/css/plugins.css" rel="stylesheet" type="text/css"/>
<link href="../../../assets/admin/layout2/css/layout.css" rel="stylesheet" type="text/css"/>
<link href="../../../assets/admin/layout2/css/themes/default.css" rel="stylesheet" type="text/css" id="style_color"/>
<link href="../../../assets/admin/layout2/css/custom.css" rel="stylesheet" type="text/css"/>
<!-- END THEME STYLES -->
<link rel="shortcut icon" href="favicon.ico"/>
</head>
<!-- END HEAD -->
<!-- BEGIN BODY -->
<body ng-controller="AppController" class="page-boxed page-header-fixed page-sidebar-closed-hide-logo page-container-bg-solid page-sidebar-closed-hide-logo page-on-load" ng-class="{'page-sidebar-closed': settings.layout.pageSidebarClosed}">
<!-- BEGIN PAGE SPINNER -->
<div ng-spinner-bar class="page-spinner-bar">
<div class="bounce1"></div>
<div class="bounce2"></div>
<div class="bounce3"></div>
</div>
<!-- END PAGE SPINNER -->
<!-- BEGIN HEADER -->
<div data-ng-include="'tpl/header.html'" data-ng-controller="HeaderController" class="page-header navbar navbar-fixed-top">
</div>
<!-- END HEADER -->
<div class="clearfix">
</div>
<!-- BEGIN CONTAINER -->
<div class="container">
<div class="page-container">
<!-- BEGIN SIDEBAR -->
<div data-ng-include="'tpl/sidebar.html'" data-ng-controller="SidebarController" class="page-sidebar-wrapper">
</div>
<!-- END SIDEBAR -->
<div class="page-content-wrapper">
<div class="page-content">
<!-- BEGIN STYLE CUSTOMIZER(optional) -->
<div data-ng-include="'tpl/theme-panel.html'" data-ng-controller="ThemePanelController" class="theme-panel hidden-xs hidden-sm">
</div>
<!-- END STYLE CUSTOMIZER -->
<!-- BEGIN ACTUAL CONTENT -->
<div ui-view class="fade-in-up">
</div>
<!-- END ACTUAL CONTENT -->
</div>
</div>
</div>
<!-- BEGIN FOOTER -->
<div data-ng-include="'tpl/footer.html'" data-ng-controller="FooterController" class="page-footer">
</div>
<!-- END FOOTER -->
</div>
<!-- END CONTAINER -->
<!-- BEGIN JAVASCRIPTS(Load javascripts at bottom, this will reduce page load time) -->
<!-- BEGIN CORE JQUERY PLUGINS -->
<!--[if lt IE 9]>
<script src="../../../assets/global/plugins/respond.min.js"></script>
<script src="../../../assets/global/plugins/excanvas.min.js"></script>
<![endif]-->
<script src="../../../assets/global/plugins/jquery.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/jquery-migrate.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/bootstrap-hover-dropdown/bootstrap-hover-dropdown.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/jquery-slimscroll/jquery.slimscroll.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/jquery.blockui.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/jquery.cokie.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/uniform/jquery.uniform.min.js" type="text/javascript"></script>
<!-- END CORE JQUERY PLUGINS -->
<!-- BEGIN CORE ANGULARJS PLUGINS -->
<script src="../../../assets/global/plugins/angularjs/angular.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/angularjs/angular-sanitize.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/angularjs/angular-touch.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/angularjs/plugins/angular-ui-router.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/angularjs/plugins/ocLazyLoad.min.js" type="text/javascript"></script>
<script src="../../../assets/global/plugins/angularjs/plugins/ui-bootstrap-tpls.min.js" type="text/javascript"></script>
<!-- END CORE ANGULARJS PLUGINS -->
<!-- BEGIN APP LEVEL ANGULARJS SCRIPTS -->
<script src="js/app.js" type="text/javascript"></script>
<script src="js/directives.js" type="text/javascript"></script>
<!-- END APP LEVEL ANGULARJS SCRIPTS -->
<!-- BEGIN APP LEVEL JQUERY SCRIPTS -->
<script src="../../../assets/global/scripts/metronic.js" type="text/javascript"></script>
<script src="../../../assets/admin/layout2/scripts/layout.js" type="text/javascript"></script>
<script src="../../../assets/admin/layout2/scripts/demo.js" type="text/javascript"></script>
<!-- END APP LEVEL JQUERY SCRIPTS -->
<script type="text/javascript">
/* Init Metronic's core jquery plugins and layout scripts */
$(document).ready(function() {
Metronic.init(); // Run metronic theme
Metronic.setAssetsPath('../../../assets/'); // Set the assets folder path
});
</script>
<!-- END JAVASCRIPTS -->
</body>
<!-- END BODY -->
</html>
app.js
var MetronicApp = angular.module("MetronicApp", [
"ui.router",
"ui.bootstrap",
"oc.lazyLoad",
"ngSanitize"
]);
MetronicApp.config(['$ocLazyLoadProvider', function($ocLazyLoadProvider) {
$ocLazyLoadProvider.config({
});
}]);
MetronicApp.config(['$controllerProvider', function($controllerProvider) {
$controllerProvider.allowGlobals();
}]);
MetronicApp.factory('settings', ['$rootScope', function($rootScope) {
var settings = {
layout: {
pageSidebarClosed: false, // sidebar state
pageAutoScrollOnLoad: 1000 // auto scroll to top on page load
},
layoutImgPath: Metronic.getAssetsPath() + 'admin/layout/img/',
layoutCssPath: Metronic.getAssetsPath() + 'admin/layout/css/'
};
$rootScope.settings = settings;
return settings;
}]);
MetronicApp.controller('AppController', ['$scope', '$rootScope', function($scope, $rootScope) {
$scope.$on('$viewContentLoaded', function() {
Metronic.initComponents();
});
}]);
MetronicApp.controller('HeaderController', ['$scope', function($scope) {
$scope.$on('$includeContentLoaded', function() {
Layout.initHeader(); // init header
});
}]);
MetronicApp.controller('SidebarController', ['$scope', function($scope) {
$scope.$on('$includeContentLoaded', function() {
Layout.initSidebar(); // init sidebar
});
}]);
MetronicApp.controller('ThemePanelController', ['$scope', function($scope) {
$scope.$on('$includeContentLoaded', function() {
Demo.init(); // init theme panel
});
}]);
MetronicApp.controller('FooterController', ['$scope', function($scope) {
$scope.$on('$includeContentLoaded', function() {
Layout.initFooter(); // init footer
});
}]);
MetronicApp.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
// Redirect any unmatched url
$urlRouterProvider.otherwise("/dashboard.html");
$stateProvider
// Dashboard
.state('dashboard', {
url: "/dashboard.html",
templateUrl: "views/dashboard.html",
data: {pageTitle: 'Admin Dashboard Template'},
controller: "DashboardController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before a LINK element with this ID. Dynamic CSS files must be loaded between core and theme css files
files: [
'../../../assets/global/plugins/morris/morris.css',
'../../../assets/admin/pages/css/tasks.css',
'../../../assets/global/plugins/morris/morris.min.js',
'../../../assets/global/plugins/morris/raphael-min.js',
'../../../assets/global/plugins/jquery.sparkline.min.js',
'../../../assets/admin/pages/scripts/index3.js',
'../../../assets/admin/pages/scripts/tasks.js',
'js/controllers/DashboardController.js'
]
});
}]
}
})
// AngularJS plugins
.state('fileupload', {
url: "/file_upload.html",
templateUrl: "views/file_upload.html",
data: {pageTitle: 'AngularJS File Upload'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'angularFileUpload',
files: [
'../../../assets/global/plugins/angularjs/plugins/angular-file-upload/angular-file-upload.min.js',
]
}, {
name: 'MetronicApp',
files: [
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// UI Select
.state('uiselect', {
url: "/ui_select.html",
templateUrl: "views/ui_select.html",
data: {pageTitle: 'AngularJS Ui Select'},
controller: "UISelectController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'ui.select',
insertBefore: '#ng_load_plugins_before',
files: [
'../../../assets/global/plugins/angularjs/plugins/ui-select/select.min.css',
'../../../assets/global/plugins/angularjs/plugins/ui-select/select.min.js'
]
}, {
name: 'MetronicApp',
files: [
'js/controllers/UISelectController.js'
]
}]);
}]
}
})
// UI Bootstrap
.state('uibootstrap', {
url: "/ui_bootstrap.html",
templateUrl: "views/ui_bootstrap.html",
data: {pageTitle: 'AngularJS UI Bootstrap'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'MetronicApp',
files: [
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// Tree View
.state('tree', {
url: "/tree",
templateUrl: "views/tree.html",
data: {pageTitle: 'jQuery Tree View'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/jstree/dist/themes/default/style.min.css',
'../../../assets/global/plugins/jstree/dist/jstree.min.js',
'../../../assets/admin/pages/scripts/ui-tree.js',
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// Form Tools
.state('formtools', {
url: "/form-tools",
templateUrl: "views/form_tools.html",
data: {pageTitle: 'Form Tools'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/bootstrap-fileinput/bootstrap-fileinput.css',
'../../../assets/global/plugins/bootstrap-switch/css/bootstrap-switch.min.css',
'../../../assets/global/plugins/jquery-tags-input/jquery.tagsinput.css',
'../../../assets/global/plugins/bootstrap-markdown/css/bootstrap-markdown.min.css',
'../../../assets/global/plugins/typeahead/typeahead.css',
'../../../assets/global/plugins/fuelux/js/spinner.min.js',
'../../../assets/global/plugins/bootstrap-fileinput/bootstrap-fileinput.js',
'../../../assets/global/plugins/jquery-inputmask/jquery.inputmask.bundle.min.js',
'../../../assets/global/plugins/jquery.input-ip-address-control-1.0.min.js',
'../../../assets/global/plugins/bootstrap-pwstrength/pwstrength-bootstrap.min.js',
'../../../assets/global/plugins/bootstrap-switch/js/bootstrap-switch.min.js',
'../../../assets/global/plugins/jquery-tags-input/jquery.tagsinput.min.js',
'../../../assets/global/plugins/bootstrap-maxlength/bootstrap-maxlength.min.js',
'../../../assets/global/plugins/bootstrap-touchspin/bootstrap.touchspin.js',
'../../../assets/global/plugins/typeahead/handlebars.min.js',
'../../../assets/global/plugins/typeahead/typeahead.bundle.min.js',
'../../../assets/admin/pages/scripts/components-form-tools.js',
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// Date & Time Pickers
.state('pickers', {
url: "/pickers",
templateUrl: "views/pickers.html",
data: {pageTitle: 'Date & Time Pickers'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before',
files: [
'../../../assets/global/plugins/clockface/css/clockface.css',
'../../../assets/global/plugins/bootstrap-datepicker/css/bootstrap-datepicker3.min.css',
'../../../assets/global/plugins/bootstrap-timepicker/css/bootstrap-timepicker.min.css',
'../../../assets/global/plugins/bootstrap-colorpicker/css/colorpicker.css',
'../../../assets/global/plugins/bootstrap-daterangepicker/daterangepicker-bs3.css',
'../../../assets/global/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css',
'../../../assets/global/plugins/bootstrap-datepicker/js/bootstrap-datepicker.min.js',
'../../../assets/global/plugins/bootstrap-timepicker/js/bootstrap-timepicker.min.js',
'../../../assets/global/plugins/clockface/js/clockface.js',
'../../../assets/global/plugins/bootstrap-daterangepicker/moment.min.js',
'../../../assets/global/plugins/bootstrap-daterangepicker/daterangepicker.js',
'../../../assets/global/plugins/bootstrap-colorpicker/js/bootstrap-colorpicker.js',
'../../../assets/global/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js',
'../../../assets/admin/pages/scripts/components-pickers.js',
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// Custom Dropdowns
.state('dropdowns', {
url: "/dropdowns",
templateUrl: "views/dropdowns.html",
data: {pageTitle: 'Custom Dropdowns'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load([{
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before',
files: [
'../../../assets/global/plugins/bootstrap-select/bootstrap-select.min.css',
'../../../assets/global/plugins/select2/select2.css',
'../../../assets/global/plugins/jquery-multi-select/css/multi-select.css',
'../../../assets/global/plugins/bootstrap-select/bootstrap-select.min.js',
'../../../assets/global/plugins/select2/select2.min.js',
'../../../assets/global/plugins/jquery-multi-select/js/jquery.multi-select.js',
'../../../assets/admin/pages/scripts/components-dropdowns.js',
'js/controllers/GeneralPageController.js'
]
}]);
}]
}
})
// Advanced Datatables
.state('datatablesAdvanced', {
url: "/datatables/advanced.html",
templateUrl: "views/datatables/advanced.html",
data: {pageTitle: 'Advanced Datatables'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/select2/select2.css',
'../../../assets/global/plugins/datatables/plugins/bootstrap/dataTables.bootstrap.css',
'../../../assets/global/plugins/datatables/extensions/Scroller/css/dataTables.scroller.min.css',
'../../../assets/global/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.min.css',
'../../../assets/global/plugins/select2/select2.min.js',
'../../../assets/global/plugins/datatables/all.min.js',
'js/scripts/table-advanced.js',
'js/controllers/GeneralPageController.js'
]
});
}]
}
})
// Ajax Datetables
.state('datatablesAjax', {
url: "/datatables/ajax.html",
templateUrl: "views/datatables/ajax.html",
data: {pageTitle: 'Ajax Datatables'},
controller: "GeneralPageController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/select2/select2.css',
'../../../assets/global/plugins/bootstrap-datepicker/css/bootstrap-datepicker3.min.css',
'../../../assets/global/plugins/datatables/plugins/bootstrap/dataTables.bootstrap.css',
'../../../assets/global/plugins/bootstrap-datepicker/js/bootstrap-datepicker.min.js',
'../../../assets/global/plugins/select2/select2.min.js',
'../../../assets/global/plugins/datatables/all.min.js',
'../../../assets/global/scripts/datatable.js',
'js/scripts/table-ajax.js',
'js/controllers/GeneralPageController.js'
]
});
}]
}
})
// User Profile
.state("profile", {
url: "/profile",
templateUrl: "views/profile/main.html",
data: {pageTitle: 'User Profile'},
controller: "UserProfileController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/bootstrap-fileinput/bootstrap-fileinput.css',
'../../../assets/admin/pages/css/profile.css',
'../../../assets/admin/pages/css/tasks.css',
'../../../assets/global/plugins/jquery.sparkline.min.js',
'../../../assets/global/plugins/bootstrap-fileinput/bootstrap-fileinput.js',
'../../../assets/admin/pages/scripts/profile.js',
'js/controllers/UserProfileController.js'
]
});
}]
}
})
// User Profile Dashboard
.state("profile.dashboard", {
url: "/dashboard",
templateUrl: "views/profile/dashboard.html",
data: {pageTitle: 'User Profile'}
})
// User Profile Account
.state("profile.account", {
url: "/account",
templateUrl: "views/profile/account.html",
data: {pageTitle: 'User Account'}
})
// User Profile Help
.state("profile.help", {
url: "/help",
templateUrl: "views/profile/help.html",
data: {pageTitle: 'User Help'}
})
// Todo
.state('todo', {
url: "/todo",
templateUrl: "views/todo.html",
data: {pageTitle: 'Todo'},
controller: "TodoController",
resolve: {
deps: ['$ocLazyLoad', function($ocLazyLoad) {
return $ocLazyLoad.load({
name: 'MetronicApp',
insertBefore: '#ng_load_plugins_before', // load the above css files before '#ng_load_plugins_before'
files: [
'../../../assets/global/plugins/bootstrap-datepicker/css/datepicker3.css',
'../../../assets/global/plugins/select2/select2.css',
'../../../assets/admin/pages/css/todo.css',
'../../../assets/global/plugins/bootstrap-datepicker/js/bootstrap-datepicker.min.js',
'../../../assets/global/plugins/select2/select2.min.js',
'../../../assets/admin/pages/scripts/todo.js',
'js/controllers/TodoController.js'
]
});
}]
}
})
}]);
MetronicApp.run(["$rootScope", "settings", "$state", function($rootScope, settings, $state) {
$rootScope.$state = $state; // state to be accessed from view
}]);
It would be great if someone can help me with this.
Thanks

Introduction:
Unfortunately almost every theme bought on internet should be "ready to use" but in reality are filled of jquery plugins and needs to be organized with a different architecture: managing dependencies with bower/npm, have good gulp scripts to manage most used tasks, removing all jquery code from controllers, substituting jquery dependencies with angular dependencies and removing all components that you will not use.
Answer:
No, you don't need a "login master file" (or index.html and login.html) if you well organize the routes. Angular is a Single Page Application framework and not a Two Page Application :)
Usually I use the ui-router and I prefere organize states in two main groups public and private and then I create many child states of them:
$stateProvider
.state('public', {
abstract: true,
template: "<ui-view/>"
})
.state('public.site', {
url: '/site',
controllerAs: 'vm',
controller: 'SiteCtrl',
templateUrl: 'site/_site.html'
})
.state('public.site.home', {
url: '/',
controllerAs: 'vm',
controller: 'HomeCtrl',
templateUrl: 'home/_home.html'
})
.state('public.site.product', {
url: '/products',
controllerAs: 'vm',
controller: 'ProductCtrl',
templateUrl: 'product/_product.html'
})
.state('public.login', {
url: '/login',
controllerAs: 'vm',
controller: 'LoginCtrl',
templateUrl: 'login/_login.html'
});
$stateProvider
.state('private', {
abstract: true,
template: "<ui-view/>"
})
.state('private.admin', {
url: '/admin',
controllerAs: 'admin',
controller: 'AdminCtrl',
templateUrl: 'admin/_admin.html'
})
.state('private.admin.category', {
url: '/categories',
controllerAs: 'vm',
controller: 'CategoryCtrl',
templateUrl: 'category/_category.html'
})
.state('private.admin.product', {
abstract: true,
url: '/products',
template: '<ui-view/>'
})
.state('private.admin.product.list', {
url: '/',
controllerAs: 'vm',
controller: 'ProductListCtrl',
templateUrl: 'product/_product.list.html'
})
.state('private.admin.product.edit', {
url: '/edit/{id}',
controllerAs: 'vm',
controller: 'ProductEditCtrl',
templateUrl: 'product/_product.edit.html'
});
The states public.site and private.admin are important because are the parent of all public or private routes. Will be the parent layout where I place the header, menu, navigation, footer etc. For example my _admin.html is look like:
<div id="header">
HEADER ADMIN
</div>
<aside id="menu">
<ul>
<li>
<a ui-sref="private.admin.category">Categories</a>
</li>
<li>
<a ui-sref="private.admin.product.list">Products</a>
</li>
...
...
</ul>
</aside>
<div ui-view class="content">
<!-- admin child states will be injected here -->
</div>
Generally the login page has a different layout of the site or the admin panel. There are no header, site menu, no navigation etc.. only there is a login form. For this reason the login state public.login is not a child of public.site.
And finally I show you my index.html. Is a clean/empty body html with no html code:
<html ng-app="app">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title page-title>Default Title</title>
<link rel="stylesheet" href="path/of/styles/abcd.css" />
<!-- all css files included here -->
</head>
<body ng-controller="MainCtrl as main">
<div ui-view>
<!-- all states will be injected here -->
</div>
<script src="path/of/scripts/bcds.js"></script>
<!-- all js files included here -->
</body>
</html>
Originally answered here

Related

window.MathJax is undefined?

Hi i Have a problem with MathJax library. I want to display the mathjax formula on the screen, but when I use window.MathJax I get the error that it is undefined. Here is how I installed the MathJax in my html file:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Test</title>
<link rel="icon" href="/icons/favicon.ico" type="image/x-icon">
<link rel="shortcut icon" href="/icons/favicon.ico" type="image/x-icon">
<!-- inject:css -->
<!-- endinject -->
<script type="text/x-mathjax-config">
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
};
MathJax.Hub.Config({
tex2jax: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
}
});
</script>
<script async type="text/javascript" src="https://cdn.jsdelivr.net/npm/mathjax#3/es5/tex-mml-svg.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
</head>
<body>
<div id="application-content">
</div>
</body>
<!-- inject:js -->
<!-- endinject -->
<script type="application/javascript">
EMBED.default.init();
</script>
</html>
And here is the component where I use the library:
import React, { Component } from 'react';
export default class MathBlock extends Component {
constructor(props) {
super(props);
this.state = {
open: false,
};
}
render() {
const text = this.props.block.getText();
const latexRegex = /\${2}(.*?)\${2}/;
const hasLatex = latexRegex.test(this.props.block.getText());
return (
<div>
<div
dangerouslySetInnerHTML={{
__html: hasLatex
? window.MathJax.tex2svg(text.replaceAll('$', '')).innerHTML
: window.MathJax.mathml2svg(text).innerHTML,
}}
/>
</div>
);
}
}
MathBlock.propTypes = {
block: React.PropTypes.object.isRequired,
};
Does anyone know what is the problem here?
Because the script tag that loads MathJax has the async attribute, it may not be loaded when your EMBED.default.init(); command likely will run before MathJax is loaded, and so before window.MathJax has been defined.
You could either remove the async attribute (which will mean your page will have to wait for MathJax to load and compile before the rest of the page is processed, slowing down your initial view of the page), or you could put the EMBED.default.init(); in MathJax's startup ready() function so that it is not performed until MathJax is loaded.
You are loading MathJax version 3, but your current configuration seems to be a mix of v2 and v3 configurations, and it is currently being ignored entirely by MathJax.
You could use
<script>
MathJax = {
options: {
renderActions: {
addMenu: []
}
},
tex: {
inlineMath: [ ['$','$'], ["\\(","\\)"] ],
processEscapes: true
},
startup: {
ready() {
MathJax.startup.defaultReady();
EMBED.default.init();
}
}
};
</script>
(a correct v3 configuration) in place of your current configuration script, and see if that avoids the problem.

Ng-view or ui-view not displaying html page

I am relatively new to Angularjs, and am building a website. When I try to inject todo.html into the body tags of index.html nothing happens. I am not getting any errors in the console. I have read many of the similar posts to mine, and have already tried
Remove the ng-include from the body of index.html
Moved the links for angualrjs and bootstrap from the body of index.html to the head
Originally I used Ng-route but it did not work, so I implemented ui-router
I have tried both ng-route and ui-router,and both run without any errors. I don't think it has anything to do with either.
index.html
<html ng-app="todoApp">
<head>
<!-- META -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"><!-- Optimize mobile viewport -->
<title>Todo App</title>
<!-- Angular ans JS links-->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="app/app.js"></script>
<script src="app/services/todo.service.js"></script>
<script src="app/controllers/todo.controller.js"></script>
<!-- <script src="vendor/angular-route/angular-route.min.js"></script>-->
<!--Jquery and Bootstrap Links-->
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://npmcdn.com/tether#1.2.4/dist/js/tether.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/js/bootstrap.min.js" integrity="sha384-VjEeINv9OSwtWFLAtmc4JCtEJXXBub00gtSnszmspDLCtC0I4z4nqz7rEFbIZLLU"
crossorigin="anonymous"></script>
<!-- css links -->
<link href="vendor/bootstrap-css-only/css/bootstrap.min.css" rel="stylesheet"><!-- load bootstrap -->
<link rel="stylesheet" href="assets/css/todoApp.css">
<link rel="stylesheet" type="text/css" href="assets/css/Header-Picture.css">
</head>
<body >
<div ng-include="'app/views/header.html'"></div>
<!--<div ng-include="'app/views/footer.view.html'"></div>
-->
<ui-view></ui-view>
<!--<div ui-view></div>-->
</body>
</html>
App.js
var todoApp = angular.module('todoApp', [
'ui.router'
]);
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
todo.controller.js
todoApp.controller('TodoController', ['$scope', 'Todos', function TodoController($scope, Todos) {
$scope.formData = {};
console.log("in the TodoController");
// when landing on the page, get all todos and show them
Todos.get()
.success(function(data) {
$scope.todos = data;
});
// when submitting the add form, send the text to the spring API
$scope.createTodo = function() {
if(!$scope.todoForm.$valid) {
return;
}
Todos.create($scope.formData)
.success(function(data) {
$scope.formData = {}; // clear the form so our user is ready to enter another
$scope.todos.push(data);
});
};
// delete a todo after checking it
$scope.deleteTodo = function(id) {
Todos.delete(id)
.success(function(data) {
angular.forEach($scope.todos, function(todo, index){
if(todo.id == id) {
$scope.todos.splice(index, 1);
}
});
});
};
// when submitting the add form, send the text to the node API
$scope.saveTodo = function(todo) {
Todos.update(todo)
.success(function(data) {
$scope.editedTodo = {};
});
};
$scope.editedTodo = {};
$scope.editTodo = function(todo) {
$scope.editedTodo = todo;
}
$scope.revertTodo = function() {
$scope.editedTodo = {};
}
}]);
You should be using otherwise to force the first state to be loaded as below
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'todo.html',
})
$urlRouterProvider.otherwise('/');
});
Your index.html will look like
<div ng-include="'app/views/header.html'"></div>
<ui-view>
</ui-view>
LIVE DEMO
I added the code posted by #Aravind to my project which I belive was an improvement on my own and was correct. But the issue was the file path to the todo.html. The file path in the original was views/todo.html
the correct path is app/views/todo.html
My original code:
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'views/todo.html',
controller: 'TodoController'
})});
Current Working Code
todoApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('todo', {
url: "/",
templateUrl: 'app/views/todo.html',
})
$urlRouterProvider.otherwise('/');
});

ion-nav-view not working when trying to transition to new template

I am trying to figure out how to transition from one url to another using ion-nav-view. Visual Studio compiles the code and doesnt throw any errors when trying to load the templates/events.html in the tab. Any suggestions are welcome
index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
<link rel="stylesheet" type="text/css" href="css/index.css">
<title>SlidingTransitionwithAPI</title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"> </script>
<script src="cordova.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.js"></script>
<script src="lib/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
<script src="lib/ionic-ion-swipe-cards/ionic.swipecards.js"></script>
<script src="lib/collide/collide.js"></script>
<script src="lib/ionic-ion-tinder-cards/ionic.tdcards.js"></script>
</head>
<body ng-app="starter" no-scroll>
<ion-nav-view>
</ion-nav-view>
</body>
app.js:
angular.module('starter', ['ionic', 'starter.controllers', 'ionic.contrib.ui.tinderCards', 'ui.router'])
.run(function ($ionicPlatform) {
$ionicPlatform.ready(function () {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleLightContent();
}
});
})
.config(function ($stateProvider, $urlRouterProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
$stateProvider
.state('FindEvents', {
url: '/findEvents',
templateUrl: 'templates/events.html',
controller: 'EventsCtrl'
})
.state('favorites', {
url: '/favorites',
templateUrl: 'templates/favorites.html',
controller: 'FavoritesCtrl'
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/findEvents');
});
controllers.js:
angular.module('starter.controllers', [])
.directive('noScroll', function () {
return {
restrict: 'A',
link: function ($scope, $element, $attr) {
$element.on('touchmove', function (e) {
e.preventDefault();
});
}
}
})
.controller('EventsCtrl', function ($scope, $state) {
var cardTypes = [
{ image: './images/event1.jpeg', title: 'New Apple Release' },
{ image: './images/event2.jpeg', title: 'Digital Conference' },
{ image: './images/event3.jpg', title: 'Skyline Sessions' },
{ image: './images/event4.jpg', title: 'Secret Rooftop Party' },
{ image: './images/event5.jpeg', title: 'Smoking Lights' },
{ image: './images/event6.jpg', title: 'Antibes Color Run' },
{ image: './images/event7.jpg', title: 'Tomorrowland' },
{ image: './images/event8.jpeg', title: 'Steve Aoki Lighting Up Town' },
{ image: './images/event9.jpeg', title: 'Nice Yacht Party' },
{ image: './images/event10.jpg', title: 'Night Pool Party' },
];
$scope.cards = [];
$scope.addCard = function () {
for (var p = 0; p < 10; p++) {
var newCard = cardTypes[p];
newCard.id = Math.random();
$scope.cards.push(angular.extend({}, newCard));
}
}
$scope.addCard();
$scope.cardDestroyed = function (index) {
$scope.cards.splice(index, 1);
};
$scope.cardSwipedLeft = function (index) {
console.log('Left swipe');
}
$scope.cardSwipedRight = function (index) {
console.log('Right swipe');
}
$scope.cardDestroyed = function (index) {
$scope.cards.splice(index, 1);
console.log('Card removed');
}
//Transitioning between states
$scope.Favorites = function () {
$state.go('favorites');
}
});
events.html:
<ion-view view-title="Time 'N Joy '" ng-controller="EventsCtrl">
<ion-content ng-app="starter" >
<ion-pane>
<div class="bar bar-header bar-dark">
<button class="button button-clear button-icon icon ion-navicon"></button>
<div class="h1 title" font="6" color="white">Event Finder</div>
<button class="button button-clear" ng-click="Favorites()">
<i class="icon ion-heart"></i>
</button>
</div>
<td-cards>
<td-card id="td-card" ng-repeat="card in cards" on-destroy="cardDestroyed($index)"
on-swipe-left="cardSwipedLeft($index)" on-swipe- right="cardSwipedRight($index)"
on-partial-swipe="cardPartialSwipe(amt)">
<div class="title">
{{card.title}}
</div>
<div class="image">
<div class="no-text overlayBox"><div class="noBox boxed">Trash</div></div>
<img ng-src="{{card.image}}">
<div class="yes-text overlayBox"><div class="yesBox boxed" id="centerMe">Save</div></div>
</div>
</td-card>
</td-cards>
</ion-pane>
</ion-content>
</ion-view>
It is probably something very straigh forward but I have gone through countless examples and documents but cant find the error.

Cannot get separate views to appear in index.html, and controller is also not working

I'm just starting out with Angular and most of programming in general. I'm trying to make a separate view1.html file appear on my index.html page but it won't, so I'm assuming it's a routing problem. I tried pasting the view1.html content in the body of my index.html to test it and it wasn't showing the controller content either. I'm sure they're simple mistakes but I can't find them. view.html is in a separate folder called views. I only have the javascript in the index.html page for convenience.
index.html
<!DOCTYPE html>
<html lang="en" ng-app='demoApp'>
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<body>
<div>
<div ng-view></div>
</div>
<script>
// create module called "demoApp" under the variable name "demoApp"
var demoApp = angular.module('demoApp', []);
// ROUTING
demoApp.config(function ($routeProvider) {
$routeProvider
.when ('/',
{
controller: 'SimpleController',
templateUrl: 'views/view1.html'
})
.when('/view2',
{
controller: 'SimpleController',
templateUrl: 'views/view2.html'
})
.otherwise({ redirectTo: '/' });
});
// CONTROLLERS
demoApp.controller('SimpleController', function ($scope) {
$scope.customers = [
{ name: 'Caleb', city: 'Indianapolis' },
{ name: 'Samantha', city: 'Zionsville' },
{ name: 'Tim', city: 'Palo Alto' }
];
$scope.addCustomer = function () {
$scope.customers.push(
{
name: $scope.newCustomer.name,
city: $scope.newCustomer.city
});
};
}
</script>
</body>
</html>
view1.html
<h2>View 1</h2>
Name:
<input type="text" ng-model="name" />
<ul>
<li ng-repeat="cust in customers"></li>
</ul>
Customer Name:
<input type="text" ng-model="newCustomer.name" />
<br>Customer City:
<input type="text" ng-model="newCustomer.city" />
<br>
<button ng-click="addCustomer()">Add Customer</button>
View 2
</div>
You need to include the script for angular's router.
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-route.min.js"></script>
Also, looks like you're missing a closing </head> tag.
Here's a working version of your HTML file:
<!DOCTYPE html>
<html lang="en" ng-app='demoApp'>
<head>
<meta charset="UTF-8">
<title>First Angular App</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-route.js"></script>
</head>
<body>
<div>
<div ng-view></div>
</div>
<script>
// create module called "demoApp" under the variable name "demoApp"
var demoApp = angular.module('demoApp', ['ngRoute']);
// ROUTING
demoApp.config(function ($routeProvider) {
$routeProvider
.when ('/',
{
controller: 'SimpleController',
templateUrl: 'view1.html'
})
.when('/view2',
{
controller: 'SimpleController',
templateUrl: 'view2.html'
})
.otherwise({ redirectTo: '/' });
});
// CONTROLLERS
demoApp.controller('SimpleController', function ($scope) {
$scope.customers = [
{ name: 'Caleb', city: 'Indianapolis' },
{ name: 'Samantha', city: 'Zionsville' },
{ name: 'Tim', city: 'Palo Alto' }
];
$scope.newCustomer = { name: "", city: ""};
$scope.addCustomer = function () {
$scope.customers.push(
{
name: $scope.newCustomer.name,
city: $scope.newCustomer.city
});
};
});
</script>
</body>
</html>

Using ng-grid in partial page

Is there any example of using ng-grid in partial pages. Whenever I try to use, an error pops up as TypeError: Cannot set property 'myData' of undefined.
My App.js
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers', 'ngGrid']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
Controller.js
'use strict';
/* Controllers */
angular.module('myApp.controllers', ['ngGrid']).
controller('MyCtrl1', [function ($scope) {
$scope.myData = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{ name: "Enos", age: 34 },];
$scope.gridOptions = {
data: 'myData',
columnDefs: [{ field: 'name', displayName: 'Name' },
{ field: 'age', displayName: 'Age', cellTemplate: '<div ng-class="{green: row.getProperty(col.field) > 30}"><div class="ngCellText">{{row.getProperty(col.field)}}</div></div>' }],
showGroupPanel: true
};
}])
.controller('MyCtrl2', [function() {
}]);
//MyCtrl1.$inject = ['$scope'];
Partial1.html
<p>This is the partial for view 1.</p>
<div class="gridStyle" ng-grid="gridOptions"></div>
<div style="clear:both"/>
<p>{{ myData | json }}</p>
Partial2.html
<p>This is the partial for view 2.</p>
<p>
Showing of 'interpolate' filter:
{{ 'Current version is v%VERSION%.' | interpolate }}
</p>
And index.html
<!doctype html>
<html xmlns:ng="http://angularjs.org" id="ng-app" lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>My AngularJS App</title>
<link rel="stylesheet" href="css/app.css"/>
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/ng-grid.css">
<link rel="stylesheet" href="css/Style.css">
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.6/angular.min.js"></script>
-->
<script src="js/jquery-1.9.1.min.js"></script>
<script src="lib/angular/angular.js"></script>
<script src="js/ng-grid-2.0.5.min.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
<script src="js/controllers.js"></script>
</head>
<body>
<ul class="menu">
<li>view1</li>
<li>view2</li>
</ul>
<div ng-view></div>
<div>Angular seed app: v<span app-version></span></div>
</body>
</html>
Can you please say, why 'myData' is unavailable in Partial1.html?
Thanks in advance.
It is probably too late, but for the code right here
{name: "Enos", age: 34 },];
you don't need the coma. It should read:
{name: "Enos", age: 34 }];