Access scope from ng-template - javascript

Using AngularJS, I want to access scope variable from inside a <script type="text/ng-template".
<script type="text/ng-template" id="firstDialogId">
<div class="ngdialog-message" align="center" id="download">
<h4 ng-show=isFrench>Télécharger la cartographie</h4>
<h4 ng-show=isEnglish>Download cartography</h4>
<a href="../downloads/PDF/{{currentLanguage}}/{{currentCartography}}.pdf" download>
<img src="../style/images/pdf-icon.png" alt="Download PDF" width="30%" height="30%">
</a>   
<a href="../downloads/VSD/{{currentCartography}}.vsd" download>
<img border="0" src="../style/images/vsd-icon.png" alt="Download VSD" width="30%" height="30%">
</a>   
<a href="../downloads/PNG/{{currentLanguage}}/{{currentCartography}}.png" download>
<img border="0" src="../style/images/PNG-icon.png" alt="Download PNG" width="30%" height="30%">
</a>   
<div class="ngdialog-buttons">
<button type="button" class="ngdialog-button ngdialog-button-primary" ng-click="closeThisDialog('button')">Close</button>
</div>
</div>
</script>
isFrench and isEnglish are 2 booleans from my controller.
Same for currentCartography and currentLanguage, they are strings from my controller.
I also tried with getter inside and outside of the controller, same result.

For those falling into the same issue :
Using ngDialog, we need to precise we want to use the scope.
In my case, I added the dialog open functions in my controller, I needed to edit the one I'm using in order to add the scope: $scope, line as follows :
$scope.openPlainCustomWidth = function () {
$rootScope.theme = 'ngdialog-theme-plain custom-width';
ngDialog.open({
template: 'firstDialogId',
controller: 'InsideCtrl',
className: 'ngdialog-theme-plain custom-width',
scope: $scope, // this line wasn't here before
closeByDocument: false
});
};

three things you can try
use ng-href instead of href
for ng-show remove double curly {{
if above two doesnt work use $parent (only if you are not using controller-as)

You are using ng-show incorrectly, it doesn't use {{}} expressions.
Try: ng-show="isFrench"
Beyond that it isn't clear what you are asking

Related

ng-click not working, trying to replace an image on click

I'm new of Angular JS, Well I'm trying to replace an image on click. i.e.,One Click on Img1 i would replace the previous image by Img1 and so on.
To achieve this I'm using ng-click. The thing is even the image names are being retrieved from DB.
So when I do this, it doesn't work-
<img class="img-responsive" src="images/products/{{oneItem.Image3}}" ng-click="current='{{oneItem.Image3}}'" />
Whereas works when I do this-
<img class="img-responsive" src="images/products/{{oneItem.Image3}}" ng-click="current='test3.jpg'" />
And I'm trying to replace it here-
<div class="trueimagger">
<img ng-src="WebDrop/images/products/{{ current }}" />
</div>
Can someone help me out by pointing where I'm messing it up.
Please lemme know if any additional info is needed. :)
ngClick expects an expression:
ng-click="current = oneItem.Image3"
You should also use ngSrc directive instead of src attribute directly:
<img class="img-responsive"
ng-src="images/products/{{oneItem.Image3}}"
ng-click="current = oneItem.Image3" />
You don't have to write double curly braces {{..}} in ng-click.
Instead, simply write:
<img class="img-responsive"
src="images/products/{{oneItem.Image3}}"
ng-click="current='oneItem.Image3'" />
I would change it directly on the controller so you can format your url without putting logic on the view
<!DOCTYPE html>
<html>
<head>
<script data-require="angularjs#1.5.8" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<script>
var app = angular.module('yourApp', [])
app.controller('FooCtrl', function($scope) {
$scope.imgSrc = 'http://www.freedigitalphotos.net/images/img/homepage/87357.jpg';
$scope.changeSrc = function() {
$scope.imgSrc = 'http://assets.barcroftmedia.com.s3-website-eu-west-1.amazonaws.com/assets/images/recent-images-11.jpg';
}
});
</script>
</head>
<body ng-app="yourApp">
<div ng-controller="FooCtrl">
<div class="trueimagger">
<img ng-src="{{ imgSrc }}" />
</div>
<button ng-click="changeSrc()">ChangeImgSrc</button>
</div>
</body>
</html>
here is a plunker with this idea

ng-click not firing $scope.doSomething(), onclick for same function works

The controller I'm using is:
angular.module('app.PostView', [])
.controller('PostViewCtrl', function($scope, $http, Constants) {
$scope.posts = [];
$scope.doSomething = function(){
console.log("in doSomething");
}
$http.get(Constants.POST_URL)
.then(function (response){
console.log(response);
var post = new PostFactory(response.data);
$scope.posts.push(post);
});
})
The view for the controller is
<div ng-repeat="post in posts" >
<div class="home-container">
<div id="details-container">
<!-- using single item Array instead of single iftem to fix linkify bug -->
<div ng-bind="post.desc"></div>
<span class="item-note single-post-details">
<!-- <div class="time-text">{{post.id}}</div> -->
<div class="title" >{{post.title}}</div>
</span>
<a ng-click="doSomething()" href="#" >{{post.name}}</a>
</div>
</div>
</div>
If I replace ng-click with onclick then doSomething is triggered. Currently it is not. The same Controller and html code in other controller/views does work.
When you clicking on the anchor, it change the routing as http://url/#, that listen by the $routeProvider & ng-view loads the default view and template as you are seeing on your side.
Basically you need to remove href="#" from your anchor link or just put href="" blank in that anchor. That would fix your problem.
<a ng-click="doSomething()" href="" >{{post.name}}</a>
Remove href completely
<a ng-click="doSomething()"
style='cursor:pointer' >{{post.name}}</a>

ng-click does not work on my directive of a slider

I use the structure provided by the yeoman with angular-generator.
The ng-click does not work in my directive, of a slider show, when I put the html directly in main.html (It only works when I put in the directive an templateurl, linked to the main.html , but this causes delay to load).
Html, that is inserted directly into main.html
<div images="images" class="slider" id="mauseOnOut">
<div class="slide" ng-repeat="image in images" ng-show="image.visible">
<a ng-href="{{image.url}}"><img ng-src="{{image.src}}" width="444" height="250"/>
<p class="texto">{{image.texto}}</p>
</a>
</div>
<ul class="minimagem" ng-show="images.length">
<li ng-repeat="image in images"><a ng-click="returner($index)"><img ng-src="{{image.src}}" width="70" height="56"/></a></li>
</ul>
<div class="arrows">
<img src="http://s5.postimg.org/qkfwdwi7n/right_arrow.png"/>
</div>
</div>
Main part of the directive (in jsFiddle have it complete)
myApp.directive('images', function ($timeout) {
return {
restrict: 'AE',
scope:{
images: '='
},
link: function (scope) {
scope.currentIndex=0;
scope.returner = function(index){
scope.currentIndex = index;
};
scope.next=function(){
scope.currentIndex<scope.images.length-1?scope.currentIndex++:scope.currentIndex=0;
};
scope.prev=function(){
scope.currentIndex>0?scope.currentIndex--:scope.currentIndex=scope.images.length-1;
};
scope.$watch('currentIndex',function(){
scope.images. forEach(function(image){
image.visible=false;
});
scope.images[scope.currentIndex].visible=true;
});
},
};
});
Put an example in jsFiddle ; when use angular 1.1, on jsFiddle, operate normally, with 1.2 or higher does not work. In my application I use the angular 1.3.10 .
How could make it work in my application? It could be to ' compile ' or in some other way , the important thing is the click staying active in the image thumbnails and arrows .
Edited: I came back with the best known directive , best to understand.

Template for directive must have exactly one root element

I am new to angularJs. I am trying to create new directive which contains input element and a button. I want to use this directive to clear input text when button is clicked.
When I use my directive in html I am getting below error :
Error: [$compile:tplrt] Template for directive 'cwClearableInput' must have exactly one root element.
html:
<div class="input-group">
<cw-clearable-input ng-model="attributeName"></cw-clearable-input>
</div>
clearable_input.js:
angular.module('cw-ui').directive('cwClearableInput', function() {
return {
restrict: 'EAC',
require: 'ngModel',
transclude: true,
replace: true,
template: '<input type="text" class="form-control"/><span class="input-group-btn"><button type="button" class="btn" ng-click="" title="Edit"><span class="glyphicon-pencil"></span></button></span>',
controller: function( $scope ) {
}
};
});
I am not able to figure it out how to achieve this.
Well, the error is pretty self-explanatory. Your template needs to have a single root and yours has two. The simplest way to resolve this would be to just wrap the whole thing in a div or a span:
template: '<div><input type="text" class="form-control"/><span class="input-group-btn"><button type="button" class="btn" ng-click="" title="Edit"><span class="glyphicon-pencil"></span></button></span></div>',
Before:
<input type="text" class="form-control"/>
<span class="input-group-btn">
<button type="button" class="btn" ng-click="" title="Edit">
<span class="glyphicon-pencil"></span>
</button>
</span>
After:
<div> <!-- <- one root -->
<input type="text" class="form-control"/>
<span class="input-group-btn">
<button type="button" class="btn" ng-click="" title="Edit">
<span class="glyphicon-pencil"></span>
</button>
</span>
</div>
This error will also occur if the path to the template is incorrect, in which case the error is everything but explanatory.
I was referring the template from within templates/my-parent-template.html with the (incorrect)
template-url="subfolder/my-child-template.html"
I changed this to
template-url="templates/subfolder/my-child-template.html"
which solved it.
Just wrap your template in something:
template: '<div><input type="text" class="form-control"/><span class="input-group-btn"><button type="button" class="btn" ng-click="" title="Edit"><span class="glyphicon-pencil"></span></button></span></div>',
If you don't want to make one root element you can instead set replace to false. In your directive you are setting it to true, which replaces the directive tag "cw-clearable-input" with the root element of your directive.
If you have a comment in your template alongside the root element in the directive template, you will see the same error.
Eg. If your directive template has HTML like this (with "replace" set to true in the directive JS), you will see the same error
<!-- Some Comment -->
<div>
<p>Hello</p>
</div>
So to resolve this in scenarios where you want to retain the comments you will need to move the comment so that it is inside the template root element.
<div>
<!-- Some Comment -->
<p>Hello</p>
</div>
When none of this worked for me, prefixing a / to the template path fixed the issue in my case.
function bsLoginModal() {
return {
restrict: 'A',
templateUrl:'/app/directives/bootstrap-login-modal/template.html',
link: linkFunction,
controller: SignInCtrl,
controllerAs: 'vm'
}
}
instead of
templateUrl:'app/directives/bootstrap-login-modal/template.html
Good Luck.
Check your template or templateUrl
templateUrl: 'some/url/here.html'
template: '<div>HTML directly goes here</div>'
My problem was that webpack's HtmlWebpackPlugin was appending a script tag to the directive content. So angular was seeing:
<div>stuff</div>
<script type="text/javascript" src="directives/my-directive"></script>
The solution is to use HtmlWebpackPlugin's inject option in your webpack.config.js:
new HtmlWebpackPlugin({
template: './src/my-directive.html',
filename: './src/my-directive.html',
inject: false
}),

ng-switch is not matching with the expected option

I'm having problems with angularjs ng-switch
JS
function TestCtrl($scope) {
$scope.currentUser = {"userId":"1","userRole":"N"};
$scope.userRoles = {"normal":"N","admin":"A"}
$scope.patient = {name: 'John'};
}
HTML
<div ng-switch on="currentUser.userRole">
<a ng-switch-when="userRoles.normal" href="normalUrl">
{{patient.name}}
</a>
<a ng-switch-when="userRoles.admin" href="adminUrl">
{{patient.name}}
</a>
<div ng-switch-default> default </div>
</div>
</div>
I expect the name of the patient to be displayed with a link to normalUrl but 'default' is displayed. What am I doing wrong?
Here is a fiddle with the code
The ngSwitchWhen directive does not evaluate expressions (although I've heard this might be added to 1.3). The value is interpolated as a string literal, so you would have to use it like this:
<a ng-switch-when="N" href="normalUrl">
That will work, but if you really need to dynamically determine your when value, then maybe ngIf will better suit your needs:
<a ng-if="currentUser.userRole === userRoles.normal" href="normalUrl">
<a ng-if="currentUser.userRole === userRoles.admin" href="adminUrl">

Categories