3

Let's say have have a simple template for a directive like this:

<section class="card {{width}} recipe-list-card">
  <div class="card-top">
    <h3>{{headerText}}</h3>
  </div>
  <div class="card-bottom">
    <div ng-transclude></div>
  </div>
</section>

In some cases I'd like to use an h2 and in others and h3. Is there a good way to change the element with a directive?

Here's what I have in my directive:

module.exports = function(app) {

      app.directive('cardDirective', function() {
        return {
          restrict: 'AC',
          replace: true,
          transclude: true,
          templateUrl: '/templates/card_template.html',
          scope: {
            header: '=',
            headerText: '@',
            width: '@' //two columns, three columns, etc
          }
        }
      })
    }

I'd like to assign the header variable to h2, h3 etc. So far I've only been able to get escaped html (the actual tag rendered out like <h2> in the browser).

2
  • 1
    where do you want to use the tags? Commented Dec 12, 2015 at 2:24
  • Where it says <h3>{{headerText}}<h3> I'd like to somehow be able to change it to an h2 if I can. Commented Dec 12, 2015 at 2:25

4 Answers 4

3

You can create a directive for your heading tag, like this:

angular.module('myApp')
    .directive('myHeading', myHeading);

function myHeading() {
    return {
        transclude: true,
        template: function(tElement, tAttrs) {
            var level = Number(tAttrs.level);
            if (level < 1 || level > 6) level = 1; // default
            return '<h' + level + '><ng-transclude></ng-transclude></h' + level + '>';
        }
    };
}

Then you could use it in your template like this:

<my-heading level="2">{{headerText}}</my-heading>
Sign up to request clarification or add additional context in comments.

2 Comments

This is great unless you need to parse the level attribute - is there any way around this that you know of? I'm trying to create a nested structure with each child having a higher level header, so my attributes look like this: level="{{level+1}}" But of course, tAttrs.level now gives the literal string "{{level+1}}" and I don't have the parent scope to parse it with.
@AlfieWoodland I would use the accepted answer. In hindsight, this answer was pretty bad because it does not support evaluating dynamic values.
2

You can do it by following the code as follows

Change HTML as follows:

<section class="card {{width}} recipe-list-card">
  <div class="card-top">
    <h3 ng-show="h3">{{headerText}}</h3>
    <h2 ng-show="h2">{{headerText}}</h2>
  </div>
  <div ng-click="updateh2h3()">Check h2h3 changes</div>
  <div class="card-bottom">
    <div ng-transclude></div>
  </div>
</section>

And modify controller as follows: module.exports = function(app) {

  app.directive('cardDirective', function() {
    return {
      restrict: 'AC',
      replace: true,
      transclude: true,
      templateUrl: '/templates/card_template.html',
      scope: {
        header: '=',
        headerText: '@',
        width: '@' //two columns, three columns, etc
      },
      controller: function($scope) {
       $scope.h2 = false;
       $scope.h3 = true;
       $scope.updateh2h3 = function(){
        if($scope.h2){
         $scope.h2 = false;
         $scope.h3 = true;
        } else {
         $scope.h2 = true;
         $scope.h3 = false;
        }
       }
      }
    }
  })
}

Comments

1

You can simply add an attribute to the directive and use ng-switch to setup the header you need for your card. take a look this demo i've done.

<div class="card">
  <div class="card--Title" ng-switch on="headline">
      <h1 ng-switch-when="h1">{{::headerText}}</h1>
      <h2 ng-switch-when="h2">{{::headerText}}</h2>
      <span ng-switch-default>{{::headerText}}</span>
  </div>
</div>

http://embed.plnkr.co/simYTj/

1 Comment

I went with this answer since it seemed the simplest and easiest to implement in my particular case.
1

I think you are looking at this issue the wrong way. Instead of switching tags around, you can just define two classes for h2 and h3, and then you can use ng-class to switch between. Dynamically compiling tags and manipulating dom for this is very expensive operation.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.