How can i make this work with AngularJS? Have this list left-side, and need to change the center div content from the click in this list.
I'm using NG-CLICK and NG-REPEAT to get the click and generate the list from a JSON.
angular.module('duall')
.controller('documentationController', [
'$scope',
'$http',
function($scope, $http){
$scope.docs = [];
$http.get('static/titles.json').success(function(doc){
$scope.docs = doc;
}).error(function(error){
console.log(error);
});
$scope.cliked = function(index){
$scope.item = $scope.docs[index]
};
}]);
<div ng-controller="documentationController">
<div class="row">
<div class="col s3" >
<div class="input-field col s12" >
<input id="search" type="search" ng-model="q" aria-label="filter docs"/>
<label for="search"><strong>Pesquise Algo! :)</strong></label>
<i class="material-icons prefix">search</i>
</div>
<ul class="animate-container">
<!-- <li ng-repeat="docs in docs | orderBy:'title' | filter:q as results "> -->
<li ng-repeat="docs in docs | filter:q as results ">
<i class="material-icons tiny">search</i>
<a ng-click="cliked($index)" href="">{{docs.title}}</a>
<div class="divider"></div>
<br>
</li>
<li ng-if="results.length === 0">
<strong>Nada encontrado :(</strong>
</li>
</ul>
</div> <!-- Fim col s3 -->
<div class="col s9">
<div class="container">
CONTENT CLICKED MUST BE HERE!
</div>
</div>
</div><!-- Fim col s9 -->
</div><!-- fim ROW -->
</div><!-- Fim Controller -->
on the ng-click you can call a function that affect a variable that will contain what you want to see in your container. the following code is only a sample to show you the idea :
First in a ng-repeat you can call a function with ng-click directive :
<li ng-repeat="docs in docs | filter:q as results ">
<i class="material-icons tiny">search</i>
<a ng-click="cliked($index)" href="">{{docs.title}}</a>
<div class="divider"></div>
<br>
</li>
Function that will affect a specific variable
$scope.cliked = function(index){
$scope.item = $scope.docs[index]
};
Variable that you can display in the good container :
<div class="container">
{{$scope.item}}
</div>
Related
This question it is a continue of the last question.
My last question in Stackoverflow
I am trying to create some A4 pages within the Objects that I have in the json file.
The last guys which answered me it, imediately stopped when I approved the answer.
But the case here it is I need your help to help me further with my problem.
The problem it is that, when the text in one property it is larger then the A4 page the directive it doesn't add new page in realtime but only in reload.
I have for example in my json tree like this.
Category -> SubCategory -> Properties.
So i need to check if the Category it is larger then A4, if the SubCategory is larger and if the property is larger as the height of A4.
I am trying to create something like Xing.
https://lebenslauf.com/
The design it look the same but instead editing in the page I have the edit logic in the modals
Here is the code what I have tried till now.
All for A4 pages
<!-- display: none style will any child that does not have #pageContent local variable defined -->
<div class="content-wrapper" #contentWrapper style="display: block">
<ng-content></ng-content>
</div>
<div class="paginated-view" #paginatedView>
</div>
export class PaginatedViewComponent implements AfterViewInit {
#Input() pageSize: "A3" | "A4" = "A4";
#ViewChild("paginatedView") paginatedView: ElementRef<HTMLDivElement>;
#ViewChild("contentWrapper") contentWrapper: ElementRef<HTMLDivElement>;
#ContentChildren(PageContentDirective, { read: ElementRef })
elements: QueryList<ElementRef>;
constructor(private changeDetector: ChangeDetectorRef ) {}
ngAfterViewInit(): void {
this.updatePages();
// when ever childs updated call the updatePagesfunction
this.elements.changes.subscribe((el) => {
this.updatePages();
});
}
updatePages(): void {
// clear paginated view
this.paginatedView.nativeElement.innerHTML = "";
// get a new page and add it to the paginated view
let page = this.getNewPage();
this.paginatedView.nativeElement.appendChild(page);
let lastEl: HTMLElement;
// add content childrens to the page one by one
this.elements.forEach((elRef) => {
const el = elRef.nativeElement;
// if the content child height is larger than the size of the page
// then do not add it to the page
if (el.clientHeight > page.clientHeight) {
return;
}
// add the child to the page
page.appendChild(el);
// after adding the child if the page scroll hight becomes larger than the page height
// then get a new page and append the child to the new page
if (page.scrollHeight > page.clientHeight) {
page = this.getNewPage();
this.paginatedView.nativeElement.appendChild(page);
page.appendChild(el);
}
lastEl = el;
});
this.changeDetector.detectChanges();
// bring the element in to view port
// lastEl.scrollIntoView({ behavior: "smooth", block: "nearest" });
}
getNewPage(): HTMLDivElement {
const page = document.createElement("div");
page.classList.add("page");
page.classList.add(this.pageSize);
return page;
}
}
#Directive({
// tslint:disable-next-line: directive-selector
selector: "[pageContent]"
})
export class PageContentDirective {
}
This is my HTML when I try to show data
<div style="transition: transform 0.25s ease 0s;transform: scale(1.3);transform-origin: 50% 0px 0px;backface-visibility: hidden;perspective: 1000px;display: block;margin: 0px 11.5385%;font-size:10px;width: 76.9231%;-webkit-font-smoothing: antialiased;">
<app-paginated-view [pageSize]="'A4'" *ngIf="model" class="Grid-grid-column">
<div pageContent class="row">
<div class="col col-lg-7">
<h4>{{currentUser?.firstName}} {{currentUser?.lastName}}</h4>
</div>
<div class="col text-right">
<input type="file" accept="image/*" (change)="readUrl($event)">
<img [src]="url" (change)="readUrl($event)" height="128" style="cursor: pointer">
</div>
</div>
<div pageContent class="Unit-unit-unitGroup"
*ngFor="let personalData of model.personalData; let id = index">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.PersonalData}">
<ng-container *ngIf="selectedCategory === category.PersonalData" clickOutside (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.PersonalData)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.PersonalData' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container>
<app-personal-data [personalData]="personalData" [model]="model" [id]="id">
</app-personal-data>
</ng-container>
</div>
</div>
</div>
<!-- Career Component -->
<ng-container *ngFor="let careers of model.careers" class="Unit-unit-unitGroup">
<div pageContent class="col-md-12">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Career' | translate}}</div>
</div>
</h3>
</div>
</div>
<div class="container-fluid" pageContent>
<ng-container *ngFor="let careerObj of careers.subCategories; let i = index">
<app-career [careerObj]="careerObj" [id]="i" [career]="careers" [model]="model"></app-career>
</ng-container>
<ng-container *ngFor="let emptyObj of careers.emptySubContents; let iEmpty = index">
<app-empty-object [emptyObj]="emptyObj" [iEmpty]="iEmpty" [model]="model" [isFromCareer]="true"></app-empty-object>
</ng-container>
</div>
</ng-container>
<!--Education Component-->
<ng-container *ngFor="let education of model.education" class="Unit-unit-unitGroup">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.Education}">
<ng-container *ngIf="selectedCategory === category.Education" clickOutside (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.Education)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Education' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container *ngFor="let educationObj of education.subCategories; let i = index" class="col-md-12">
<app-education [educationObj]="educationObj" [id]="i" [education]="education" [model]="model"></app-education>
</ng-container>
</div>
</div>
</ng-container>
<!-- Skills Component-->
<ng-container *ngFor="let skills of model.skills" class="Unit-unit-unitGroup">
<div pageContent [ngClass]="{ 'isCatActive': selectedCategory === category.Skills}">
<ng-container clickOutside *ngIf="selectedCategory === category.Skills" (clickOutside)="removeClick()">
<ul>
<li class="fa fa-plus addIconTop" (click)="openDialog()"></li>
<li class="fa fa-plus addIconBottom" (click)="openDialog()"></li>
<li class="fa fa-trash deleteIconRight" (click)="deleteCategory(index)"></li>
<li class="fa fa-arrow-down moveIconDown"></li>
<li class="fa fa-arrow-up moveIconTop"></li>
</ul>
</ng-container>
<div pageContent class="col-md-12" (click)="setCategory(category.Skills)">
<div class="row height">
<div class="col-md-4 col-sm-6 text-right tLine"></div>
<h3 class="first-template-paragraphTitle Paragraph-paragraph-title height">
<div class="Text-text-wrapper">
<div class="Text-Text-text">{{'category.Skills' | translate}}</div>
</div>
</h3>
</div>
</div>
<div pageContent class="container-fluid">
<ng-container *ngFor="let skillObj of skills.subCategories; let i = index" class="col-md-12">
<app-skills [skillObj]="skillObj" [id]="i" [skills]="skills" [model]="model"></app-skills>
</ng-container>
</div>
</div>
</ng-container>
</app-paginated-view>
</div>
And this is the css
.A4 {
width: 595px;
height: 842px;
padding: 25px 25px;
position: relative;
}
If you want to see more code, here is the stackblitz.
Stackblitz
And here is the screenshot which is the current design.
As you can see here the space in the Career it is very large it should not be like that.
It should add the text based on the height and if is alrger then cut the text and the other text add to new page.
I am quite new with AngularJS so excuse me if I'm asking a stupid thing. I'm trying to create a task manager for events with AngularJS + Mysql + PHP.
The layout is separated in two columns. In the left column there's an overview of staff, loaded by function getUsers() in app.js. By clicking the + button after each staffname the user_id is being posted in a mysql database table. The results of this table is shown in the right column, function getEventUsers() in app.js. I'm trying to find out how to reload or update the right table after clicking the + button. The functions itself are working correctly (they get json_encoded results from the .php pages), but the right column is not updating itself only after pressing F5 after each click it is showing the correct result. So the right column, so function getEventUsers() in app.js, has to refresh/reload after clicking on the + button.
Template
ng-app="myApp" is in the html tag
ng-controller="usersController" is in the body tag
<div class="row">
<div class="container">
<blockquote><h1>Task Manager</h1></blockquote>
<div class="col-md-6">
<div class="widget-box" id="recent-box" ng-controller="usersController">
<div class="widget-header header-color-blue">
<div class="row">
<div class="col-sm-6">
<h4 class="bigger lighter">
<i class="glyphicon glyphicon-align-justify"></i>USERS
</h4>
</div>
<div class="col-sm-6">
<input type="text" ng-model="filterTask" class="form-control search header-elements-margin" placeholder="Filter Tasks">
</div>
</div></div>
<div class="widget-body ">
<div class="task">
<label class="checkbox" ng-repeat="user in users | filter : filterTask">
<input
type="checkbox"
value="{{user.active}}"
ng-checked="user.active==1"
ng-click="toggleStatus(user.id,user.active)"/>
<span ng-class="{strike:user.active==0}">{{user.firstname}} {{user.lastname}} [{{user.id}}]</span>
<a ng-click="addEventUser(user.id)" class="pull-right"><i class="glyphicon glyphicon-plus"></i></a>
</label>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="widget-box" id="recent-box" ng-controller="usersController">
<div class="widget-header header-color-blue">
<div class="row">
<div class="col-sm-6">
<h4 class="bigger lighter">
<i class="glyphicon glyphicon-align-justify"></i>EVENT MANAGER
</h4>
</div>
<div class="col-sm-6">
<input type="text" ng-model="filterTask" class="form-control search header-elements-margin" placeholder="Filter Tasks">
</div>
</div></div>
<div class="widget-body ">
<div class="task">
<label class="checkbox" ng-repeat="eventuser in eventusers | filter : filterTask">
<span ng-class="{strike:task.STATUS==2}">{{eventuser.firstname}} [{{eventuser.lastname}}]</span>
<a ng-click="deleteTask(eventuser.id)" class="pull-right"><i class="glyphicon glyphicon-trash"></i></a>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="app/app.js"></script>
App.js
//Define an angular module for our app
var app = angular.module('myApp', []);
app.controller('usersController', function($scope, $http) {
getUsers(); // Load all available users
function getUsers(){
$http.post("ajax/getUsers.php").success(function(data){
$scope.users = data;
//alert(data);
});
};
getEventUsers(); // Load all available users for event
function getEventUsers(){
$http.post("ajax/getEventUsers.php").success(function(data){
$scope.eventusers = data;
//alert(data);
});
};
$scope.addEventUser = function (user_id) {
$http.post("ajax/addEventUser.php?userid="+user_id).success(function(data){
alert(getEventUsers());
});
};
$scope.toggleStatus = function(item, status) {
if(status=='1'){
active='0';
}else{
active='1';
}
$http.post("ajax/updateUsers.php?id="+item+"&active="+active).success(function(data){
getUsers();
});
};
});
I want to generate unique variable share in *ngFor so I can open single modal.
<li *ngFor="let gallery of galleries; let i = index">
<div class="gallery card" >
<div class="share-fab" (click)="share = !share" [class.open]="share">
<div class="option email" [class.open]="share"><i class="material-icons">email</i></div>
<div class="option download" [class.open]="share"><i class="material-icons">file_download</i></div>
<div class="option facebook" [class.open]="share"><i class="material-icons">whatshot</i></div>
<div class="option twitter" [class.open]="share"><i class="material-icons">notifications_none</i></div>
<div class="close" [class.open]="share"><i class="material-icons cross">close</i></div>
</div>
</div>
</div>
</li>
I appreciate any help...
You should add a property share to your gallery object, for instance:
export class Gallery {
//...
public share: boolean = false;
}
In your template you can do something like this:
<li *ngFor="let gallery of galleries; let i = index">
<div class="gallery card" >
<div class="share-fab" (click)="gallery.share = !gallery.share" [class.open]="gallery.share">
<div class="option email" [class.open]="gallery.share"><i class="material-icons">email</i></div>
<div class="option download" [class.open]="gallery.share"><i class="material-icons">file_download</i></div>
<div class="option facebook" [class.open]="gallery.share"><i class="material-icons">whatshot</i></div>
<div class="option twitter" [class.open]="gallery.share"><i class="material-icons">notifications_none</i></div>
<div class="close" [class.open]="gallery.share"><i class="material-icons cross">close</i></div>
</div>
</div>
</div>
</li>
Another option would be to create a variable in your component where you keep track of which galleries should be active. Pretty sure you will figure out how to do that yourself :)
I have this JSON with list of topics and path to the template (ng-include) of this topic, like this:
{"id":"01","title":"Primeiros Passos no sistema",
"url":"static/doc/01.html" },
I already can make a list from the JSON with NG-REPEAT, but how can I make a list of my templates in javascript?
angular.module('duall')
.controller('documentationController', [
'$scope',
'$http',
function($scope, $http){
$scope.docs = [];
$http.get('static/titles.json').success(function(doc){
$scope.docs = doc;
}).error(function(error){
console.log(error);
});
//caminho onde estão os arquivos
//var path = "static/doc/";
//caminho para os templates 'htmls' de cada parte da documentação já formatados
//$scope.templates = [
//{name: 'Primeiros Passos', url:path+'01.html'},
//{name: 'Login', url:path+'02.html'}
//];
for(i = 0; i < $scope.docs.$index; i++ ){
$scope.templates.name[i] = $scope.docs.name[i];
$scope.templates.url[i] = $scope.docs.url[i];
}
$scope.template = $scope.templates[0];
$scope.cliked = function(index){
$scope.template = $scope.templates[index];
console.log(index);
};
}]);
<div ng-controller="documentationController">
<div class="row">
<div class="col s3" >
<div class="input-field col s12" >
<input id="search" type="search" ng-model="q" aria-label="filter docs"/>
<label for="search"><strong>Pesquise Algo! :)</strong></label>
<i class="material-icons prefix">search</i>
</div>
<ul class="animate-container">
<!-- <li ng-repeat="docs in docs | orderBy:'title' | filter:q as results "> -->
<li ng-repeat="docs in docs | filter:q as results ">
<i class="material-icons tiny">search</i>
<a ng-click="cliked($index)" href="">{{docs.title}}</a>
<div class="divider"></div>
<br>
</li>
<li ng-if="results.length === 0">
<strong>Nada encontrado :(</strong>
</li>
</ul>
</div> <!-- Fim col s3 -->
<div id="container-doc" class="col s9">
<br>
<div class="container left" ng-include="template.url">
</div>
</div>
</div><!-- Fim col s9 -->
</div><!-- fim ROW -->
</div><!-- Fim Controller -->
I have this Vue instance:
var vm = new Vue({
el: '#app',
data: {
user: {
email: '',
password: '',
passwordconfirm: '',
bars: {},
authentication_token: '',
id: 0
}
},
components: {
dashboard: dashboard
},
events: {
'onLoginSuccesfull': function(user) {
// do stuff with user obj
this.$broadcast('onUserLoggedIn');
}
}
}
It has a 'dashboard' component:
var dashboard = Vue.extend({
template: '#dashboard',
data: function() {
return {
currentPage: 'main'
}
},
components: {
'dashboard-mainpage': dashboardmainpage
}
events: {
'onUserLoggedIn': function() {
alert('I should be firing bu I am not!');
}
}
});
Vue.component('dashboard', dashboard);
The 'dashboard' has a 'dashboard-mainpage' component:
var dashboardmainpage = Vue.extend({
template: '#dashboard-mainpage',
methods: {
loadData: function() {
this.$http.get('/dashboard/main.json', {
authenticity_token: window._token
}).then(function(response) {
var data = JSON.parse(response.body);
console.log(data);
}, function(response) {
console.log(response);
this.$dispatch("onRequestUnauthorized");
});
}
},
events: {
'onUserLoggedIn': function() {
alert('I should be firing as well but I am not!');
this.loadData();
}
}
});
The problem is that when the 'onLoginSuccesfull' event is triggered on the main Vue instance, the subsequently broadcasted 'onUserLoggedIn' on the 1st and 2nd level descendant are not triggered, when calling 'this.$broadcast('onUserLoggedIn');'.
I know that event callbacks must return true to keep propagating down the chain but the first event callback (on 'dashboard') is not even triggered.
What am I missing?
Thanks!
===== EDIT =====
Main app:
<div id="app">
<dashboard v-if="currentStep == 'dashboard'" v-bind:appname="appName" v-bind:dashboard-vm="dashboard" v-bind:user="user" v-bind:bar.sync="bar"></dashboard>
</div>
Dashboard template:
<template id="dashboard">
<div class="container body">
<div class="main_container">
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
<span>The Bar</span>
</div>
<div class="clearfix"></div>
<br />
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
{{ user.email }}
<div class="menu_section">
<ul class="nav side-menu">
<li><a v-on:click="createNewBar"><i class="fa fa-plus"></i> Create new bar</a>
</li>
<li><a v-on:click="showDashboard"><i class="fa fa-bar-chart"></i> Dashboard</a>
</li>
<li><a v-on:click="showBars"><i class="fa fa-bars"></i> Bars</a>
</li>
<li><a><i class="fa fa-tachometer"></i> Settings <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a v-on:click="showProfile">Profile</a></li>
<li><a v-on:click="showPaymentsPlans">Plan & payments</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- /sidebar menu -->
</div>
</div>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<nav>
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li class="">
<a v-on:click="$parent.logoutUser" style="cursor: pointer">Log out</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main">
<dashboard-mainpage v-if='currentPage == "main"' v-bind:vm="dashboardVm"></dashboard-mainpage>
</div>
</div>
<!-- /page content -->
<!-- footer content -->
<footer>
<div class="pull-right">
© <%= Time.now.year %> The Bar
</div>
<div class="clearfix"></div>
</footer>
<!-- /footer content -->
</div>
</div>
</template>
Dashboard-mainpage:
<template id="dashboard-mainpage">
<div class="col-md-12 x_title">
<div>
<div class="btn-group pull-right">
<button type="button" class="btn btn-info"><span class="fa fa-calendar" aria-hidden="true"></span> Today</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li>
Today
</li>
<li>
Yesterday
</li>
<li>
Last 7 days
</li>
<li>
Last 30 days
</li>
<li>
Last year
</li>
<li>
All
</li>
</ul>
</div>
<span class="pull-right">Filter:</span>
</div>
</div>
<!-- top tiles -->
<div class="row top_tiles">
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-bars"></i></div>
<div class="count">{{ vm.totalBars }}</div>
<h3>Total bars</h3>
<p>All you active bars</p>
</div>
</div>
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-eye"></i></div>
<div class="count">{{ vm.totalViews }}</div>
<h3>Total views</h3>
<p>Total number of bar views</p>
</div>
</div>
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-mouse-pointer"></i></div>
<div class="count">{{ vm.totalClicks }}</div>
<h3>Total clicks</h3>
<p>Total number of clicks</p>
</div>
</div>
</div>
<!-- /top tiles -->
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="dashboard_graph">
<div class="row x_title">
<div class="col-md-6">
<h3>Statistics</h3>
</div>
<div class="col-md-6">
<div id="reportrange" class="pull-right" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc">
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
<span>December 30, 2014 - January 28, 2015</span> <b class="caret"></b>
</div>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_title">
<h2>Sub title</h2>
<div class="clearfix"></div>
</div>
<p>stats here</p>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
<br />
</template>
Ok. For anyone who is going to wander onto this "issue". Here's the fix.
I used 'v-if' attributes on the children that were listening to the 'onUserLoggedIn' event. The docs for 'v-if' say:
Conditionally render the element based on the truthy-ness of the
expression value. The element and its contained data bindings /
components are destroyed and re-constructed during toggles. If the
element is a element, its content will be extracted as the
conditional block.
So, when 'v-if = "something false"' on some child component it practically does not exist and thus is not able to do or respond to anything, including events.
When using 'v-show' instead of 'v-if' to conditionally toggle certain components, the component stays "alive" and will be able to respond.
Some stuff going on:
If you define a component in another component (as you are doing in the app component, there is no need to define this component globally (https://vuejs.org/guide/components.html#Registration-Sugar).
If a component is not "called" inside another component's template, you never establish a relation parent-children between them. I can't see the template of the App component, so I assume there is none.
There is some bits of code missing, but I assume that onLoginSuccesfull never gets actually called on the App component to begin with!
As you say, if you want an event to propagate after it's been triggered for the first time, this triggering function must return true.
Here's a working jsfiddle with the basics covered: https://jsfiddle.net/e85ekxk1/2/
Good luck!