6

Hi I couldn't find a working solution properly. Please help me out.

I have a single page application with ui-selects in the page, basically it is for a directory listing. The user will select folders and finally when he/she selects a HTML file in the list, I am generating a url and I have to display the html file in my spa. I was able to display text files, but I don't know how to display html files. I tried ng-bind-html, but don't know how to display that.

I am getting the content of the html using $http.get method and storing the html content in a variable called "contentHTML" I need to display that

clearScreen
  • 1,002
  • 4
  • 15
  • 31

4 Answers4

3

I think you're looking for ngInclude.
You don't even need to handle the AJAX request, it's done for you.

Fetches, compiles and includes an external HTML fragment.

Usage

<ANY
  ng-include="path_of_your_file.html"
  [onload="string"]
  [autoscroll="string"]>
  ...
</ANY>

Important things to note:

  • Your HTML file needs to be on the same domain or it gets complicated (see docs)
  • This is a template, which means:
    • All relative paths will be relative to the current path, not to the imported template's path
    • Angular in it will be evaluated
Jerska
  • 11,722
  • 4
  • 35
  • 54
3

Your issue is with angular sanitization. It will not let you use ng-bind-html until you stick your HTML content in a special variable that is marked as trusted HTML. Angular makes you do this so that you know that you are very explicitly telling Angular it's okay to render this markup.

It helps protect the average developer from accidentally rendering user input unencoded, which would be very dangerous. You wouldn't want users submitting javascript in input fields and then having your app render that script right into the page somewhere. If it did, the malicious script would run when rendered and could cause all sorts of havoc.

You need to include the ngSanitize module in your app's dependencies.

var app = angular.module('myApp', ['ngSanitize']);

Don't forget to include the angular-sanitize lib in your script references.

<script src="//ajax.googleapis.com/ajax/libs/angularjs/X.Y.Z/angular-sanitize.js"></script>

Then you need to mark your HTML content as safe to render using the $sce service.

app.controller('myController', function ($scope, $sce) {
  $scope.trustedHtml = $sce.trustAsHtml(contentHTML);
});

Only then will ng-bind-html work.

<div ng-bind-html="trustedHtml"></div>

Demo: http://codepen.io/Chevex/pen/xGYydr?editors=101

CatDadCode
  • 58,507
  • 61
  • 212
  • 318
  • Hi, thanks for the detailed answer, it is working, but only the text elements of the html are shown, there are graphs, charts and tables in the html file, they are not getting displayed – clearScreen Jul 03 '15 at 06:13
  • Think you could duplicate that in a [codepen](http://codepen.io) so I can take a look? – CatDadCode Jul 03 '15 at 06:21
  • the html I'm trying to display is in the local intranet, ill try to create a html and then duplicate that in a codepen.... through ng-bind-html, is it necessary that the html page be static? – clearScreen Jul 03 '15 at 06:26
  • The HTML would just be inserted into the DOM wherever you put `ng-bind-html`. If there are ` – CatDadCode Jul 03 '15 at 06:28
  • http://codepen.io/anon/pen/aOqRGL .... i have included the html file i need to display – clearScreen Jul 03 '15 at 06:47
  • Okay. I stepped out for a moment but when I get back I'll definitely take a look. At first glance I'm glad to see the charts rendering so I can plug it into angular and see if I get the same issue as you :) – CatDadCode Jul 03 '15 at 07:01
  • 1
    Oh... I didn't realize this was an entire HTML page. Well that's why. You're trying to render a full HTML page inside another HTML page. That file should only contain the contents of the body tag. You can move your script and style tags into the body content. I had assumed you were pulling down a chunk of HTML but not a full document since you were trying to show it on the page with angular. – CatDadCode Jul 03 '15 at 07:27
  • Make the HTML document you're pulling down, look like this instead: http://codepen.io/Chevex/pen/KpQGJM – CatDadCode Jul 03 '15 at 07:31
  • oh, thanks for looking at it..... I am getting the source of the html from $http.get request, how do I modify it, I mean how do I remove head and body tags? – clearScreen Jul 03 '15 at 07:36
  • Oh, and put the script tags *below* the charts, tables, and graphs. The DOM is parsed in order so you want the scripts to run after those elements have loaded. – CatDadCode Jul 03 '15 at 07:37
  • 1
    Check out [this answer](http://stackoverflow.com/a/6195639/498624) to see how they use Jquery to pull out the body contents. Angular uses jquery behind the scenes. You can substitute `anguler.element` for all the `$` calls. For convenience you can do `var $ = angular.element;`. You can also use it to move the script tags to the bottom. `$('script').append('body');`. That would move all script tags to the bottom of the body. – CatDadCode Jul 03 '15 at 07:39
2

To display your html from contentHtml you need to have a div on your html page like:

<div ng-controller="htmlBucket">
    {{content}}
</div>

Then in your javascript you should have this

app.registerCtrl('htmlBucket', function($scope)
{
   $scope.content =  $sce.trustAsHtml(contentHTML); 
});

Don't forget include your .js, jquery and angular dependencies to your HTML

<script src="lib/jquery/jquery.js"></script>
<script src="lib/angular/angular.js"></script>

Hope it helps.

Sapikelio
  • 2,594
  • 2
  • 16
  • 40
  • 1
    This will render the markup encoded. Meaning it will turn the string `"

    hi

    "` into `"<h1>hi</h1>"` when it renders the bound variable.
    – CatDadCode Jul 03 '15 at 06:09
  • 2
    Yep, that's what happens you stick `<h1>hi</h1>` into a web page, it will render the source as page content to be displayed. i.e. you would literally see `

    hi

    ` displayed on the page as plain text. [Demo](http://codepen.io/Chevex/pen/YXeJxv)
    – CatDadCode Jul 03 '15 at 06:23
  • To display the content as Html try with this: $scope.content = $sce.trustAsHtml(contentHTML); – Sapikelio Jul 03 '15 at 06:28
  • @carlos to do that you'll first need to include `ngSanitize` as an app dependency. My answer goes into detail about the `$sce` service :) – CatDadCode Jul 03 '15 at 06:31
  • i tried $sce.trustAsHtml ... only text elements are being displayed.... there are graphs, charts and tables, these elements are not getting displayed – clearScreen Jul 03 '15 at 06:31
  • 1
    @swordfish12 My guess is that your graphs, charts and tables need some javascript or CSS to run that isn't loading/running properly. Just a guess. I'll know more once you have the codepen up. – CatDadCode Jul 03 '15 at 06:32
  • oh, ill check that first – clearScreen Jul 03 '15 at 06:32
1

You can achieve what you are looking for using ui-router. Here is the link for the same.

using ui-select once user select the folders. write a event trigger in your controller to change the url to your predefined one. using $stateProvider. you can also see their example for the same here

Hope that helps

raj
  • 694
  • 1
  • 5
  • 22