Angular broadcast event not received in other controller - javascript

Header contorller
mapsModule = angular.module('maps-module');
mapsModule.controller('psHeaderCtrl', function($scope, $rootScope, MESSAGES,
psHttpSrvc){
$scope.addAlertPin = function(){
console.log('broadcast event');
$scope.$broadcast('event1', { data: 'asdasdasasda'});
}
});
Map contorller
map = angular.module('maps-module');
map.controller('map_controller',function
($scope,$rootScope,$timeout) {
$scope.$on('event1', function(event, args){
console.log('asdasdasd');
});
});
Header.html
<div ng-controller="psHeaderCtrl">
<ul class="nav navbar-toolbar navbar-right navbar-toolbar-right">
<li class="nav-item" id="plus">
<a class="nav-link" data-toggle="" href="javascript:void(0)"
title="plus" ng-click="addAlertPin()">
<i class="icon wb-plus" aria-hidden="true"></i>
</a>
</li>
</ul>
</div>
All files are included. Angular is working fine but broadcast events are not received.

Try using $rootScope to broadcast event:
$scope.addAlertPin = function(){
console.log('broadcast event');
$rootScope.$broadcast('event1', { data: 'asdasdasasda'});
}

Related

Jquery, can't update attribute previously created

I'm just trying to work on new slider menu but I've a problem with Jquery.
I've a link. When I click on I use .css('left', -230) and all is okay but when i want to reverse by another clicked link like .css('left', 0) nothing happen.
I show you some code :
// The open part "target.width()" = 230
$('.nav-item').on('click', function () {
if( 0 < $(this).find('.navbar-nav__sub').length ) {
var target = $('.navbar-nav');
target.css('left', -target.width());
}
});
// The close part
$('.navbar-nav__sub .go-back').on('click', function () {
console.log('HERE');
var target = $('.navbar-nav');
console.log(target);
console.log(target.css('left'));
target.css('left', 0);
console.log(target.css('left'));
console.log('END');
});
A strange thing in this problem is that I've this in my console :
HERE
Object { 0: ul.navbar-nav.flex-column, length: 1, prevObject: […] }
-230px
0px
END
It seem that the code work well but in my page the left attribute is always to -230px.
Someone have an idea ?
Thank you.
PS: As asked the JSfiddle who reproduce my problem
https://jsfiddle.net/w7Lknsxg/
If you click on "Menu01" Color turn to red and when you click on "<=" in submenu you have the execution in the console but the color don't change.
You can see the class navbar-nav get new class "toto" but don't lost when I try to remove it in the second case.
Because the .go-back is nested within the .nav-item you are firing both event listeners due to event bubbling. You can stop this with event.stopPropagation(); from within the listener placed on the child item. (or be more specific in what you target as not to include subelements)
var ftl = window.ftl || {};
ftl.navbar = {
config: {
targetName: '.nav',
target: null,
},
init: function init() {
this.config.target = $(this.config.targetName);
$('.navbar-toggle').on('click', function () { ftl.navbar.toggle(); });
$('.nav-item').on('click', function () {
if( !ftl.navbar.config.target.hasClass('open') ) {
ftl.navbar.open();
}
// test la présence d'un sous menu
if( 0 < $(this).find('.navbar-nav__sub').length ) {
var target = $('.navbar-nav');
target.addClass('toto');
target.css('color', 'red');
}
});
$('.navbar-nav__sub .go-back').on('click', function (event) {
event.stopPropagation();
console.log('HERE');
var target = $('.navbar-nav');
console.log(target);
console.log(target.hasClass('toto'));
target.removeClass('toto');
target.css('color', "green");
console.log('END');
})
},
open: function open() {
this.config.target.addClass('open').one('transitionend', function () {
ftl.navbar.config.target.addClass('opened');
});
},
close: function close() {
this.config.target.removeClass('opened')
.removeClass('open');
},
toggle: function toggle() {
if( this.config.target.hasClass('open') ) {
this.close();
} else {
this.open();
}
}
}
$(document).ready(function() {
ftl.navbar.init();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="nav">
<nav class="navbar" role="navigation">
<div class="container-nav flex-column">
<div class="navbar__header">
<a href="#" class="no-style">
<i class="fa fa-comment-o fa-2x navbar__icon" aria-hidden="true"></i>
<span class="navbar__text"><strong class="text-primary">web</strong>tutu</span>
</a>
</div>
<div class="navbar__divider"></div>
<ul class="navbar-nav flex-column">
<li id="nav-item--one" class="nav-item">
<a href="#nav-item--one">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu01</span>
</a>
<ul class="navbar-nav__sub">
<li>link 01</li>
<li>link 02</li>
<li><a class="go-back" href="#"> <= </a></li>
</ul>
</li>
<li id="nav-item--two" class="nav-item">
<a href="#nav-item--two">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu02</span>
</a>
</li>
<li id="nav-item--three" class="nav-item">
<a href="#nav-item--three">
<i class="fa fa-user-circle-o navbar__icon" aria-hidden="true"></i>
<span class="navbar__text">Menu03</span>
</a>
</li>
<li class="mt-auto">
<i class="fa fa-angle-double-right fa-2x navbar-toggle" aria-hidden="true"></i>
</li>
</ul>
</div>
</nav>
</nav>

How do I make my sidebar navigation child menus remain expanded and active on new HTTP request in Laravel?

I have an issue with my child menus.When I click a child menu it becomes active after http request but I want it to remain expanded after http request(page refresh).Menu structure is below.
<ul class="sidebar-navigation>
#foreach($parent as $parent)
<li>{{$parent->name}}
<ul>
#foreach($child as $child)
#if(isset($_GET['name']) && $_GET['name'] == $child->name)
<li class="active">
#endif
{{$child>name)}}
</li>
#endforeach
</ul>
</li>
#endforeach
</ul>
Here is an idea, and it's what i do to acheieve this effects. i use AdminLTE, you should base this code to change your code, Basic idea is judge current route if route need open sidebar then give a class 'active'
to html tag.
Html:
<div class="main-sidebar">
<div class="sidebar">
<ul class="sidebar-menu">
<li class="treeview {{ sidebar_open(['admin.roles.*']) }}">
<a href="#">
<i class="fa fa-user-secret"></i>
<span>角色管理</span>
<span class="pull-right-container">
<i class="fa fa-angle-left pull-right"></i>
</span>
</a>
<ul class="treeview-menu">
<li><i class="fa fa-circle-o"></i>角色列表</li>
<li><i class="fa fa-circle-o"></i>新建角色</li>
</ul>
</li>
</ul>
define a helper functions:
<?php
if (!function_exists('sidebar_open')) {
function sidebar_open($routes = []) {
$currRoute = Route::currentRouteName();
$open = false;
foreach ($routes as $route) {
if (str_contains($route, '*')) {
if (str_contains($currRoute, substr($route, '-1'))) {
$open = true;
break;
}
} else {
if ($currRoute === $route) {
$open = true;
break;
}
}
}
return $open ? 'active' : '';
}
}

unable to hide logout button after signout using ng-show in angularjs

I have the logout button like this:
<li class="dropdown" data-ng-if="userName">
<a href class="dropdown-toggle clear" data-toggle="dropdown" data-ng-show="userName">
</a>
<!-- dropdown -->
<ul class="dropdown-menu>
<li ng-hide="fb_id">
<a ui-sref="app.changePassword">Change Password</a>
</li>
<li>
<a ui-sref="app.changeProfilePic">Change Profile Picture</a>
</li>
<li data-ng-show="userName">
<a ui-sref="access.signout" data-ng-if="userName">Logout</a>
</li>
</ul>
<!-- / dropdown -->
</li>
And in the controller:
$scope.logIn = function (user) {
$scope.myPromise = AuthService.login({
'uid': user.email,
'password': user.password,
}).then(function (response) {
$localStorage.userName = response.userName;
$scope.userName = $localStorage.userName;
}, function (error) {
$scope.authError = true;
});
};
Sign out controller:
$scope.userName = "";
delete $localStorage.userName;
$rootScope.userName = "";
Doesn't matter I use ng-if or ng-show it is still showing the logout button and the dropdown.
Try with the below code.
<a ui-sref="access.signout" data-ng-if="userName != ''">Logout</a>
This should do
<li data-ng-show="userName !== ''">
<a ui-sref="access.signout">Logout</a>
</li>

Display content on click of navigation menu in angularjs

My html page contain two sections. Left side I have navigation(code is below) and right side is to display contents for respective navigation menu.
On click of each navigation menu, particular section should be rendered on my content part.
I have done it using ng-show/ng-hide by setting flag in my js file. But since I am setting flags for each sections and show/hide , my js code file looks very odd. I know this is not the correct way to do it.
I am new to angularjs. Kindly help me to achieve this efficiently.
HTML code: (only navigation part)
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li class="active">Home</li>
<div class="collapse" id="Login">
<ul class="nav nav-pills nav-stacked">
<li><a class="glyphicon glyphicon-log-in" href="#" ng-click="LoginScreen()">Login</a></li>
<li><a class="glyphicon glyphicon-user" href="#" ng-click="RegisterScreen()">Register</a></li>
</ul>
</div>
<li>About</li>
<div class="collapse" id="Contact">
<ul class="nav nav-pills nav-stacked">
<li><a class="glyphicon glyphicon-save" href="#" ng-click="LoadUserDetailsScreen()">LoadUserDetails</a></li>
<li><a class="glyphicon glyphicon-phone-alt" href="#">Contact</a></li>
</ul>
</div>
</ul>
</div>
JS code:
var app = angular.module('myApp', []);
app.controller('mycontroller', function($scope) {
$scope.FlagHomeScreen = true;
$scope.LoadData=false;
$scope.showtable=false;
$scope.showstatus=false;
$scope.FlagLoginScreen = false;
$scope.RegisterScreenFlag= false;
$scope.menuitems =[10,20,30];
$scope.LoginScreen = function(){
$scope.FlagLoginScreen = true;
$scope.FlagHomeScreen =false;
$scope.LoadData=false;
$scope.RegisterScreenFlag=false;
};
$scope.LoadUserDetailsScreen =function(){
$scope.LoadData=true;
$scope.FlagLoginScreen = false;
$scope.FlagHomeScreen =false;
$scope.RegisterScreenFlag=false;
};
$scope.RegisterScreen=function(){
$scope.RegisterScreenFlag=true;
$scope.LoadData=false;
$scope.FlagLoginScreen = false;
$scope.FlagHomeScreen =false;
};
});
You can handle your navigation in your app using ui-router. For your case you need a main template which includes your navigation bar and in each state of your app you want to show a different view.
Here is a fiddle which shows you how you can use ui-router to handle your views. For clarity I only implemented login and user details in the example below. You can add remaining parts yourself, it would be a good practice for you.
Define your states as such:
var myApp = angular.module('myApp', ['ui.router'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('home', {
url: "/",
template: '<div ui-view=""/>' // templates of child states will fill components with ui-view attribute
})
.state('home.userDetails', {
url: "userDetails",
template: '<div>user details</div>',
controller: "UserDetailsCtrl"
})
.state('home.login', {
url: "login",
//templateUrl: "path/to/login.html" // instead of giving inline templates as below, you can include your template into a html file, and use it in your state by templateUrl property
template: '<div>user login</div>',
controller: "LoginCtrl"
})
}])
And you can navigate within your states using ui-sref instead of using ng-show and ng-click.
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li class="active">Home</li>
<div class="collapse" id="Login">
<ul class="nav nav-pills nav-stacked">
<li><a class="glyphicon glyphicon-log-in" ui-sref="home.login">Login</a></li>
<li><a class="glyphicon glyphicon-user" href="#" ng-click="RegisterScreen()">Register</a></li>
</ul>
</div>
<li>About</li>
<div class="collapse" id="Contact">
<ul class="nav nav-pills nav-stacked">
<li><a class="glyphicon glyphicon-save" ui-sref="home.userDetails">LoadUserDetails</a></li>
<li><a class="glyphicon glyphicon-phone-alt" href="#">Contact</a></li>
</ul>
</div>
</ul>
</div>
<div ui-view=""/>
Don't forget to check documentation of ui-router:
http://angular-ui.github.io/ui-router/site/#/api
JSFiddle:
http://jsfiddle.net/7tzXh/48/

ng-click doesn't work on anchor element

Q1: I tried to use nav in bootstrap to make a navigation bar and bound ng-click to the anchors.
However after I click the anchor link,there is nothing happened.
Q2: I've noticed that the anchor link clicked won't be active by setting bg-color to it? How can this be implemented?
Here is the JSfiddle...
<div ng-controller="SuiteSectionCtrl">
<ul class="nav nav-pills nav-stacked">
<li class="active">All Suites
</li>
<li><a ng-click="handleClick">Suite1</a>
</li>
<li>Suite2
</li>
<li>Suite3
</li>
</ul>
The brackets for function invocation are missing. You should have:
ng-click="handleClick()"
Answering Q2:
Maybe there are smarter solutions, but this one works as well:
angular.module('myApp').controller('MenuCtrl', ['$scope', '$location', '$rootScope',
function ($scope, $location, $rootScope) {
$rootScope.$on('$locationChangeSuccess', function () {
var path = $location.path();
// you may apply logic on the path (group together in case of dropdown-menu e.g.)
$scope.topMenu = path;
});
}
]);
<div class="navbar navbar-inverse navbar-fixed-top" role="navigation"
ng-controller="MenuCtrl">
<div class="container-fluid">
<div class="navbar-header">
<!-- ... -->
</div>
<div class="navbar-collapse collapse" id="navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li ng-class="{active: topMenu == '/'}">
Home</li>
<li ng-class="{active: topMenu == '/about'}">
About</li>
<!-- more... -->
</ul>
</div>
</div>
</div>
I have Updated your code. Add ng-app directive to your body tag. And In your html change ng-click="handleClick" to ng-click="handleClick()"
<body ng-app="app"><div ng-controller="SuiteSectionCtrl">
<ul class="nav nav-pills nav-stacked">
<li class="active">All Suites
</li>
<li><a ng-click="handleClick()">Suite1</a>
</li>
<li>Suite2
</li>
<li>Suite3
</li>
</ul>
</div></body>
and our JS code is
var executionAPP = angular.module('app',[])//register your app
executionAPP.controller('SuiteSectionCtrl',['$scope',function($scope){
$scope.oneAtATime = true;
$scope.testSuites = [{title:"TestSuite1",content:"TestContent1"},
{title:"TestSuite2",content:"TestContent2"},
{title:"TestSuite3",content:"TestContent3"},
{title:"TestSuite4",content:"TestContent4"},
{title:"TestSuite5",content:"TestContent5"}];
$scope.handleClick = function(){
alert('Accordion clicked');
};
}]);
Updated Fiddle...

Categories

Resources