Yii2 + AngularJS PrettyURL enable to work - javascript

I'm using Yii2 with AngularJS. I have to call different pages like about us, contact us etc. But my Pretty URL not working Properly. I need PrettyUrl like this:
localhost/angularjsyii/frontend/web/site/#/login
Current Url which is not working: localhost/angularjsyii/frontend/web/site#!/#%2Flogin
.htaccess
RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php
main.php(<navbar>)
<?php
use frontend\assets\AppAsset;
/* #var $this \yii\web\View */
AppAsset::register($this);
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>" ng-app="app">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Angular Yii Application</title>
<?php $this->head() ?>
<script>paceOptions = {ajax: {trackMethods: ['GET', 'POST']}};</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/pace.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/pace/1.0.2/themes/red/pace-theme-minimal.css" rel="stylesheet" />
<a base href="/angularjsyii/frontend/web/"></a>
</head>
<body>
<?php $this->beginBody() ?>
<div class="wrap">
<nav class="navbar-inverse navbar-fixed-top navbar" role="navigation" bs-navbar>
<div class="container">
<div class="navbar-header">
<button ng-init="navCollapsed = true" ng-click="navCollapsed = !navCollapsed" type="button" class="navbar-toggle">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span></button>
<a class="navbar-brand" href="/angularjsyii/frontend/web/site/index">My Company</a>
</div>
<div ng-class="!navCollapsed && 'in'" ng-click="navCollapsed=true" class="collapse navbar-collapse" >
<ul class="navbar-nav navbar-right nav">
<li data-match-route="/">
Home
</li>
<li data-match-route="/about">
About
</li>
<li data-match-route="/contact">
Contact
</li>
<li data-match-route="/login">
Login
</li>
</ul>
</div>
</div>
</nav>
<div class="container">
<div ng-view>
</div>
</div>
</div>
<footer class="footer">
<div class="container">
<p class="pull-right"><?= Yii::powered() ?> <?= Yii::getVersion() ?></p>
</div>
</footer>
<?php $this->endBody() ?>
</body>
</html>
<?php $this->endPage() ?>
app.js (For routing)
'use strict';
var app = angular.module('app', [
'ngRoute', //$routeProvider
'mgcrea.ngStrap'//bs-navbar, data-match-route directives
]);
app.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'partials/index.html'
}).
when('/about', {
templateUrl: 'partials/about.html'
}).
when('/contact', {
templateUrl: 'partials/contact.html'
}).
when('/login', {
templateUrl: 'partials/login.html'
}).
otherwise({
templateUrl: 'partials/404.html'
});
}
])
;
config/main.php
'urlManager' => [
'class' => 'yii\web\UrlManager',
// Disable index.php
'showScriptName' => false,
// Disable r= routes
'enablePrettyUrl' => true,
],

You should enable HTML5 mode in AngularJS to disable hashPrefix ! in your route.
app.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$locationProvider.html5Mode(true);
$routeProvider.
when('/', {
templateUrl: 'partials/index.html'
}).
when('/about', {
templateUrl: 'partials/about.html'
}).
when('/contact', {
templateUrl: 'partials/contact.html'
}).
when('/login', {
templateUrl: 'partials/login.html'
}).
otherwise({
templateUrl: 'partials/404.html'
});
}
]);
From reading the $location documentation of AngularJS:
Relative links
Be sure to check all relative links, images, scripts etc. You must
either specify the url base in the head of your main html file (<base href="/my-base">) or you must use absolute urls (starting with /)
everywhere because relative urls will be resolved to absolute urls
using the initial absolute url of the document, which is often
different from the root of the application.
In your case the base href should be something like this <a base href="/angularjsyii/frontend/web/site">. Now you dont need # on your URL anymore. Change your routes like:
<li data-match-route="/login">
Login
</li>
The URL should finaly look like: localhost/angularjsyii/frontend/web/site/login which is more pretty.

Related

Why my $scope is not accessible in my controller - Angular JS?

I am not able to get declared scope variable in my controller. Instead I'm getting reference error : message is not defined
Below is my code:
My Index.html
<body ng-app="myApp" ng-controller="homingController" ng-cloak>
<script type="text/javascript">
angular.module('myApp' ['ngRoute','ngMaterial']).controller('homingController', ['$scope',
function($scope){
$scope.message = 'Hello';
}
]).config(function ($routeProvider) {
$routeProvider.when("/home", {
templateUrl: "home.html",
controller: "homingController"
}).when("/monitor", {
templateUrl: "monitor.html",
controller: "monitoringController"
}).otherwise({
redirectTo: '/home'
});
}).controller('monitoringController', function ($scope) {
$scope.message = "Monitor";
});
</script>
<nav class = "navbar navbar-inverse" role="navigation">
<ul class = "nav navbar-nav" >
<li ><img src="./images/home.svg">Home</li>
<li >Monitor</li>
<li ><a class = "active" ui-sref = "Audit" ><img src="./images/audit.svg">Audit</a></li>
<li ><a class = "active" ui-sref = "configuration" ><img src="./images/configure.svg">Configure</a></li>
</ul>
</nav>
</div>
</body>
<div ng-view></div>
My home.html
{{ message}}
/*This line giving error in console : angular.js:14328 ReferenceError: $scope is not defined
*/
Is there anything I am missing here?
Your <div ng-view></div> should be inside your <body> tag. By placing it outside of the body, in which you define your app, the views have no idea what app or controller they should be using.
You also don't need to identify ng-controller's anywhere around your views, since you define them in your routeconfig:
var app = angular.module('myApp' ['ngRoute']);
app.config(function($routeProvider) {
$routeProvider
.when("/home", {
templateUrl: "home.html",
controller: "homingController"
}).when("/monitor", {
templateUrl: "monitor.html",
controller: "monitoringController"
}).otherwise({
redirectTo: '/home'
});
});
app.controller('homingController', function($scope) {
$scope.message = 'Hello';
})
app.controller('monitoringController', function($scope) {
$scope.message = "Monitor";
});
If you want to display something from one of your controllers you should define it like so:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
</head>
<body ng-app="myApp">
<div ng-controller="homingController">
{{message}}
</div>
<nav class="navbar navbar-inverse" role="navigation">
<ul class="nav navbar-nav">
<li>
Home
</li>
<li>
Monitor
</li>
</ul>
</nav>
<div ng-view></div>
</body>
With your home.html & monitor.html containing {{ message }}. An exact example of this can be found at w3Schools (Under the heading "Controllers"). Build that, then once you have that working start expanding on it to fill in the rest of your application.

$location.path change url but no redirecting

I want to redirect to another page by clicking a button, but when I click on a button, URL is changed, but it is not redirected, I have to refresh the page with new URL. The same is also happening when I click on link.
locationController.js
angular.module('reservationModule').controller('locationController', function($scope, $location){
$scope.setLocation = function (url) {
$location.path(url);
};
})
reservationModule.js
(function () {
var resModule = angular.module('reservationModule', ['ngRoute']);
resModule.controller('HomeController', function ($scope) { // here $scope is used for share data between view and controller
$scope.Message = "Yahoooo! we have successfully done our first part.";
});
resModule.config(function ($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: '/Home/Index.cshtml',
controller: 'locationController'
})
.when('/Home/Index', {
templateUrl: '/Home/Index.cshtml',
controller: 'locationController'
})
.when('/Home/Registration', {
templateUrl: '/Home/Registration.cshtml',
controller: 'registerController'
})
.when('/Home/Login', {
templateUrl: '/Home/Login.cshtml',
controller: 'loginController'
})
.otherwise({ redirectTo: '/' });
});
})();
Index.cshtml
#{
// Layout = "~/Views/Shared/_Layout.cshtml";
ViewBag.Title = "Webový rezervační systém";
}
<base href="/">
<div class="container" ng-controller="locationController">
<header class="header">
<div class="headerleft">
<div class="headerlogo">
<img alt="reservation" src="../Content/pics/vetstoria-logo.jpg" width="50" height="50">
</div>
</div>
<div class="headerright">
<p class="headerlogintext">
<a class="btn headerlogin" href="/Home/Login" style="text-decoration:none">Přihlašte se</a>
</p>
</div>
</header>
<div class="content">
<h1 class="content-title">Webový rezervační systém</h1>
<p class="content-title-text">V našem rezervačním systému se můžete rezervovat na cokoliv chcete. Ať už si chcete rezervovat sportoviště, nějaký kurz nebo jiné, u nás to jde snadno.</p>
<p class="content-title-text">Pro začátek vám stačí jediné.</p>
<button class="btn-big" ng-click="setLocation('/Home/Registration')">Registrovat</button>
</div>
<!-- <ul class="menuUl">
<li>#Html.ActionLink("Register", "Registration")</li>
</ul>-->
#section Scripts{
<script src="~/Scripts/Angular_Controllers/locationController.js"></script>
}
I read some topics about this, but I don't know, if an error is in the module, or in the controller.
I had a similar issue. The template url should point to ".html" rather than ".cshtml". When you try to access files inside the Default Folders created by Visual Studio, for some reason you cannot access it. So try changing your path.

AngularJS Stopping CSS background slideshow showing all pages with ng-route

I am doing my AngularJS project with ng-route and everything works fine but the problem is I have a CSSC full background slide show which i implemented form this site http://tympanus.net/codrops/2012/01/02/fullscreen-background-image-slideshow-with-css3/ which work fine. When I click on other pages the content shows but the slideshow shows up as well moving/transitioning in the background. I want to stop this from happening. I want the slideshow to only show up on the index.html page only. Any solutions would be appreciated.
--- HTML code ---
<body ng-app="bigBlue"> <!--angular directive-->
<div main-page-navbar></div> <!--angular navbar directive-->
<div main-slide-show> </div> <!--angular side show directive-->
<div ng-view ></div>
<!-- Additional Java Script Files -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- Angular Files -->
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular/angular-route/angular-route.js"></script>
<!-- Module/directives -->
<script src="js/app.js"></script>
<script src="js/directives/main-content.js"></script>
</body>
------- navbar directive code --------
<body>
<nav class="navbar navbar-inverse navbar-static-top">
<div class="container-fluid">
<div class="navbar-header"><a class="navbar-brand navbar-link" href="#/">Big Blue</a>
<button class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navcol-1"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button>
</div>
<div class="collapse navbar-collapse" id="navcol-1">
<ul class="nav navbar-nav navbar-right">
<li class="active" role="presentation">Home </li>
<li role="presentation">Overview </li>
<li role="presentation">Map </li>
</ul>
</div>
</div>
</nav>
------ slide show directive code --------
<ul class="cb-slideshow">
<li><span>Image 01</span><div><h3>endangered</h3></div></li>
<li><span>Image 02</span><div><h3>powerful</h3></div></li>
<li><span>Image 03</span><div><h3>caring</h3></div></li>
<li><span>Image 04</span><div><h3>loyal</h3></div></li>
<li><span>Image 05</span><div><h3>intelligent</h3></div></li>
<li><span>Image 06</span><div><h3>serene</h3></div></li>
</ul>
---- Angular Code ----
var app = angular.module("bigBlue", ["ngRoute"]); /* New module called big blue */
app.config(function($routeProvider) {
$routeProvider
.when('/overview', {
templateUrl : 'overview.html',
controller : 'whaleController'
})
.when('/map', {
templateUrl : 'map.html',
controller : 'MapController',
})
.otherwise({
redirectTo : '/'
});
});
You need to move your slideshow directive into the context of the index instead of the context of the entire application. Something like this:
app.config(function($routeProvider) {
$routeProvider
.when('/', {
template: '<div main-slide-show></div>'
})
.when('/overview', {
templateUrl : 'overview.html',
controller : 'whaleController'
})
.when('/map', {
templateUrl : 'map.html',
controller : 'MapController',
})
.otherwise({
redirectTo : '/'
});
});
And pull the slideshow directive out of the markup.

ng-repeat not displaying items

i have a weird bug in my angular app where the data in my ng-repeat is not displaying but if i refresh the page and navigate to my home page it quickly flickers into view then disappears, im not sure why this is happening can someone help me out?
thanks in advance
appRoutes.js
angular.module('appRoutes', []).config(['$routeProvider','$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
// home page
.when('/', {
templateUrl: 'views/home.html',
controller: 'MainController'
})
// characters page that will use the CharactersController
.when('/characters', {
templateUrl: 'views/characters.html',
controller: 'CharactersController'
});
$locationProvider.html5Mode(true);
}]);
CharactersCtrl.js
angular.module('CharactersCtrl', []).controller('CharactersController', function($scope) {
$scope.init = function(){
$scope.getCharacters();
}
$scope.getCharacters = function(){
$.ajax({
url:'https://gateway.marvel.com/v1/public/characters?apikey=APIKEY',
success:function(response){
$scope.characters = response.data.results;
console.log($scope.characters);
},
fail:function(){
}
});
}
$scope.init();
});
characters.js
<div>
<div class="text-center">
<h1>Characters</h1>
</div>
<section id="character-section" class="row">
<figure class="columns small-3" ng-repeat="hero in characters">
<!-- <img ng-src="{{hero.thumbnail.path}}" alt="{{hero.name}}-image"> -->
<figcaption>
{{hero.name}}
</figcaption>
</figure>
</section>
</div>
index.html
<body ng-app="marvelApp">
<!-- HEADER -->
<header>
<nav class="navbar navbar-inverse">
<div class="navbar-header">
<a class="navbar-brand" href="/">Stencil: Node and Angular</a>
</div>
<!-- LINK TO OUR PAGES. ANGULAR HANDLES THE ROUTING HERE -->
<ul class="nav navbar-nav">
<li>characters</li>
</ul>
</nav>
</header>
<!-- ANGULAR DYNAMIC CONTENT -->
<main ng-view ></main>
</body>
app.js
angular.module('marvelApp', ['ngRoute', 'appRoutes', 'MainCtrl', 'CharactersCtrl', 'CharactersService']);
You are using jQuery ajax. Angular does not automatically update variable when modified outside the Angular scope (in this case, $scope.characters is modified using jquery ajax);
I sugges you use the $http service provided by angular for making ajax calls.
But if you insist in using jquery ajax, you can wrap this code $scope.characters = response.data.results; with
`$scope.$apply(function(){
})`
Result:
$scope.$apply(function(){
$scope.characters = response.data.results;
})

AngularJS ui-routing with IIS

I have this AngularJS project where I use ui-router for my routing.
When I run the project through a NodeJS server it all works fine, however I need to move it all to an IIS server, which have more than one application running on it.
Here's my problem: After moving the project to the IIS I can only load one page, whenever I try to go to one of the other pages it returns to the initial one.
This is my setup:
index.html
<!doctype html>
<html ng-app="SimPlannerApp">
<head>
<base href="/simplanner/">
...
<!-- Load AngularJS modules -->
<script src="lib/Angular-1.4.7/angular.min.js"></script>
<script src="lib/Angular-1.4.7/angular-ui-router.min.js"></script>
<!-- Load AngularJS Application -->
<script src="core.js"></script>
...
</head>
<body>
<nav ng-controller="navController">
<div class="col-md-8">
<span class="menu">
<i class="glyphicon glyphicon-menu-hamburger"></i> <span class="hidden-xs">Menu</span>
</span>
<ul>
<li ng-repeat="view in nav">
{{ view.route | capitalize }}
</li>
</ul>
</div>
<span class="clearfix"></span>
</nav>
<!-- This is where page content is inserted to -->
<div class="col-md-8">
<div ui-view></div>
</div>
</body>
</html>
core.js
...
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
var urlBase = '/' + config.IISProjectName;
// For any unmatched url, redirect to '/'
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: "/login",
templateUrl: urlBase + '/views/login.html',
controller: 'loginController'
})
.state('view', {
url: '/view/:view',
templateUrl: urlBase + '/views/view.html',
controller: 'viewController',
resolve: {
view: function ($stateParams, configService) {
for (var i = 0; i < config.views.length; i++) {
if (config.views[i].route === $stateParams.view) {
return config.views[i];
}
}
return undefined;
}
}
})
.state('404', {
url: '{path:.*}',
templateUrl: urlBase + '/views/404.html',
controller: 'errorController'
});
$locationProvider.html5Mode(true);
});
...

Categories