Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

button click not correctly calling my angular directive

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>
like image 284
Talen Kylon Avatar asked Jun 05 '26 13:06

Talen Kylon


1 Answers

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);
                }
            }
        }
    })
like image 181
Maxim Shoustin Avatar answered Jun 07 '26 10:06

Maxim Shoustin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!