1

New to AngularJS - I am trying to create a function that finds "tokens" of specific text, replaces them with an ng-click directive bound to a function on the controller. For example, from my database I have lots of text-fields with something like this:

<p>Your [labor] cost is included in price</p>

Which I would like to end up like this:

<p>Your <a href="#" ng-click="showModal('labor')">labor</a> cost is included in price.</p>

I have no problem replacing the [labor] token with a filter, but I am a bit lost on how to incorporate $compile to bind the ng-click to $scope.showModal() on my controller.

Any help would be appreciated. Thank you.

My existing filter:

myApp.filter('parseHtml', function ($sce) {

    return function (text) {

        var link = '<a href="" ng-click="getModal(\'labor\')">Labor</a>';
        var replaced = text.replace(/\[labor\]/g, link);

        return $sce.trustAsHtml(replaced);
    };
});

In the html

<span ng-bind-html="package.price | parseHtml"></span>

The controller

myApp.controller('MainController',
    function MainController($scope, $http) {

        $scope.getpackage = function (slug) {

            var onpackageComplete = function (response) {
                $scope.package = response.data;
            };
            $http.get('/packages/api/' + slug + '/detail')
                .then(onpackageComplete);
        };

        $scope.getModal = function (name) {

            $scope.modalVisible = true;
            if (name === 'labor') {
                $scope.modalBody = '/path/to/html/snippet/ModalLabor.html';
            } else if (name === '') {
                $scope.modalBody = '';
            }

        };
    }
);
brandondavid
  • 201
  • 1
  • 8
  • See https://stackoverflow.com/questions/42539999/how-to-call-a-function-from-another-function-with-ng-click/42540297#42540297. There is a sample of usage of `$compile` service – lealceldeiro Mar 01 '18 at 16:49
  • If you see that example and still don't know how to do it in your code, share the controller code in your question and we'll help you. Without code is hard to tell – lealceldeiro Mar 01 '18 at 16:53
  • Hi I've been studying that referenced example for quite some time and am still quite lost, so I added some sample code from my project to the original post. thank you – brandondavid Mar 01 '18 at 19:22

1 Answers1

1

Taking as reference the accepted answer provided in Compiling dynamic HTML strings from database, this should do the trick

Change your filter for a directive instead, which takes the content with the token, replace it with the click function and compiles the content, putting in the DOM again. See below demo carefully in order to see how to do it.

angular
  .module('app', [])

  //The new directive! (which replaced the old filter)
  .directive('parseHtml', function($compile) {
    return {
      restrict: 'A',
      replace: true,
      link: function(scope, iElem, attrs) {
        var link = '<a href="" ng-click="getModal(\'labor\')">Labor</a>';

        scope.$watch(attrs.parseHtml, function(text) {
          if (text) {
            var replaced = text.toString().replace(/\[labor\]/g, link);
            iElem.html(replaced);
            $compile(iElem.contents())(scope);
          }
        })
      }
    }
  })

  //sample controller
  .controller('MainController',
    function MainController($scope, $http) {
      var p = 1;
      
      $scope.getpackage = function() {debugger;
        $scope.package = {
          price: "Value is " + p + " hundred - [labor]"
        };
        p = p + 1;
      };

      $scope.getModal = function(name) {
        console.log('getModal clicked!');
        alert('getModal clicked!');
      };
    }
  );
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="MainController">

  <!--mock request-->
  <button ng-click="getpackage()"> Get Package</button> <br /> <br />

  <!-- how to use the directive -->
  <span parse-html="package.price"></span>

</div>

Important: The action in the link is getModal (fixed in the directive). If you need this do be added dynamically too, you need to pass that function as argument to the directive too. That new implementation would require some changes.

lealceldeiro
  • 14,342
  • 6
  • 49
  • 80
  • 1
    thank you very much, this is much easier for me to understand, I can use this to learn more about the compile function. – brandondavid Mar 01 '18 at 20:38