1

Problem: I would like to be able to decode an HTML entity in an Angular expression. Based on what I have read online, I can use Sanitize and ng-bind-html.

However, based on the examples I have seen online (below):

<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-sanitize.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl">

<p ng-bind-html="myText"></p>

</div>

<script>
var app = angular.module("myApp", ['ngSanitize']);
app.controller("myCtrl", function($scope) {
    $scope.myText = "My name is: &John Doe&";
});
</script>

I am not sure how I can apply what I have looked up with the following angular expression:

<div id="searchResults" ng-repeat="e in Data" ng-show="ShowResults">
  <div class="row">
    <div class="col-md-4 no-margin padding">
       <strong>Data:</strong> {{e.Specialty}}
    </div>
 </div>
</div>

Update: I have tried the following and when I display results, the Specialty appears blank and when I debug code, it appears that doing that approach removes it

  <strong>Data:</strong> <span ng-bind-html="e.Specialty"></span>

Here is the angularjs where I am calling the specialty. Where would I include "ngSanitize". However, it crashes everything in the form when I include ngSanitize and not sure why it would

(
function(){
    var $scope, $location;
    var indexApp = angular.module('indexApp',['ui.bootstrap', 'ngSanitize']);

    indexApp.controller('IndexController',function($scope,$http,$location,anchorSmoothScroll){
        $scope.Lang = 'initVal';
        $scope.ShowResults = false;
        $scope.ShowDesc = true;
        $scope.NoResults = false;
        $scope.currentPage = 1;
        $scope.maxPageNumbersToShow = 10;
        $scope.formModel = {};
        $scope.searchMode = 0;
        $scope.miles =  [{'value':'5'},{'value':'10'},{'value':'15'},{'value':'20' }];
        $scope.Specialties = [{'value':'Family practice'},{'value':'General practice'},{'value':'Internal medicine'},{'value':'Pediatrics'}];
        $scope.Gender = [{'value':'Male'},{'value':'Female'}];
        $scope.Languages = {};
        $scope.Cities = {};
        $scope.searchParam = {};
        $("input").removeAttr('disabled');

        $scope.searchParam.Distance = $scope.miles[0];

        $scope.GetCurrentZip = function (){
            try{
                var lon, lat;
                // console.log('starting geoposition code.');
                if("geolocation" in navigator){
                    window.navigator.geolocation.getCurrentPosition(function(pos){
                        lat = pos.coords.latitude.toFixed(3);
                        lon = pos.coords.longitude.toFixed(3);
                        // console.log(lat + ' ' + lon);
                        $http.get("/remote/ReturnCurrentZipcode.cfm?Lat=" + lat + "&Lon=" + lon)
                        .then(function(response){
                            $scope.searchParam.Zip = response.data;
                        })
                    })
                }
                else{ console.log('No geolocation'); }
            }
            catch(err) { console.log(err.message); }
        }

        $scope.GetCityList = function (){
            try{
                $http.get("/remote/ReturnCityList.cfm")
                    .then(function(response){
                        $scope.Cities = response.data.Cities;
                    })
            }
            catch(err){}
        }

        $scope.GetLangList = function (){
            try{
                $http.get("/remote/ReturnLangList.cfm")
                    .then(function(response){
                        $scope.Languages = response.data.Languages;
                    })
            }
            catch(err){}
        }

        $scope.SearchProvider = function(searchParam){
            try{
                $scope.searchMode = 1;
                var queryString='';
                if($scope.formModel && $scope.formModel !== searchParam){
                    $scope.resultsCount = 0;
                    currentPage = 1;
                }
                if(searchParam){
                    $scope.formModel = searchParam;
                    for(var param in searchParam){
                        if(searchParam.hasOwnProperty(param)){
                            var paramValue = searchParam[param].value ? searchParam[param].value.trim() : searchParam[param].trim();
                            if (paramValue.length > 0)
                                queryString += param + '=' + paramValue + '&';
                        }
                    }
                }
                console.log(queryString);
                queryString= '?' + queryString + 'currentpage=' + $scope.currentPage;

                $http.get("/remote/ReturnProvidersList.cfm" + queryString)
                .then(function(response){
                    $scope.providers = response.data.provider;
                    $scope.resultsCount = response.data.rowCount;
                    if (!$scope.providers){
                            $scope.NoResults = true;
                            $scope.ShowResults = false;
                            $scope.ShowDesc = false;
                        }
                    else{
                            $scope.NoResults = false;
                            $scope.ShowResults = true;
                            $scope.ShowDesc = false;
                        }
                })
            }
            catch(err){ alert('No response.: ' + err.message); }
        }

        $scope.$watchGroup(['currentPage'], function(){
            try{
                if($scope.searchMode == 1){
                    $scope.SearchProvider($scope.formModel);
                    }
            }
            catch(err){}
        });


        $scope.GetCityList();
        $scope.GetLangList();
        $scope.GetCurrentZip();

        $scope.gotoElement = function (eID){
            //http://jsfiddle.net/brettdewoody/y65G5/
              // set the location.hash to the id of
              // the element you wish to scroll to.

            //$location.hash('bottom');

              // call $anchorScroll()
            var browserWidth = screen.availWidth;
            if (browserWidth < 768)
                anchorSmoothScroll.scrollTo(eID);
        };

    });

    indexApp.service('anchorSmoothScroll', function(){
        this.scrollTo = function(eID) {

            // This scrolling function 
            // is from http://www.itnewb.com/tutorial/Creating-the-Smooth-Scroll-Effect-with-JavaScript

            var startY = currentYPosition();
            var stopY = elmYPosition(eID);
            var distance = stopY > startY ? stopY - startY : startY - stopY;
            if (distance < 100) {
                scrollTo(0, stopY); return;
            }
            var speed = Math.round(distance / 100);
            if (speed >= 20) speed = 20;
            var step = Math.round(distance / 25);
            var leapY = stopY > startY ? startY + step : startY - step;
            var timer = 0;
            if (stopY > startY) {
                for ( var i=startY; i<stopY; i+=step ) {
                    setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
                    leapY += step; if (leapY > stopY) leapY = stopY; timer++;
                } return;
            }
            for ( var i=startY; i>stopY; i-=step ) {
                setTimeout("window.scrollTo(0, "+leapY+")", timer * speed);
                leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
            }

            function currentYPosition() {
                // Firefox, Chrome, Opera, Safari
                if (self.pageYOffset) return self.pageYOffset;
                // Internet Explorer 6 - standards mode
                if (document.documentElement && document.documentElement.scrollTop)
                    return document.documentElement.scrollTop;
                // Internet Explorer 6, 7 and 8
                if (document.body.scrollTop) return document.body.scrollTop;
                return 0;
            }

            function elmYPosition(eID) {
                var elm = document.getElementById(eID);
                var y = elm.offsetTop;
                var node = elm;
                while (node.offsetParent && node.offsetParent != document.body) {
                    node = node.offsetParent;
                    y += node.offsetTop;
                } return y;
            }

        };

    });

    indexApp.directive('allowPattern',[allowPatternDirective]);
    indexApp.directive('popPopup',[describePopup]);
    indexApp.directive('pop', function pop ($tooltip, $timeout) {
    var tooltip = $tooltip('pop', 'pop', 'event');
    var compile = angular.copy(tooltip.compile);
    tooltip.compile = function (element, attrs) {      
      var first = true;
      attrs.$observe('popShow', function (val) {
        if (JSON.parse(!first || val || false)) {
            $timeout(function(){
                element.triggerHandler('event');
            });
            }
            first = false;
        });
        return compile(element, attrs);
        };
        return tooltip;
    });

    indexApp.filter('PhoneNumber', function(){
    return function(phoneNumber){
        var dash = '-';
        var openParen = '(';
        var closeParen = ') ';
        if(phoneNumber){
            var pn = phoneNumber;
            pn = [pn.slice(0, 6), dash, pn.slice(6)].join('');
            pn = openParen + [pn.slice(0, 3), closeParen, pn.slice(3)].join('');
            return pn;
            }
        return phoneNumber;
        }
    });

    indexApp.filter('Zip', function(){
    return function(zipcode){
        var dash = '-';
        if(zipcode && zipcode.length > 5){
            var zc = zipcode;
            zc = [zc.slice(0, 5), dash, zc.slice(5)].join('');
            return zc;
            }
        return zipcode;
        }
    });

    function allowPatternDirective(){
        return{
            restrict: "A",
            compile: function(tElement, tAttrs){
                return function(scope, element, attrs){
                    element.bind("keypress", function(event){
                        var keyCode = event.which || event.keyCode;
                        var keyCodeChar = String.fromCharCode(keyCode);

                        if(!keyCodeChar.match(new RegExp(attrs.allowPattern, "i"))){
                            event.preventDefault();
                            return false;
                        }
                    });
                }
            }
        }
    }

    function describePopup(){
        return {
            restrict: 'EA',
            replace: true,
            scope: { title: '@', content: '@', placement: '@', animation: '&', isOpen: '&' },
            templateUrl: 'template/popover/popover.html'
            };
        }
})();
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Robert
  • 167
  • 1
  • 2
  • 14
  • Could you please clearify what you want to do? – wrager Sep 08 '17 at 16:19
  • In your [dupe question](https://stackoverflow.com/questions/46105570/how-to-get-rid-of-amp), you said you tried this and it didn't work. Now, you're saying you don't know how to try it. –  Sep 08 '17 at 16:20
  • @wrager: What I am trying to do is change any html entity ("&", "*", etc) and display those characters rather then the entity name. – Robert Sep 08 '17 at 16:28

1 Answers1

0

Here is a fiddle demonstrating how to use it, please apply it to your use case.

JSFiddle Demo

<div ng-controller='MyController' ng-app="myApp">
<div id="searchResults" ng-repeat="e in Data" ng-show="ShowResults">
  <div class="row">
    <div class="col-md-4 no-margin padding">
       <strong>Data:</strong> <span ng-bind-html="e.Speciality"></span>
    </div>
 </div>
</div>

</div>
Naren Murali
  • 19,250
  • 3
  • 27
  • 54
  • I have tried that approach. However, when I try to see the results, the name of the specialty does not appear – Robert Sep 08 '17 at 16:27
  • @Robert Share a sample of the data, where its failing, you can use the `JSFiddle` link I provided! – Naren Murali Sep 08 '17 at 16:30
  • @ Naren: I am using a CMS (Mura) and it appears to not like it when I attempted to wrap angular expression in a span and tried a div as well and displays no results – Robert Sep 08 '17 at 16:33
  • @Robert I guess you will be using PHP, so if you use the function `htmlentities()` in php, it will encode for you! Refer [here](https://www.w3schools.com/php/func_string_htmlentities.asp) – Naren Murali Sep 08 '17 at 16:37
  • @ Naren: Thank you but I am not using PHP. I am using angularjs, coldfusion. To use "ng-bind-html", do i need to use the sanitize script?? – Robert Sep 08 '17 at 16:42
  • @Robert Ok, just check this link for reference [here](https://stackoverflow.com/questions/21919533/using-html-entities-within-angular-strings) – Naren Murali Sep 08 '17 at 16:45
  • 1
    @ Naren: I have tried those approach and has not worked for me. I understand how your fiddle works. However, I am not sure why it is removed on my end – Robert Sep 08 '17 at 16:47
  • @ Naren: When I try your approach, it crashes. So, the database, there are characters like "&" and so on. So when I enter those type of characters, it crashes – Robert Sep 08 '17 at 17:54
  • @Robert can you give me a sample string? I tried my example with special characters there was no issue – Naren Murali Sep 08 '17 at 17:56
  • Example: Camp & Stuff. When I enter that, it wont render the results. It will actually show Camp & Stuff – Robert Sep 08 '17 at 18:04
  • @Robert One doubt, you are receiving the data properly right from the server? then why are you not rendering using the original code `{{e.Specialty}}` why use ng-bind-html, seems unnecessary! – Naren Murali Sep 08 '17 at 18:32
  • @ Naren: Yes you are correct from the server. However, it is rendering the ampersand character as '&' when using the original code. In the database, I thought & was '&' but it is inputted as &. – Robert Sep 08 '17 at 18:38
  • @ Naren: That is why I am trying a approach to decode the html entity when displayed – Robert Sep 08 '17 at 18:49
  • @Robert Either of the two suggestions I gave else, I dont know, maybe check the console, its possible, you are not implementing `ng-sanitize` properly – Naren Murali Sep 08 '17 at 19:16
  • @ Naren: Check the header tag and the js and it looks correct to me – Robert Sep 08 '17 at 19:26