1

Ok-edited to add code.

I cannot get javascript functions to bind to element in an html page that is an angular include.

This works:

<button id="toggleMessage">Click Me</button>

<script src="/Scripts/jquery-2.1.0.min.js"></script>
<script type="text/javascript">
    var myapp = angular.module('myapp', []);

    var globalFunctions = function () {
        var init = function () {
            toggleMenuLeft();
        };

        var toggleMenuLeft = function () {
            $('#toggleMessage').bind('click', function (e) {
                alert("Hello");
            });
        };

        return {
            init: init,
        };
    }();

    //Load global functions
    $(document).ready(function () {
        globalFunctions.init();

    });
</script>

Once I move that button into an include it no longer works. I tried changing .click to .on but still doesn't work:

#ParentPage.html

<body ng-app="myapp">
    <div ng-include="'/IncludePage.html'"></div>

    <script src="/Scripts/jquery-2.1.0.min.js"></script>
    <script src="/Scripts/angular.js"></script>
    <script type="text/javascript">
        var myapp = angular.module('myapp', []);

        var globalFunctions = function () {
            var init = function () {
                toggleMenuLeft();
            };

            var toggleMenuLeft = function () {
                $('#toggleMessage').bind('click', function (e) {
                    alert("Hello");
                });
            };

            return {
                init: init,
            };
        }();

        //Load global functions
        $(document).ready(function () {
            globalFunctions.init();
        });
    </script>
</body>

#IncludePage.html
<button id="toggleMessage">Click Me</button>

The real code, called from a topnav include which looks for a #toggle-left on a leftnav include. https://gist.github.com/anonymous/11084106

#RealCode - For Matt

var toggleMenuLeft = function () {
        $(document).on('click', '#toggle-left', function (e) {
            if (!$('.sidebarRight').hasClass('.sidebar-toggle-right')) {
                $('.sidebarRight').removeClass('sidebar-toggle-right');
                $('.main-content-wrapper').removeClass('main-content-toggle-right');
            }
            $('.sidebar').toggleClass('sidebar-toggle');
            $('.main-content-wrapper').toggleClass('main-content-toggle-left');
            e.stopPropagation();
        });
    };
4
  • It is difficult to guess what might be wrong without seeing the code. Commented Apr 19, 2014 at 10:38
  • 1
    I guess #toggle-left doesn't exist when the code runs. You have to bind after the view has been loaded. Commented Apr 19, 2014 at 10:43
  • 1
    Have you tried using .on() instead of .bind()? Commented Apr 19, 2014 at 10:51
  • OK going to add code now to make it easier to understand Commented Apr 19, 2014 at 10:56

2 Answers 2

1

Mixing jQuery with AngularJs seems like the easy way but will result in trouble down the road. Ideally you should place this logic inside of a controller or a directive.

Via Controller

#IncludePage.html
<div ng-controller="PageCtrl">
    <button id="toggleMessage" ng-click="toggle()">Click Me</button>
</div>

app.controller("PageCtrl", [$scope, function($scope){
    $scope.toggle = function(){
        //do something
    };
}]);

Via directive

#IncludePage.html
<button id="toggleMessage" toggle="">Click Me</button>

app.directive("toggle", function(){
    return {
        restrict: "A",
        link : function(scope, element, atts){
            $(element).bind('click', function (e) {
                alert("Hello");
            });
        }
    }
});
Sign up to request clarification or add additional context in comments.

4 Comments

Wondering if this will work in my app as in reality i have a ParentPage with an include that is a layout and that include has a topnav, sidebar and rightbar and buttons on the topnav, control elements on the left and right includes. This was originally why I was going for something on the parent page that was more global.
It really depends what is the actual logic inside of toggleMessage. If there is any sort of business logic placing that inside of a controller method would be ideal so you can stay inside of the angular world (plus you can test as well). For example say you just use jQuery now you need the jQuery click to invoke an angular function now you need to find the scope and call $apply() Keeping to code inside of angular is easier for development
Adding the real code above. I need to look into this apply and figure out then how to use it, it sounds like. Added a gist link gist.github.com/anonymous/11084106 I'd have to figure out how to incorporate this into my controller then.
Ok in the end your solution was the better one. I slowly moved the global methods into controllers and or directives and set the includes to use the corresponding controllers.
0

Ahh I found this answer: jQuery click events not firing within AngularJS templates which is inline with what Matt said. I just had to put it on the document element instead.

Solution

 var toggleMenuLeft = function () {
                $(document).bind('click', '#toggleMessage', function (e) {
                    alert("Hello");
                });
            };

Comments

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.