HTML anchor conflicts with express router - angularjs

I'd like to use the bootstrap tab-list in my project. While it contains anchors point to the sub-panel of the list. These anchors became invalid when I set the express router. The HTML code is like:
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a class="allerta" style="font-size:15px;"
href="/#overview" aria-controls="overview" role="tab" data-toggle="tab">Overview</a></li>
<ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active allerta" id="overview" style="
margin-top:15px;margin-bottom:15px;font-size:18px">
...
</div>
</div>
This href="/#overview" didn't point to the tabpanel anymore after I set up the express router. Instead it points to a empty page which url is "localhost:3000/#/overview". While if I delete the "/" before overview. It will conflict with the $routeProvider in Angularjs. The js file was as below:
var express = require('express');
var app = express();
app.use(express.static(__dirname));
app.listen(3000);

Related

Angularjs: initiating first tab as active on page load

We are creating a tabs widget in ServiceNow and want to initiate the first tab as the active tab when the page loads. Right now when the page loads, this is what we see:
We actually want to see this on load:
Our code looks like this:
<ul class="nav nav-tabs">
<li ng-click="c.activateClass(tabs)" ng-repeat="tabs in c.data.tab_labels track by $index" ng-class="{'active':tabs.active}">
<a data-toggle="tab" href="#{{tabs}}">{{tabs}}</a>
</li>
</ul>
<div class="tab-content" >
<div ng-repeat="content in c.data.tab_labels" id="{{content}}" class="tab-pane fade in active">
<h3>{{content}}</h3>
<p>Some content.</p>
</div>
</div>
function($scope) {
/* widget controller */
var c = this;
c.data.tab_labels = c.options.tab_labels.split(',');
c.activateClass = function(subModule){
subModule.active = !subModule.active;
}
console.log('tabs');
console.log($scope);
}
We tried to use ng-init, but it was returning a console error. Any idea how to initiate the first tab on page load? Thanks!
You can set the active tab as active like this:
if(c.data.tab_labels.length > 0) {
c.data.tab_labels[0].active = true;
}
and show the active content:
<div ng-repeat="content in c.data.tab_labels | filter:{active:true}">

Menu items not displaying from config.toml definition

I'm attempting to define a site wide menu that is displayed within a bootstrap navbar.
Top level config.toml is;
baseURL = "http://localhost/"
languageCode = "en-us"
title = "Localhost"
[menu]
[[menu.main]]
identifier = "page1"
name = "page1"
url = "/page1/"
weight = 0
[[main.menu]]
identifier = "page2"
name = "page2"
url = "/page2/"
weight = 1
[[main.menu]]
identifier = "page3"
name = "page3"
url = "/page3/"
weight = 2
The menu sits within a site-header partial that is being passed in the site context.
index.html
{{ partial "head.html" . }}
<body>
{{ partial "site-header.html" . }}
<div class="row">
<div class="col-12">
<main>
<section>
<h1>{{.Title}}</h1>
</section>
</main>
</div>
</div>
</body>
site-header.html
<header>
<div class="container">
<nav class="navbar navbar-expand-sm navbar-dark ">
<a class="navbar-brand" href="{{ "/" | relURL}}"><img src="/images/Main-Logo-v1-1.png" class="d-inline-block align-top menu-brand-image" alt="Logo"></a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav ml-auto">
{{ $currentPage := . }}
{{ range .Site.Menus.main }}
<li class="navbar-item {{if or ($currentPage.IsMenuCurrent "main" .) ($currentPage.HasMenuCurrent "main" .) }} active{{end}}">
<a class="nav-link" href="{{ .URL }}" title="{{ .Title }}">{{ .Name }}</a>
</li>
{{ end }}
</ul>
</div>
</nav>
</div>
</div>
</header>
The {{range .Site.Menus.main }} seems only to parse the first element within the table array [[menu.main]] as the 'page1' entry is all that is included within the generated html.
I've added some debug printf also which confirms that the range only recognises [[menu.main]] as being an array of 1.
Any ideas, pointers would be appreciated.
Seems like you have misspelled the other menu entries in config.toml menu definition. You are declaring [[main.menu]] instead of [[menu.main]]. The first one is correct though, that's why it appears.
Add pageRef to each menu item in config.toml that should be the same as url.
Source 1: Menus in Hugo
Source 2: Hugo release v0.86.0
I was also facing same problem. when I have started using hugo its version was V0.83.1. when I deploy my website menus where working fine. but after some days menus where not displaying.
git hub issue link
after referring above link I have updated to latest version of hugo i.e v0.108.0 and it works. you may check by updating hugo version.

Angular - Page does not bind variable outside view when specific view url is requested

I tried to solve the problem but could not find the solution for this one. I have 2 views home and cart. Home displays all the products and cart displays all the items added to the cart. Backend for this is NodeJS which just servers index file and processes views.
In the following index file, I have {{fullCart.totalItems}} . When I try localhost:3000 then it binds perfectly by showing 0 and routes to localhost:3000/home but when I try localhost:3000/home url directly in the browser then it does not bind {{fullCart.totalItems}} so nothing is displayed
index.html
<body ng-app="bagitApp" ng-init="quanArr=[1,2,3,4,5,6,7,8,9,10]">
<div class="container-fluid nav-color navbar-fixed-top" ng-controller="headerController">
<div class="container">
<a class="navbar-brand" href="#"><img class="img-responsive" src="images/logo.png"></a>
<nav>
<div class="navbar-header">
<button type="button" class="navbar-toggle nav-btn" data-toggle="collapse" data-target="#navBar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="collapse navbar-collapse" id="navBar">
<ul class="nav navbar-nav">
<li>Home</li>
<li>Cart</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><i class="glyphicon glyphicon-shopping-cart"></i><i class=" teal new badge">{{fullCart.totalItems}}</i></li>
</ul>
</div>
</nav>
</div>
</div>
<div class="container pan-mar" ng-view>
</div>
</body>
main.controller.js
var app=angular.module('bagitApp',['ngRoute']);
app.config(['$routeProvider','$locationProvider',function($routeProvider,$locationProvider){
$routeProvider
.when('/home',{
templateUrl:'partials/Products Panel.html',
controller:'productsController'
})
.when('/cart',{
templateUrl:'partials/cart.html',
controller:'cartController'
})
.otherwise({
redirectTo:'/home'
});
$locationProvider.html5Mode({enabled:true,requireBase:false});
}]);
app.factory('cartService',function(){
return {
cart:[],
totalItems:0
};
});
function headerController($rootScope,$scope,cartService){
$scope.fullCart = cartService;
console.log("headerController")
console.log($scope.fullCart)
}
function productsController($rootScope,$scope,cartService){
$scope.fullCart = cartService;
$scope.products = products;
console.log("productsController")
console.log($scope.fullCart)
$scope.addToCart=function(item,quantity){
$scope.fullCart.cart.push({item,quantity:parseInt(quantity)});
$scope.fullCart.totalItems += parseInt(quantity);
console.log($scope.fullCart);
}
$scope.removeFromCart=function(itemId){
}
}
app.controller('productsController',['$rootScope','$scope','cartService',productsController])
app.controller('headerController',['$rootScope','$scope','cartService',headerController])
Server.js
var express = require('express');
var server = express();
var engines = require('consolidate');
server.set('views',__dirname);
server.engine('html',engines.mustache);
server.set('view engine','html')
server.use(express.static(__dirname));
server.get('/:name',function(req,res){
res.render('index');
});
server.listen(3000,function(){
console.log("Listening on localhost:3000");
})
Your problem is that when you go to
localhost:3000
then on the server your express.static serves index.html as a static asset so it's not render using mustache.
Since mustache uses same syntax {{ }} as angular then when you go to /home route handler for /:name renders index.html using mustache and since you dont pass in any variable then mustache simply deletes this
{{fullCart.totalItems}}
what you should do is
1.create public folder and place all public assets in it and change
server.use(express.static(__dirname));
to
server.use('/public', express.static(__dirname));
-html templates into templates subfolder
-js files like angular.js into js subfolder, etc.
2.create views folder and place your index.html in it.
This way you avoid index.html is servered once as static and once render with mustache. from now on it's always rendered. Unfortunately this will lead to another problem which is mustache will overwrite or delete any {{}}
So one option is to change angular {{}} to something like [[ ]] by adding
appModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
});
Then you could use it in your template:
<div>[[message]]</div>
Or you can most probably change {{}} to something else in mustache too but i don't know myself but you can have a look at mustache docs
On the node service you will want to add this.
app.get('*', function(req, res, next){
res.sendFile(PATH_TO_INDEX);
});
This will respond with the index.html on any other route, and then once the angular app bootstraps it will take over on routing and render the correct page.
In your angular app you will want to add this as well for each script/css file.
<base href="/">
Make sure it is above any of your scripts or stylesheets though.

$scope is only visible in function and thats why is not working

My layout page looks like this:
<li class="dropdown">
<ul class="submenu">
<li>#Translate("MY_ACCOUNT")</li>
</ul>
</li>
In layout page i have : #RenderBody()where i have Index page.In index page im using <div ng-view></div>. What im trying to do is when user click on a href to redirect him on that page and set class to this menu that is render in ng-view:
<div class="account-item">
<div class="account-heading" ng-class="{active : activeMenu === 'Settings'}">
<h4 class=" account-title has-sub">
<a data-toggle="collapse" data-parent="#accordion" href="#settings" ng-click="activeMenu='Settings'">5. #Translate("SETTINGS")</a></h4>
</div>
<div id="settings" class="account-collapse collapse in">
<div class="account-body">
#Translate("PERSONAL_INFORMATION")
#Translate("NOTIFICATIONS")
#Translate("CHANGE_PASSWORD")
#Translate("GAME_SETTINGS")
</div>
</div>
</div>
When i try this nothing happens:
$scope.SetActiveMenuForPersonalInfo = function () {
$scope.activeMenu = 'Settings';
$scope.activeLink = "PersonalInfo";
}
$scope.activeMenu and $scope.activeLink are visible only in function and thats why i cant set class on menu. When i put it out of function it works
Try changing the tripple equality sign in ng-class="{'active-link' : activeLink==='PersonalInfo'}" to double ==
PS: I do not understand the last paragraph

Left hand menu link color chnage in angular

For my angular application , i have created left nav menu. On click of link ,corresponding page is opening. My problem is I want to change active link color to blue whereas other links are in white color. When I click another link from menu ,that link should be in blue and remaining are in white.
I do not know how to do this in angular. With Jquery , its easy for me. But angular makes me nervous.
My left nav is
<div class="leftNavList">
<div class="leftNavManageHeading"><span "mSans300 font14">Manage</span></div>
<ul class="nav manageNav">
<li ng-click="isCollapsed2 = !isCollapsed2">
<div class="listOuterWrapper">
<div class="listInnerWraper">
<span class="mSans300">Usage</span>
</div>
</div>
</li>
<li ng-click="isCollapsed3 = !isCollapsed3">
<div class="listOuterWrapper">
<span class="mSans300">Payment</span>
</div>
<div class="listInnerWraper">
<div collapse="!isCollapsed3">
<ul class="paymentNav mSans30 font14">
<li>PaymentMethod</li>
<li>PaymentHistory</li>
</ul>
</div>
</div>
</li>
<li ng-click="isCollapsed4 = !isCollapsed4">
<div class="listOuterWrapper">
<div class="listInnerWraper">
<span class="mSans300">Account</span>
</div>
</div>
</li>
</ul>
</div>
Step 1: In ng-init declare a variable.
ng-init="activelink=0"
Step 2: Now in ng-cick of link change the value of activelink.
<li><a href="" ng-click="activelink=1"</a></li>
<li><a href="" ng-click="activelink=2"</a></li>
Step 3: Declare a class linkcolor that defines the color of the active link.
Step 4: Now use ng-class="{ 'linkcolor' : activelink==1 }" expression for both the link.
Step 5: The links will change to
<li><a href="" ng-click="activelink=1" ng-class="{ 'linkcolor' : activelink==1 }" </a></li>
<li><a href="" ng-click="activelink=2" ng-class="{ 'linkcolor' : activelink==2 }"</a></li>
The expression activelink==1 will return true or false depending on the value of activelink.
I would recommend looking into ui-router , it has active states (these are the pages of your app) which do all these css and state changing from the view rather than having the logic in your controller and there are many powerful tools to make your app function better in less code..
In your nav:
<ul>
<li ui-sref-active="active" class="item">
<a href ui-sref="route1">route1</a>
</li>
</ul>
And thats it! Your currently active state/ view will apply the ui-sref-active="active" class to that li element. where "active" is the class name which is applied.

Resources