Angular js tabs content HTML tags not rendering - html

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>

Related

Changing html language on click

I am new to HTML and I try to figure out how to change the website language once a button is clicked.
For example, I created a website with 2 flags (US, ES) and I had like the whole page to change the language once the flag is clicked.
However, I'm not sure how to do it since it seems to me like all of the text I used is static but I'm not sure how to do it otherwise.
For example, my code looks like this:
<header id="header" class="row">
<nav id="header-nav-wrap">
<ul class="header-main-nav">
<li class="current"><a class="smoothscroll" href="#home" title="home">Home</a></li>
<li><a class="smoothscroll" href="#about" title="about">About</a></li>
<li><a class="smoothscroll" href="#download" title="download">Download</a></li>
</ul>
</nav>
<img class="esp" href="#esp" src="https://www.countryflags.io/es/shiny/64.png" height="30" width="30" onclick="document.body.className='es'">
<img class="english" href="#english" src="https://www.countryflags.io/us/shiny/64.png" height="30" width="30" onclick="document.body.className='en'">
<a class="header-menu-toggle" href="#"><span>Menu</span></a>
</header> <!-- /header -->
Now here the Home/About/Download are static strings from my understanding. How can I change them once clicked?
Thank you
Handling Internationalization is not a small task. There are many pieces that you need to prepare before you can properly supply language specific page content.
That being said, the lang global attribute defines the language of an element. Adding this step to the work done in your click event would be a good idea. Using Element.setAttribute() you can update the lang attribute on the <body> and update nav link text with Node.textContent every time the locale flags are pressed.
Note: The default value of lang is unknown, therefore it is recommended to always specify this attribute with the appropriate value.
There are a few ways you could go about doing this. I see your adding the locale as a class to the <body> inside the inline onclick event, if you wanted to change the nav link text based on the body having a class of "en" or "esp" you could do that. Or you could attach event listeners to each of the <img> elements and then update the nav link text and lang depending on which locale flag is clicked. You will need to swap the current text with a locale specific type on each click event, so I added some demo data to represent the en-US and es content.
Now here the Home/About/Download are static strings from my understanding. How can I change them once clicked?
The text content of each <a> element in your list of nav links is indeed static text, but when a click event is triggered from the <img> flag being pressed, we can dynamically update the textContent for those <a> nodes on the DOM using Node.textContent and reassign its value like Node.textContent = "".
const espFlag = document.querySelector(".esp");
const engFlag = document.querySelector(".english");
const navLinks = document.querySelectorAll(".smoothscroll");
const body = document.querySelector("body");
const espLocaleLinks = ["One", "Two", "Three"];
const engLocaleLinks = ["Home", "About", "Download"];
espFlag.addEventListener("click", () => {
body.setAttribute("lang", "es");
body.className = 'es';
navLinks.forEach((link, index) => link.textContent = espLocaleLinks[index]);
console.log(body);
});
engFlag.addEventListener("click", () => {
body.setAttribute("lang", "en-US");
body.className = 'en';
navLinks.forEach((link, index) => link.textContent = engLocaleLinks[index]);
console.log(body);
});
<header id="header" class="row">
<nav id="header-nav-wrap">
<ul class="header-main-nav">
<li class="current"><a class="smoothscroll" href="#home" title="home">Home</a></li>
<li><a class="smoothscroll" href="#about" title="about">About</a></li>
<li><a class="smoothscroll" href="#download" title="download">Download</a></li>
</ul>
</nav>
<img class="esp" href="#esp" src="https://www.countryflags.io/es/shiny/64.png" height="30" width="30">
<img class="english" href="#english" src="https://www.countryflags.io/us/shiny/64.png" height="30" width="30">
<a class="header-menu-toggle" href="#"><span>Menu</span></a>
</header> <!-- /header -->
There is no simple way to do this with pure HTML and CSS. It is possible to use JavaScript, but you would still need to request the translated content from some database, JSON file or similar and figure out how to hardcode it in the right places.
It would be better for you to use a content management system (e.g. WordPress) or a static website generator (e.g. Gatsby) to automate these procedures.
Or just use Google Translate to do this automatically for you (be aware of possible translation errors).
You would require some backend to achieve that. Internalization and localization with Django, learn more here
If you had no other option for some reason, you could create a copy of the site for each language you want to support, place them under their own subdirectories, and have each flag link to the corresponding language:
site/
+ en-US/
- index.html
- about.html
+ fr-FR/
- index.html
- about.html
But this is not something you would generally accomplish with HTML alone.
What follows requires quite a bit of additional infrastructure and knowledge; too much to cover thoroughly here, but just to give you a sense of it:
A common approach to this is to use a web templating language to render the page with localized strings pulled from an external datasource.
If your template looks like this:
{{home}}
{{email}}
And you have locale data like this:
{
"en-US": {
"home": "Home",
"email": "Email"
},
"fr-FR": {
"home": "Domicile",
"email": "Messagerie électronique"
},
}
Then you can get a page in a different language by passing the appropriate data to the template:
res.render(template, localeData['en-US']);
If the user changes languages you render with different data:
res.render(template, localeData['fr-FR']);
The question then becomes how do you know what language your visitor wants? And again, there are lots of options available. For example, you could set a cookie to track their language preference. Or you could use a static site generator to pre-render all the pages in all the available languages and use the directory structure linking approach described above. (The latter approach has the benefit of being very easy to deploy, requiring minimal server resources, etc.)
Good luck.

What are some ways to inject a large amount of HTML into a <div>?

I'm pretty new to web design, and I'm trying to build a dashboard for a project. So far, I've got my UI looking like I want it to. It basically consists of a header bar, with a navigation bar on the left side with some options that the user can click on. I want a click on each item to change the content in the central area. The way I thought of was simply to use:
document.getElementById("central text element").innerHTML = "the HTML I want to change it to";
This approach, functionally, does everything I would like. The only problem is, the content I would like to insert is not short. For each of my options, I basically have to create individual HTML documents that I could edit the content in, then run it through a converter like this: https://tomeko.net/online_tools/cpp_text_escape.php?lang=en, then copy it in. As you can probably understand, this method is not very streamlined, as every time I want to make some changes to the code, I have to copy that chunk of code into this converter then paste it into the JavaScript function.
Is there a better way to achieve what I'm trying to do here?
There are several ways to do this:
The <template> element
If you want all the content to be loaded in the page, you can use <template>.
const content1 = document.getElementById("content1").content,
content2 = document.getElementById("content2").content,
div = document.getElementById("div");
function changeContent(content) {
const nodes = [...div.childNodes];
for (let node of nodes) {
node.remove();
}
div.appendChild(content.cloneNode(true));
}
document.getElementById("add-content1-btn").addEventListener("click", () => {
changeContent(content1);
});
document.getElementById("add-content2-btn").addEventListener("click", () => {
changeContent(content2);
});
#div {
border: 1px solid black
}
<template id="content1">
<p>
This is some HTML content. It won't be rendered unless you use JavaScript.
It supports <strong>markup</strong>, of course.
</p>
</template>
<template id="content2">
<p>
This is another HTML content.
</p>
<ul>
<li>Yes,</li>
<li>it</li>
<li>supports</li>
<li>lists.</li>
</ul>
</template>
<button id="add-content1-btn">Add content1 to div</button> <button id="add-content2-btn">Add content2 to div</button>
<div id="div"></div>
Loading pages with <iframe>
You can use <iframe> to load another page inside a page. This is a great approach if the content is really big, because the main page won't need to load that content unless requested. You can change the src attribute of the <iframe> dynamically to load different pages. Note that the page you load needs to be a full page, with its own CSS and all.
<iframe src="https://example.com/">

How to hide a component menu in Angular

I developing a login page and i wouldn't like to show my menu in this page. Currently im calling the component menu in app-component. I would like to know what is the best practice to hide it.
<app-toolbar></app-toolbar>
<div class="row d-flex justify-content-center">
<div class="col-md-8">
<router-outlet></router-outlet>
</div>
</div>
Thanks!
For me, I simply did an *ngIf on my menu bar element. The ngIf referenced a function that would check if the user was logged in or not.
getLoggedInStatus() {
if (localStorage.getItem('userToken') != null) {
return true;
}
else {
return false
}
}
You can see I'm checking local storage for a token that is set on login
<div class="col hide-on-med-and-down l2 no-padding" *ngIf="getLoggedInStatus()">
And there is the menu element wrapper with the if statement. Should be said that I don't know if this is best practice, but I was new when writing my app and by the time I got to login/authentication I was WAY too far down the rabbit hole to re-write things
The best way to hide/show any element in Angular is to use the *ngIf directive. Do note that the component/element will bee hidden/shown based on a condition which you will have to provide.

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

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

Angular.js template to plain html

I want to know if it is possible to compile a Angular.js template to plain html. for example.
//script.js
function TestCtrl($scope) {
$scope.browsers = ['chrome', 'firefox', 'ie'];
}
// template.html
<div ng-app>
<ul>
<li ng-repeat="browser in browsers">{{browser}}</li>
</ul>
</div>
To:
<div>
<ul>
<li>chrome</>
<li>firefox</>
<li>ie</>
</ul>
</div>
There are some way to perform this converssion or some CLI tool for this?
I tried with $compile but the result is not what I want. For Example
...
var compiled = $compile('<ul><li ng-repeat="browser in browsers">{{browser}}</li></ul>');
var el = compiled($scope);
console.log(el.html())
...
The result is a HTML comment
In Chrome, view the page and open the developer tools. In the elements tab, right click <html> and click copy as HTML. This copies the HTML for what is currently on screen. You can also copy the HTML for individual components by right clicking them and selecting copy as HTML.