0

I want to create dynamically an element when I click on a button. Do I have to use ng-click or a directive for that?

Here is a JSFIDDLE of what I'm trying to achieve using jQuery :

HTML:

<button id="myButton">Click Me</button>
<div id="container"></div>

JS:

$("#myButton").on("click", function() {
    $("#container").append('<div class="box"></div>');
});

Also, here is a base JSFIDDLE, of what I have so far, to work on if you want for an angularjs solution.

Warn:

  • Please avoid a solution with a controller using ng-repeat. The code above is a simplified example. The created elements won't be as a list, because I'll attach a drag directive to them.
4
  • you dont have to use ng-click, but you can. Commented Aug 7, 2014 at 13:04
  • I can't visualise how to do that. I'm fairly new at angularjs and still have some problem to know what to use in which case and how to use it. Commented Aug 7, 2014 at 13:05
  • You should research how to properly use directives. You are right that a directive is the correct solution, you just need to follow through and add a link function with a controller and a template. Commented Aug 7, 2014 at 13:17
  • I've read the full documentation on Directives and watched a video on youtube of about an hour on it. Still, it seems to have a lot of possibilities, and I wanted to have some examples to look at in this case. I'll take a deeper look at link property. ;) Commented Aug 7, 2014 at 13:23

2 Answers 2

4

Do I have to use ng-click or a directive for that?

To create new element I would use $compile. Any DOM manipulations I strongly recommend to do in directives only. You can trigger appending process through ng-click directive or to use bind like:

 element.bind("click", function(e){
      // do stuff here
   });

Something like that:

 demo.directive("boxCreator", function($compile){   
      return{
        restrict: 'A',
        link: function(scope , element){        
           element.bind("click", function(e){

            var childNode = $compile('<button ng-click="doStuff()" >new button</button>')(scope)
            element.parent().append(childNode);                   
           });

            scope.doStuff = function(){                   
              // do stuff
            }
        }
    }
   });

Demo Fiddle

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

4 Comments

This is a solid answer - I would only recommend tying a template into this that joins the "click me" button, and the new box getting appended to the container so that you can leverage ng-click instead.
I don't understand this line : var childNode = $compile('<button >new button</button>')(scope)
Is it better do use a directive to bind or a controller would do the trick ? (Just asking for best practice)
@Elfayer the $compile tells to angular that new DOM element is created and will notify angular to run digest cycle on new created element. Take a look on ng-click I added to button template. For sure you can use $compile in controller but its not good practice.
2

http://jsbin.com/cuciyu/2/edit

JS

var app = angular.module('app', []);

app.directive("addDiv", function($compile){   
          return{
            restrict: 'AE',
            link: function(scope , element,attr){        
               element.bind("click", function(e){ 
               var container =   angular.element(document.querySelector("#container"));
               var childNode = $compile('<div class="box">BOX DIV</div>')(container);
               container.append(childNode);

               });
            }
        };
       });

    app.controller('firstCtrl', function($scope){


    });

HTML:

  <body ng-app="app">
  <div ng-controller="firstCtrl">
    <button add-div>Click Me</button>
        <div id="container"></div>
      </div>
</body>

2 Comments

DOM manipulation in the controller is bad practice. It's even worse that you aren't using the $document service. Finally, it doesn't allow him to add more than one box.
@Fourth agree but that is answer for Elfayer question

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.