How to write HTML code in $rootScope variable using angularJS? - html

I am trying to change the value of a label in my HTML page on an event,is it possible to insert html code into the variable?
The HTML code is like:
<div ng-controller="welcomeCon" ><label>{{ welcomemsg }}</label></div>
and in some controller in the script:
$rootScope.welcomemsg="You are not logged in,please log in or register"
Is there a way to make the words log in and register to be links?
If no, I would be happy if someone could guide me what to do in alternative.
Thanks

Use $sce service. Here is the sample example
angular.module('app',[])
.controller("welcomeCon", function($scope,$sce){
$scope.loginHtml = "You are not logged in,please <a href=''>log in</a> or <a href=''>register</a>";
$scope.trustedHtml = $sce.trustAsHtml($scope.loginHtml);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<div ng-app="app" ng-controller="welcomeCon">
<div ng-bind-html="trustedHtml">
</div>
</div>
OR you can use ngSanitize module
angular.module('app',["ngSanitize"])
.controller("test", function($scope){
$scope.html = "You are not logged in,please <a href=''>log in</a> or <a href=''>register</a>";
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.2/angular-sanitize.js"></script>
<div ng-app="app" ng-controller="test">
<div ng-bind-html="html">
</div>
</div>

You can do that as the other answers suggest by using the $sce service or ng-bind-html, but I would object to that approach because the links won't change, so why do it by defining the html in your code instead of in the html.
What you probably want is something like this:
<ul class="my-menu">
<li ng-if="$root.loggedIn">
Logout
</li>
<li ng-if="!$root.loggedIn">
You are not logged in, please login or register
</li>
</ul>

Use ng-bind-html directive to bind HTML to the model value. See link: http://www.w3schools.com/angular/ng_ng-bind-html.asp
You need to use ngSanitize module in your application. Include angular-santize.js file to do it.

I know you've already got your answer, but just to put this out there...
You can also do this using a very simple directive as like a child view, and avoid using $rootScope all together. This promotes reuse across applications, and follows angular's modular approach of breaking things down into small parts (in this case very small parts!).
welcomeMessage.js
app.directive('welcomeMessage', function() {
return {
restrict: "E",
templateUrl: "welcomeMessage.html"
};
});
welcomeMessage.html
<p>
You are not logged in, please
log in or
register
</p>
Sample Usage (in your index.html)
<welcome-message />
Sample Plunk

Related

automatically read path to Razor page in Nav Menu

What I want to do is to read the path as indicated with the #page attribute of every Razor Page, to link to it in the Nav Menu. With the purpose of not having to manually redo a href when for whatever reason I want to change the url.
I did however not find a way to read the page attribute from components, am I missing something or is there another way of doing this?
Just to visualise what I want, this is how it should roughly look in the end:
<div class="nav-item px-3">
<NavLink class="nav-link" href=UploadPage.page>
<span class="oi oi-data-transfer-upload" aria-hidden="true"></span> Content Upload
</NavLink>
</div>
The blazor framework doesn't expose any public APIs* to do what you want. You could perhaps post on github as a feature request.
*Internally, a route table is generated by scanning your assembilies for RouteAttribute.
Having said that, there is this blog post about using source generators to read the RouteAttribute of each component and generate the nav menu for you. Unfortunately, in order to use it, you have to turn off razor source generation to do it currently as source generators cannot see the output of other source generators. Hopefully in the future, we will be able to use source generators with the razor compiler (Here is the issue tracking it).
Thanks to the input by Jesse Good I found the following relatively simple answer to my problem, using reflection.
The Navmenu:
<div class="nav-item px-3">
<NavLink class="nav-link" href="#(PathTo<MyRazorPage>())">
<span class="oi oi-book" aria-hidden="true"></span> My ePaper
</NavLink>
</div>
The resolving Function:
private string PathTo<T>()
{
var attributes = typeof(T).GetCustomAttributes(typeof(Microsoft.AspNetCore.Components.RouteAttribute), inherit: false);
var route = (Microsoft.AspNetCore.Components.RouteAttribute) attributes[0];
return route.Template;
}

AngularJS - Modal view not showing [duplicate]

When both, href and ng-click attributes are defined:
Sign out
the href attribute takes precedence over ng-click.
I am looking for a way to raise priority of ng-click.
href is required for Twitter Bootstrap, I can't remove it.
This example from the angular documentation site just does href without even assigning it to an empty string:
[<a href ng-click="colors.splice($index, 1)">X</a>]
http://docs.angularjs.org/api/ng.directive:select
You can simply prevent the default behavior of the click event directly in your template.
<a href="#" ng-click="$event.preventDefault();logout()" />
Per the angular documentation,
Directives like ngClick and ngFocus expose a $event object within the scope of that expression.
Here is another solution :
Sign out
i.e. Just remove the # from the href attribute
You should probably just use a button tag if you don't need a uri.
Just one more hint. If you need real URL (to support browser accessibility) you can do the following:
template:
<a ng-href="{{link}}" ng-click="$event.preventDefault(); linkClicked(link)">{{link}}</a>
directive:
$scope.linkClicked = function(link){
// your code here
$location.path(link);
};
In this way your code in linkClicked() will have chance to execute before navigating to the link
In Angular, <a>s are directives. As such, if you have an empty href or no href, Angular will call event.preventDefault.
From the source:
element.on('click', function(event){
// if we have no href url, then don't navigate anywhere.
if (!element.attr(href)) {
event.preventDefault();
}
});
Here's a plnkr demonstrating the missing href scenario.
This worked for me in IE 9 and AngularJS v1.0.7:
Logout
Thanks to duckeggs' comment for the working solution!
There are so many answers for this question here but it seems there is a bit of confusion about what's actually going on here.
Firstly, your premise
"href overrides ng-click in Angular.js"
is wrong. What is actually happening is that after your click, the click event is first handled by angular(defined by ng-click directive in angular 1.x and click in angular 2.x+) and then it continues to propagate(which eventually triggers the browser to navigate to the url defined with href attribute).(See this for more about event propagation in javascript)
If you want to avoid this, then you should cancel the event propagation using the The Event interface's preventDefault() method:
<a href="#" ng-click="$event.preventDefault();logout()" />
(This is pure javascript functionality and nothing to do with angular)
Now, this will already solve your problem but this is not the optimal solution. Angular, rightfully, promotes the MVC pattern. With this solution, your html template is mixed with the javascript logic. You should try to avoid this as much as possible and put your logic into your angular controller. So a better way would be
<a href="#" ng-click="logout($event)" />
And in your logout() method:
logout($event) {
$event.preventDefault();
...
}
Now the click event will not reach the browser, so it will not try to load the link pointed by href. (However note that if the user right clicks on the link and directly opens the link, then there won't be a click event at all. Instead it will directly load the url pointed by the href attribute.)
Regarding the comments about visited link color in the browsers. Again this has nothing to do with angular, if your href="..." points to a visited url by your browser by default the link color will be different. This is controlled by CSS :visited Selector, you can modify your css to override this behaviour:
a {
color:pink;
}
PS1:
Some answers suggest to use:
<a href .../>
href is an angular directive. When your template is processed by angular this will be converted to
<a href="" .../>
Those two ways are essentially the same.
Just write ng-click before href ..It worked for me
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.5.0" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script>
angular.module("module",[])
.controller("controller",function($scope){
$scope.func =function(){
console.log("d");
}
})</script>
</head>
<body ng-app="module" ng-controller="controller">
<h1>Hello ..</h1>
<a ng-click="func()" href="someplace.html">Take me there</a>
</body>
</html>
I don't think you need to remove "#" from href. Following works with Angularjs 1.2.10
Logout
You can also try this:
<div ng-init="myVar = 'www.thesoftdesign'">
<h1>Tutorials</h1>
<p>Go to <a ng-href="{{myVar}}">{{myVar}}</a> to learn!</p>
</div>
I'll add for you an example that work for me and you can change it as you want.
I add the bellow code inside my controller.
$scope.showNumberFct = function(){
alert("Work!!!!");
}
and for my view page I add the bellow code.
<a href="" ng-model="showNumber" ng-click="showNumberFct()" ng-init="showNumber = false" >Click Me!!!</a>
Did you try redirecting inside the logout function itself? For example, say your logout function is as follows
$scope.logout = function()
{
$scope.userSession = undefined;
window.location = "http://www.yoursite.com/#"
}
Then you can just have
<a ng-click="logout()">Sign out</a>
Please check this
Logout
$scope.logout = function(event)
{
event.preventDefault();
alert("working..");
}
//for dynamic elements - if you want it in ng-repeat do below code
angular.forEach($scope.data, function(value, key) {
//add new value to object
value.new_url = "your url";
});
<div ng-repeat="row in data"><a ng-href="{{ row.url_content }}"></a></div>
This works for me
<a href (click)="logout()">
<i class="icon-power-off"></i>
Logout
</a>
<a href="#">
<span ng-click="logout()"> Sign out </span>
</a>
I did like this and it worked for me.

Call a function defined in parent scope inside ng-repeat

Original question: (please skip to the EDIT)
I am trying to make images of books which I am receiving clickable.
<div ng-app="myApp" ng-controller="myAppCrtl">
<ul ng-repeat="x in browseBooks">
<div id="{{x.bookId}}">
<li>
<p>{{x.name}}</p>
<p>{{x.price}}</p>
<br>
</li>
</div>
</ul>
</div>
Following the solutions provided here doesn't work, and the link to the angularjs site is broken.
I know the function logout works perfectly, as with button it is executing.
The problem with <a> tag I am unable to make the image trigger a desired function.
EDIT
I understand what my problem is, ng-repeat creates a child scope for each item in the loop. So trying to access the logout() method defined in parent scope is not working. ?
Any idea? even replacing "logout()" with $parent.logout() isn't working...
EDIT2
It is working, however all changes are local to inner scope...
You need quotes around logout()
and then you could use javascript:void(0) if needed and # doesn't work for you
<img style="max-width:100px;" ng-src="{{x.img}}">
Have you tried:
<li ng-click="logout()">
<img style="max-width:100px;" ng-src="{{x.img}}">
<p>{{x.name}}</p>
<p>{{x.price}}</p>
<br>
</li>

Angularjs Expression

I am trying to display the html tags from the data in the view.I have a data level which is $scope.level="<b>i should be bold</b>" and when the data is given in the template as given below should respect the html tag as well
<div ng-controller="MyCtrl" >
{{level}}
</div>
that is it should be bold without using
<div ng-controller="MyCtrl" id="tableForVxp" class="dataDisplay2">
<b>{{level}}</b>
</div>
But with what i have tried so far i am not able to achive it.It is also showing the tag in the view.The issue is illustrated in this JSFiddle Here.
Is there anyway to achieve it.or am i totally wrong here?
You can use the ngBindHtml directive which evaluates the expression and inserts the resulting HTML into the element. Don't forget to include the ngSanitize directive.
https://docs.angularjs.org/api/ng/directive/ngBindHtml
Example :
app.js
angular.module('app', ['ngSanitize'])
.controller('Controller', function($scope) {
$scope.data = '<b>my text</b>'
});
index.html
<div ng-controller="Controller">
<p ng-bind-html="data"></p>
</div>
You can use ng-bind-html-unsafe:
<div ng-controller="MyCtrl" id="tableForVxp" class="dataDisplay2">
<div ng-bind-html-unsafe="level"></div>
</div>
Unsafe because the DOM should generally not be modified inside a controller.
Why can't you move the <b> tags to the markup and then just interpolate the value of 'level'?
http://jsfiddle.net/u37xtpjd/2/
You can accomplish this using the ng-bind-html directive:
<div ng-controller="MyCtrl" id="tableForVxp" class="dataDisplay2">
<span ng-bind-html="level"></span>
</div>

Angular js tabs content HTML tags not rendering

I have one angularjs application. In that application if we click button we are displaying some content which have tabs. By clicking each tab corresponding data will be fetch and need to display there. So data i am getting dynamically. But problem is in below example, i have HTMl tags in content(EX:- "address":"<b>NewYork</b>"). But when i click address tab, it is displaying like <b>NewYork</b>,instead i need NewYork Kindly suggest me
$scope.tabs = [
{ title:'id', content:data[0].id, active:true },
{ title:'name', content:data[0].name,active:false},
{ title:'address', content:$sce.trustAsHtml(data[0].address),active:false},
{ title:'pin', content:data[0].pin,active:false}
];
<ul class="nav nav-tabs">
<li ng-repeat="tab in tabs" ng-class="{active: tab.active}" >
{{tab.title}}
</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in" ng-repeat="tab in tabs" ng-class="{active: tab.active}" style="width:100%">
{{tab.content}}
</div>
</div>
You can solve this by using to_trusted filter
and add filter in your js side
angular.module("app", [])
.controller("ctrl", function ($scope) {
//some code
}).filter('to_trusted', ['$sce', function ($sce) {
return function(text) {
return $sce.trustAsHtml(text);
};
}]);
By default angular sanitizes your values to display any HTML tags as text, for obvious security reasons. If you want to include HTML from your objects in your templates, you can use the ng-bind-html="yourvalue" directive on your HTML elements, ie:
<span ng-bind-html="yourvalue"></span>
Or specifically for your case:
Keep in mind though that this isn't really a best practice in angular (tempting though it is, I've used it too often myself already). It all depends on your particular situation of course, but in general you might want to include this kind of markup in your template and/or include some property in your model with some significance and adjust your display based on that. For example, if city.isFavourite is true, you could conditionally add a favourite CSS class to it in your template.
To wrap it up, this page goes into some safety considerations when using HTML verbatim in your template: AngularJS API for $sanitize
Thank you so much guys. It is working fine now. I kept like below.
<div ng-bind-html="tab.content"></div>