How can I add code into my directive with transclude and pass in a parameter in AngularJS?

angularjs

Solution

About transclusion, I advise you to take a look to this section of the doc. In your case, you have to:

- ask for transclusion in the directive definition object

- indicate in the template which element will receive the transcluded elements with the ng-transclude directive

That give us this directive:

app.directive('mySelect', function () {
    return {
        restrict: "A",
        transclude: true,
        template: "<div class='select-area'>" +
                    "<span> </span>" +
                    "<div ng-transclude></div>" +
                  "</div>"
    };
});  

About passing a parameter, you have access to the attributes of the directive on the third parameter of the link function:

app.directive('mySelect', function () {
    return {
        restrict: "A",
        transclude: true,
        template: "<div class='select-area'>" +
                    "<span> </span>" +
                    "<div ng-transclude></div>" +
                  "</div>",
        link: function (scope, element, attrs) {

        }
    };
});  

Then, if your parameter is always plain text you can access the value directly:

attrs.mySelectArea      

Otherwise, if your parameter can be in the scope you can use the $parse service to get its value:

$parse(attrs.mySelectArea)(scope)

To display the value in the template, you have to provide it in the scope:

app.directive('mySelect', function () {
    return {
        restrict: "A",
        transclude: true,
        template: "<div class='select-area'>" +
                    "<span> {{ mySelectArea }} </span>" +
                    "<div ng-transclude></div>" +
                  "</div>",
        link: function (scope, element, attrs) {
            scope.mySelectArea = attrs.mySelectArea;
        }
    };

Finally, if you want that your directive template replace the element you can use the replace option (more infos):

app.directive('mySelect', function () {
    return {
        restrict: "A",
        transclude: true,
        replace: true,
        template: "<div class='select-area'>" +
                    "<span> {{ mySelectArea }} </span>" +
                    "<div ng-transclude></div>" +
                  "</div>",
        link: function (scope, element, attrs) {
            scope.mySelectArea = attrs.mySelectArea;
        }
    };

I made a plunker of it.

I strongly advise you to to deep dive into the directive guide and the directive API to have a good sight of what can be done with directives.

Problem

I have code like the following that's used in many places in my application and would like to replace some of this HTML with a directive. I realize there is not so much I can replace as the HTML's are so different: ``` <div class="select-area"> <span>Subject</span> <select data-ng-disabled="option.subjects.length == 0" data-ng-model="option.selectedSubject" data-ng-options="item.id as item.name for item in option.subjects"> </select> </div> <div class="select-area" data-ng-hide="utilityService.isNotNumber(option.selectedTopic)"> <span>Subtopic</span> <select data-ng-model="option.selectedSubtopic" data-ng-options="item.id as item.name for item in option.subtopicsPlus"> </select> </div> ``` I would like to use a directive but I am not really sure how to start. I want to use transclude to replace the inside so I was thinking that my directive call would look something like this: ``` <div class="select-area" my-select-area="Subject"> <select data-ng-disabled="option.subjects.length == 0" data-ng-model="option.selectedSubject" data-ng-options="item.id as item.name for item in option.subjects"> </select> </div> <div class="select-area" data-ng-hide="utilityService.isNotNumber(option.selectedTopic)" my-select-area="Subtopic"> <select data-ng-model="option.selectedSubtopic" data-ng-options="item.id as item.name for item in option.subtopicsPlus"> </select> </div> ``` Here's what I have so far: ``` app.directive('mySelect', function () { return { restrict: "A", template: "<div class='select-area'>" + "<span> </span>" + "</div>", }; }); ``` Can someone show me how I can pass in the parameter that goes inside the span and also how I can add transclude? Update: Based on Bastien's answer There were a couple of small syntax errors but based on Bastien's answer I tried the following: ``` app.directive('mySelect', function () { return { restrict: "A", transclude: true, template: "<div class='select-area'>" + "<span> {{ mySelectArea }} </span>" + "<div ng-transclude></div>" + "</div>", link: function (scope, element, attrs) { scope.mySelectArea = attrs.mySelectArea; } } }); ``` Here's my HTML: ``` <div data-my-select myselectarea="Page type"> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes"></select> </div> ``` Here's the HTML it created: ``` <div data-my-select="" myselectarea="Page type"> <div class="select-area"> <span class="ng-binding"> </span> <div ng-transclude=""> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes" class="ng-scope ng-pristine ng-valid"> <option value="0">Edit Basic</option> <option value="1" selected="selected">Edit Standard</option> <option value="2">Report</option> </select> </div> </div> </div> ``` What I really need is for it to create this: ``` <div class="select-area"> <span>Page Type</span> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes" class="ng-pristine ng-valid"> <option value="0">Edit Basic</option> <option value="1" selected="selected">Edit Standard</option> <option value="2">Report</option> </select> </div> ```

Original source