3

Using this page as a reference, How to add div with a button click in angularJs

I created an angular directive to add a div to my html page on button click. However, when I click the button nothing happens. My end goal is to be able to add many Column divs. Here is my code. There are no other errors in the debugger, seems like I'm not properly binding to the click event.

The data I'm getting back from both calls are arrays of strings,

$scope.dataTypes = {"String", "Boolean", "Integer"}
$scope.generatorTypes = {"StringGenerator", "IntegerGenerator", "BooleanGenerator"}

And the code

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script src="~/Scripts/angular.js"></script>
    <script>
        function GetDataTypes($scope, $http) {
            $scope.selectedDataType = null;
            $scope.dataTypes = [];
            $scope.TemplateName = 'NameTest';
            $scope.ColumnCount = '20';
            $http({
                method: 'GET',
                url: 'http://localhost:60568/source/types'
            }).then(function (result) {
                $scope.dataTypes = result.data.Result;
                console.log($scope.dataTypes);
            });

            $scope.selectedDataTypeChanged = function () {
                $scope.generatorTypes = []
                console.log($scope.selectedDataType);
                $http({
                    method: 'GET',
                    url: 'http://localhost:60568/source/generator?datatype='+$scope.selectedDataType
                }).then(function (result) {
                    $scope.generatorTypes = result.data.Result;
                    console.log($scope.dataTypes);
                });
            }
        }

        var myApp = angular.module("myApp", []);
        myApp.controller("GetDataTypes", GetDataTypes);

        myApp.directive('addColumn', function () {
            return {
                restrict: 'A',
                scope: true,
                template:                
                    '<div id="Column">'+
                        '<hr />'+
                       'Select DataType :-'+
                       '<select ng-model="selectedDataType" ng-change="selectedDataTypeChanged()">'+
                           '<option ng-repeat="dataType in dataTypes">{{ dataType }}</option>'+
                       '</select>'+
                       '<br />'+

                       'Select Generator :-'+
                       '<select ng-model="selectedGenerator">'+
                           '<option ng-repeat="generatorType in generatorTypes">{{generatorType}}</option>'+
                    '</select>'+
                    '</div>',
                controller: function ($scope, $element, $compile) {
                    $scope.clicked = 0;
                    $scope.click = function () {
                        $('body').append($compile($('.Columns').clone())($scope));
                    }
                }
            }
        })
    </script>
</head>

<body ng-app="myApp">
    <div id="TemplateCollection" ng-controller="GetDataTypes">
        <div id="Template">
            TemplateName :- <input ng-model="TemplateName" type="text" id="TemplateName" value="" /><br />
            RowCount :- <input ng-model="RowCount" type="text" id="RowCount" value="" /><br />
            <button addColumn>Add New Column</button>
            <div class="Columns">
                <div id="Column">
                    <hr />
                    Select DataType :-
                    <select ng-model="selectedDataType" ng-change="selectedDataTypeChanged()">
                        <option ng-repeat="dataType in dataTypes">{{ dataType }}</option>
                    </select>
                    <br />

                    Select Generator :-
                    <select ng-model="selectedGenerator">
                        <option ng-repeat="generatorType in generatorTypes">{{generatorType}}</option>
                    </select>
                </div>
            </div>
        </div>
</body>
</html>
2
  • please post data you return with http://localhost:60568/source/types Commented Aug 26, 2017 at 6:07
  • updated @MaximShoustin Commented Aug 26, 2017 at 6:12

1 Answer 1

2

You have several problems here:

  • problem is with button ng-click. You can inspect the element and find that you have:

    <button addcolumn="">Add New Column</button> So ng-click is missed.

  • you cannot add directive as attribute to button with above mentioned logic. It can cause to unexpected behaviors.

  • even after your click will work, your select will duplicate list. In this case jQuery.clone() will not solve it.

  • its not best practice to use jQuery you can use single document.querySelector

I changed directive and click method:

$scope.click = function () {
   var el = angular.element('<add-column></add-column>');
    el = $compile(el)($scope);
    var body = document.querySelector('body');
    angular.element(body).append(el);
 }

The directive call will be <add-column></add-column> and not:

<button addColumn>Add New Column</button>

So you don't need to duplicate your code

Demo


Full direcitve

  myApp.directive('addColumn', function ($compile) {
        return {
            restrict: 'E',
            scope: true,
            template:                
                '<div class="Column">'+
                '<button ng-click="click()">Add New Column</button>'+  
                    '<hr />'+
                   'Select DataType :-'+
                   '<select ng-model="selectedDataType" ng-change="selectedDataTypeChanged()">'+
                       '<option ng-repeat="dataType in dataTypes">{{ dataType }}</option>'+
                   '</select>'+
                   '<br />'+

                   'Select Generator :-'+
                   '<select ng-model="selectedGenerator">'+
                       '<option ng-repeat="generatorType in generatorTypes">{{generatorType}}</option>'+
                '</select>'+
                '</div>',
            link: function ($scope, $element) {
                $scope.clicked = 0;

                $scope.click = function () {
                  var el = angular.element('<add-column></add-column>');
                  el = $compile(el)($scope);
                  var body = document.querySelector('body');
                  angular.element(body).append(el);
                }
            }
        }
    })
Sign up to request clarification or add additional context in comments.

4 Comments

What would I need to change if I only want one "Add New Column" button? I don't want it to be in the same div as the column.
Put button outside directive
Taking button out of directive and putting in before the add-column did not work <button ng-click="click()">Add New Column</button> <add-column></add-column>
@TalenKylon I think this should totally change our code. Do you want something like this? plnkr.co/edit/dKklNRMNvq0J3W5h8Bb7?p=preview

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.