2

I have an AngularJS directive, which needs to be appended after an HTML element which called it. The elements structure can have many nested buttons on different levels of DOM structure.

Right now a directive gets appended in the wrong place instead of a container element that contains the button, which called the append function.

It looks like this:

enter image description here

The text should be appended after a button, which was clicked.

Directive:

app.directive('recursiveFields', function ($compile, $http) {
    return {
        scope: {
            field: '=field',
            model: '=model'
        },
        restrict: 'E',
        replace: true,
        controller: "httpPostController",
        template: '<div ng-repeat="nestedField in field.nestedFields"><div ng-show="{{!nestedField.isEntity && !nestedField.isEnum}}">' + '<p ng-show={{nestedField.isRequired}}>{{nestedField.name}}*: </p>' + '<p ng-show={{!nestedField.isRequired}}>{{nestedField.name}}: </p>' + '<input type="text" ng-model="model[nestedField.name]" ng-change="getCreateEntityAsText()"' + 'class="form-control" placeholder="{{parseClassName(nestedField.type)}}">' + '</div>' + '<div ng-show="{{nestedField.isEnum}}">' + '<p ng-show={{nestedField.isRequired}}>{{nestedField.name}}*: </p>' + '<p ng-show={{!nestedField.isRequired}}>{{nestedField.name}}: </p>' + '<select ng-model="model[nestedField.name]" ng-change="getCreateEntityAsText()" class="form-control">' + '<option></option>' + '<option ng-repeat="enumValue in nestedField.enumValues" label={{enumValue.name}}>{{enumValue.ordinal}}</option>' + '</select>' + '</div>' +

        '<div ng-show="{{nestedField.restResourceName != null}}">' + '<accordion close-others="oneAtATime">' + '<accordion-group heading={{nestedField.name}} is-open="false">' + /*'<recursive-fields model="createEntityResource" field="field"></recursive-fields>'*/
        '<button type="button" ng-click="appendDirective()">I should append a "recursiveFields" directive</button>' + '</accordion-group>' + '</accordion>' + '</div>' + '</div>',

        link: function (scope, element, attrs) {
            console.log("1");
            if (scope.field.restResourceName != null) {
                $http.get(CONSTANTS.EXPLAIN_URL + "/" + scope.field.restResourceName)
                .success(function (data, status) {
                    scope.field.nestedFields = [];
                    data.content.resource.fields.forEach(function (field) {
                        if (field.isEnum) {
                            $http.get(CONSTANTS.ENUMS_URL + scope.$root.parseClassName(field.type)).success(function (data, status) {
                                field.enumValues = [];
                                for (var index in data.content.values) {
                                    field.enumValues.push(data.content.values[index]);
                                }
                            })
                        }
                        scope.field.nestedFields.push(field);
                    })
                })
            }

            scope.appendDirective = function () {
                var recursiveFields = $("<p>Insert me</p>");
                recursiveFields.insertAfter(element[0]);
                $compile(recursiveFields)(scope);
            }
        }
    }
})

Does anyone know how to solve this issue with Angular? Every useful answer is highly appreciated and evaluated.

Thank you.

1
  • 1
    as a side note: its not good practice to use async call like pyramid in jQuery. Angular has powerful promises that allow you to use chain promise. Commented Apr 22, 2014 at 11:51

1 Answer 1

3

ngClick has access to the $event that can be passed to your method like this:

<button type="button" ng-click="appendDirective($event)"

That event has a property target.

Check this: https://docs.angularjs.org/api/ng/directive/ngClick and this: https://docs.angularjs.org/guide/expression#-event-

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I came up with the same solution.

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.