I have a button in a div with a controller named controllerBubble. I would like this button show a div controlled by an other controller : controllerDependance. Is it possible to wrap the button in a div and the hidden div with same controller but it doesn't works.
This is my HTML :
<div ng-app="app">
<div ng-controller="mainController" ng-show="myvalue" class="ng-cloak">
<div id="panelSap" ng-controller="controllerDependance">
My hidden div
</div>
</div>
<div id="containerDetailsTicket" class="clearfix" ng-controller="controllerBubble">
Div which contains the button
<div id="containerButton" ng-controller="mainController">
<button ng-click="showAlert()">Afficher</button>
</div>
</div>
</div>
This is my controllers :
var d3DemoApp = angular.module('app', [])
d3DemoApp.controller('controllerBubble', function() {
});
d3DemoApp.controller('controllerDependance', function($scope) {
$scope.myvalue = false;
$scope.showAlert = function() {
$scope.myvalue = true;
};
});
d3DemoApp.controller('mainController', function AppCtrl($rootScope, $scope) {
$scope.myvalue = false;
$scope.showAlert = function() {
$scope.myvalue = true;
};
});
I created a Plunker
Any idea what's happening ? Someone can do work on the Plunker. I Hope someone can help me.
Thanks a lot.
Look, not sure why you want to have such a nesting of controllers but I am pretty much sure that it ain't good. I'll tell you why. In your code, you are trying to use same controller at two DOM ele. So, they are having 2 different scope $scope and so they are not working.
I have made a working plunker for you by using $rootScopebut its not a clean approach as you'll be having a global variable ($rootScope.myvalue) declared. Declaring global variable should always be avoided unless forced to.
Another suggested approach in plunker is to use $emit as event notifier. The $on would take appropriate action when the event is triggered. You can even pass values that too to different controllers.
Service can also be used to pass values among controllers .
Let me know if you need more info
Update 1:
If you want to remove some div (not hide) then you should try to use ng-if.
Related
I have a modal and I want a progress bar to be shown while the data for modal display is being fetched by the service call. But in this case, progress bar is being fetched first and then the modal which makes the progress bar to be displayed under the modal. How to fix this ?
this.service.searchMembers(memSearchJson).subscribe((response: any) => {
// some function
}
<modal id="custom-modal-2">
<div class="modal">
</div>
<div id="memberSearchBar" class="class-hide">
<mat-spinner></mat-spinner>
Finding Member IDs..
</div>
</modal>
If document.getElementById("memberSearchBar").className = 'loading-div'; is called before the service call, it throws error as className null. Where should I call this to display progress bar on modal?
I would recommend using *ngIf, as mentioned above. For a better understanding, I add a link to the perfect tutorial.
Loading spinner
For example: in ts:
showSpinner: boolean = true;
ngOnInit() {
this.spinnerShow();
}
if you need show spinner before you get data like from service.
spinnerShow(){
this.workflowService.getData().subscribe(()=>
this.showSpinner = false);
}
And in HTML
<div *ngIf="showSpinner"></div>
Sorry for my terrible english, but i hope this will help you. :)
Instead of doing document.getElementById("memberSearchBar").className = 'loading-div' you can take advantage of Angular's *ngIf and [class.class-name]="expression"
Try something like this instead
displayModalAndSearchMembers(){
// using only isLoading should be sufficient, but I wanted to show how you could use [class.classname]="expression" in the html template as well.
this.isLoading = true;
this.showSpinner = true;
this.displayModal = true;
this.service.searchMembers(memSearchJson).subscribe((response: any) => {
// some function
this.isLoading = false;
this.showSpinner = false;
}
}
<modal id="custom-modal-2">
<div *ngIf="displayModal" class="modal"> <!-- added *ngIf -->
</div>
<div id="memberSearchBar" *ngIf="showSpinner" [class.loading-div]="isLoading">
<mat-spinner></mat-spinner>
Finding Member IDs..
</div>
</modal>
EDIT
You could also use *ngIf="displayModal" on the modal as well, in case you have some display: none on that one as well.
I added some ts code as well. I am not 100% sure what the desired behaviour OP wants, but I am assuming that she wants to show/hide the spinner, and set a class name on it.
This can be simplified by using only *ngIf="isLoading":
<div id="memberSearchBar" class="loading-div" *ngIf="showSpinner">
I'm using templates based on my JSON. So, I can't really use my ng-bind-html like I would normally do.
Seems like the only option I have is to use my sanitized html inside an directive.
Looking for similar questions, I couldn't figure it out how to apply in my case.
Yes, I am pretty newbie into angular.
I'm currently receiving this data from my controller:
$scope.safecontainers = $sanitize($scope.containersmsg);
In my html would normally be like this:
<p ng-bind-html="containersmsg"></p>
But I don't want this, I need to use this ng-bind-html inside a directive!
Some people have talked about $compile, but I couldn't really figure it out how to apply in my case.
EDIT:
Based on comments, i'll add more code to help you guys further understand my goal.
Inside my index.html I'm declaring the controllers needed and calling my
<ng-view></ng-view>
Then, based on what I receive, i'll load one view or another:
<div ng-if='setores[0].SetorTema == "1"'>
<theme-one titulo="{{setores[0].SetorNome}}" logo="
{{setores[0].SetorLogo}}" evento="{{evento[0].EventoNome}}">
</theme-one>
// I omitted some of the parameters because they ain't relevant
</div>
My template is like this: (Just a little part of it to avoid much useless code)
<section class="target">
<div class="col-md-6 col-xs-12">
<div class="" ng-repeat="banner in title">
<div class="target-title">{{ banner.BannerLevelTitulo }}
</div>
<div class="target-desc">{{banner.BannerLevelDescricao}}</div>
</div>
</div>
<div class="col-md-6 col-xs-hidden">
<div class="target-image"><img ng-src="{{targetimage}}" alt="">
</div>
</div>
</section>
This is the controller I want my sanitized code.
hotsite.controller('containerController', function($scope, $http, $sanitize)
{
$scope.containers = [];
$scope.containersmsg = '';
$scope.safecontainers = $sanitize($scope.containersmsg);
$http.get('/Admin/rest/getContainer')
.then(function onSuccess(response) {
var data = response.data;
$scope.containers = data;
$scope.containers = response.data.filter(containers =>
containers.ContainerAtivo);
$scope.containersmsg = $scope.containers[0].ContainerDesc;
})
.catch(function onError(response) {
var data = response.data;
console.log(data);
});
});
This is a piece of my directive:
angular.module('hotsiteDirectives', [])
.directive('themeOne', function($compile) {
var ddo = {};
ddo.restrict = "AE";
ddo.transclude = true;
ddo.scope = {
titulo: '#',
...
(a lot of other scope's)
contimg: '#'
};
ddo.templateUrl = 'app/directives/theme-one.html';
return ddo;
})
And yes, I am calling the ngSanitize
var hotsite = angular.module('hotsite',['ngRoute', 'hotsiteDirectives',
'ngSanitize']);
TL;DR
This is how my code looks like inside a directive, with raw html and not rendered:
This is how it works with ng-bind-html, formatted html
If I do put this inside my view
<p ng-bind-html="containersmsg"></p>
It will be alright, all of it working like it should.
BUT, I need to call this only inside my directive, and I don't know how to do it.
So, with this context:
How can I put my sanitized html inside my directive and template?
You don't even have to trust the html to render it using ngBindHtml because the directive already does it for you. You basically need to create a parameter attribute for your directive to hold the html string, so, inside the directive's template, you use ng-bind-html="myParam".
The following snippet implements a simple demonstration of creating a directive that receives and renders an html input parameter that comes from a controller.
angular.module('app', ['ngSanitize'])
.controller('AppCtrl', function($scope) {
$scope.myHtml = '<div><b>Hello!</b> I\'m an <i>html string</i> being rendered dynamicalli by <code>ngBindHtml</code></div>';
})
.directive('myDirective', function() {
return {
template: '<hr><div ng-bind-html="html"></div><hr>',
scope: {
html: '='
}
};
});
<div ng-app="app" ng-controller="AppCtrl">
<my-directive html="myHtml"></my-directive>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular-sanitize.js"></script>
I want to bind an array (customLayers) and use it for ng-repeat.
I fill the array inside the kv.colorMap Object.
I have three directives using these technique. But the directive updates the binded array on view ONLY after pressing a functionless button (checkResult), which is inside this directive.
Directive Template Code:
...
<div class="createInfo colorExprContainer">
<div ng-repeat="layer in customLayers">{{layer.color}}</div>
</div>
<div class="buttonWrapper text-center">
<button class="btn" ng-click="checkResult()">Ergebnis prüfen</button>
</div>
...
Directive JavaScript Code:
app.directive('boolKv', function($parse, $timeout){
return {
restrict: 'E',
replace:true,
scope:true,
templateUrl: "directives/boolKV/boolKV.html",
link: function($scope, $element, $attr) {
...
var kv = new BAKV({target: cv[0].id, expr: expr});
$scope.customLayers = kv.colorMap.layers;
...
$scope.checkResult = function(){console.log("it works!");};
});
Does someone have an idea?
Thank you very much!
Thank you MirMasej!
You were right, I was calling it after render. Maybe because I've used the EaselJs Library for canvas. I wanted to get the update after click on a block inside this canvas.
I solved it by adding, if someone has a better idea I would try it:
kv.colorMap.onChangedLayer = function(layer) {
$timeout(function(){
$scope.$apply();
});
};
Im calling this onChangedLayer event after changing the data inside the colorMap object.
I have an html form ( ) , I want that it is displayed when I click on a button.
the declaration of the form is the following :
<div id = "formulaire" class="gl" >
and the button is :
Edit
I use angularjs in my code . Please help me.
It better to use a simple variable than a function in this case. I would also recommend using controller scope when setting variables instead of the application scope so you don't run into issues with the variables when your application becomes large.
I also picked data-ng-click over ng-click because it will allow the html to validate correctly (which can be checked using the W3's validator).
Try this...
"use strict";
angular.module('myApp', [])
.controller("myController", function() {
this.edit = false;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<div data-ng-app="myApp" data-ng-controller="myController as ctrl">
Edit
<div id="formulaire" class="gl" data-ng-show="ctrl.edit">
<form>
<fieldset>
<label>Field:</label>
<input type="text" />
</fieldset>
</form>
</div>
</div>
Have you looked into the ngShow directive? It ables you to show or hide a DOM element depending on whether the attribute expression resolves to a truthey or falsey value.
Add model change on click
Edit
And then display the form if model is true
<div id = "formulaire" class="gl" ng-if="show">
My question is very similar to Hide element outside the ng-view DOM based on route
If possible I would like to have a TypeScript solution that allows to assign a value to ng-show property of an element outside of ng-view from my existing controllers.
I tried assigning a value to $rootScope property but it was not visible in index.html outside of the view.
Here's what I tried in controller constructors:
$rootScope.isForm = "true"; in one, and $rootScope.isForm = "false"; in another.
Inside my index.html I have the following:
<div class="navbar navbar-inverse">
....
<form <form class="navbar-form navbar-input-group" ng-show="$rootScope.IsForm">
...
</form>
...
</div>
...
<div "ng-view">
...
</div>
How should I go about it? Is there still a solution using $rootScope?
You can get the $rootScope inside your controllers and modify it there. i.e.
class FooController{
static $inject = ['$rootScope'];
constructor(public $rootScope){
// You can also do this based on some user action.
// Just a demo of how :
this.$rootScope.IsForm = true;
}
}