0

I have a menu for the website written in HTML, and, rather than include all of it on each page individually (such that I would have to edit each page to change something), I'm including the HTML through the use of Angular (<div ng-include="menu.html"></div>).

I have some Javascript (external .js file) that I need to run on the included HTML in order to animate the navigation menu. If I actually include the HTML on the page, it works fine. It's only when I make the HTML external (through angular's ng-include) that it doesn't.

I think this may be an issue with it not being targeted correctly? I really don't know enough javascript to solve this myself.

I'm also using Pure CSS so that's what most of the classes are in the included HTML.

HTML Page:

<body ng-app="">
    <div ng-include="header.html"></div>
    *rest of the page*
</body>

Included HTML:

//Header for the page
<div id="topbar" class="pure-g">
    <div class="pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5"> </div>
    <div class="pure-u-22-24 pure-u-sm-20-24 pure-u-md-16-24 pure-u-lg-3-5">
        <h1>Title</h1>
    </div>
    <div class="pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5"> </div>
</div>

//Navigation menu
<div id="menu" class="custom-wrapper pure-g">

    //column 1
    <div class="pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5"> </div>

    //column 2
    <div class="pure-u-22-24 pure-u-sm-20-24 pure-u-md-16-24 pure-u-lg-3-5 ">
        //makes another row 
        <div class="pure-g">

            //column 1
            <div class="pure-u-1 pure-u-md-1-3" style="height: 2.1em">
                <div class="pure-menu"> <a href="#" class="pure-menu-heading custom-brand" id="navTitle">Navigation</a> <a href="#" class="custom-toggle" id="toggle"><s class="bar"></s><s class="bar"></s></a> </div>
            </div>

            //column 2
            <div class="pure-u-1 pure-u-md-1-3">
                <div class="pure-menu pure-menu-horizontal custom-can-transform">
                    <ul class="pure-menu-list">
                        <li class="pure-menu-item"><a href="#" class="pure-menu-link">Home</a></li>
                        <li class="pure-menu-item"><a href="#" class="pure-menu-link">About</a></li>
                        <li class="pure-menu-item"><a href="#" class="pure-menu-link">Contact</a></li>
                    </ul>
                </div>
            </div>

            //column 3
            <div class="pure-u-1 pure-u-md-1-3">
                <div class="pure-menu pure-menu-horizontal custom-menu-3 custom-can-transform">
                    <ul class="pure-menu-list">
                        <li class="pure-menu-item"><a href="#" class="pure-menu-link">Yahoo</a></li>
                        <li class="pure-menu-item"><a href="#" class="pure-menu-link">W3C</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

    //column 3
    <div class="pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5"> </div>
</div>

Javascript:

function menuScript() {
(function (window, document) {
    var menu = document.getElementById('menu')
        , WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange' : 'resize';

    function toggleHorizontal() {
    [].forEach.call(document.getElementById('menu').querySelectorAll('.custom-can-transform'), function (el) {
            el.classList.toggle('pure-menu-horizontal');
        });
    };

    function toggleMenu() {
        // set timeout so that the panel has a chance to roll up
        // before the menu switches states
        if (menu.classList.contains('open')) {
            setTimeout(toggleHorizontal, 500);
        }
        else {
            toggleHorizontal();
        }
        menu.classList.toggle('open');
        document.getElementById('toggle').classList.toggle('x');
    };

    function closeMenu() {
        if (menu.classList.contains('open')) {
            toggleMenu();
        }
    };
    document.getElementById('toggle').addEventListener('click', function (e) {
            toggleMenu();
            e.preventDefault();
    });
    window.addEventListener(WINDOW_CHANGE_EVENT, closeMenu);
})(this, this.document);
};
zaviiox
  • 33
  • 7
  • It seems to me that you need to write a directive that marries your javascript functionality to the html. – Amy Blankenship Feb 01 '17 at 19:55
  • @AmyBlankenship How exactly would I go about this? Sorry for my lack of knowledge here, I really haven't delved deeply into Javascript before. If you could even just send me to some sort of tutorial that'd be great too! – zaviiox Feb 01 '17 at 20:30
  • @zaviiox Please have a look at this http://stackoverflow.com/questions/12197880/angularjs-how-to-make-angular-load-script-inside-ng-include – nishant agrawal Feb 01 '17 at 21:08
  • I probably wouldn't do it as @nishantagrawal suggests. Instead, I'd hook the library functionality up to the directive in a more conventional manner. How that would work depends on the specifics of the library. Or you can just use one of the directives from [angular-bootstrap](https://angular-ui.github.io/bootstrap/) if they fit your needs. – Amy Blankenship Feb 01 '17 at 21:11

2 Answers2

0

So you need to use a directive for that to work without much complication, here is an example of how:

 angular.module('myApp').directive('menu', menu);
        function menu() {
            return {
                restrict: 'EA',
                template: "<div id=\"topbar\" class=\"pure-g\">\n" +
                        "    <div class=\"pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5\"> </div>\n" +
                        "    <div class=\"pure-u-22-24 pure-u-sm-20-24 pure-u-md-16-24 pure-u-lg-3-5\">\n" +
                        "        <h1>Title</h1>\n" +
                        "    </div>\n" +
                        "    <div class=\"pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5\"> </div>\n" +
                        "</div>\n" +
                        "\n" +
                        "<div id=\"menu\" class=\"custom-wrapper pure-g\">\n" +
                        "\n" +
                        "    <div class=\"pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5\"> </div>\n" +
                        "\n" +
                        "    <div class=\"pure-u-22-24 pure-u-sm-20-24 pure-u-md-16-24 pure-u-lg-3-5 \">\n" +
                        "        <div class=\"pure-g\">\n" +
                        "\n" +
                        "            <div class=\"pure-u-1 pure-u-md-1-3\" style=\"height: 2.1em\">\n" +
                        "                <div class=\"pure-menu\"> <a href=\"#\" class=\"pure-menu-heading custom-brand\" id=\"navTitle\">Navigation</a> <a href=\"#\" class=\"custom-toggle\" id=\"toggle\"><s class=\"bar\"></s><s class=\"bar\"></s></a> </div>\n" +
                        "            </div>\n" +
                        "\n" +
                        "            <div class=\"pure-u-1 pure-u-md-1-3\">\n" +
                        "                <div class=\"pure-menu pure-menu-horizontal custom-can-transform\">\n" +
                        "                    <ul class=\"pure-menu-list\">\n" +
                        "                        <li class=\"pure-menu-item\"><a href=\"#\" class=\"pure-menu-link\">Home</a></li>\n" +
                        "                        <li class=\"pure-menu-item\"><a href=\"#\" class=\"pure-menu-link\">About</a></li>\n" +
                        "                        <li class=\"pure-menu-item\"><a href=\"#\" class=\"pure-menu-link\">Contact</a></li>\n" +
                        "                    </ul>\n" +
                        "                </div>\n" +
                        "            </div>\n" +
                        "\n" +
                        "            <div class=\"pure-u-1 pure-u-md-1-3\">\n" +
                        "                <div class=\"pure-menu pure-menu-horizontal custom-menu-3 custom-can-transform\">\n" +
                        "                    <ul class=\"pure-menu-list\">\n" +
                        "                        <li class=\"pure-menu-item\"><a href=\"#\" class=\"pure-menu-link\">Yahoo</a></li>\n" +
                        "                        <li class=\"pure-menu-item\"><a href=\"#\" class=\"pure-menu-link\">W3C</a></li>\n" +
                        "                    </ul>\n" +
                        "                </div>\n" +
                        "            </div>\n" +
                        "        </div>\n" +
                        "    </div>\n" +
                        "\n" +
                        "    <div class=\"pure-u-1-24 pure-u-sm-2-24 pure-u-md-4-24 pure-u-lg-1-5\"> </div>\n" +
                        "</div>",
                scope: {
                },
                controller: function () {
                    var menu = document.getElementById('menu')
                            , WINDOW_CHANGE_EVENT = ('onorientationchange' in window) ? 'orientationchange' : 'resize';

                    function toggleHorizontal() {
                        [].forEach.call(document.getElementById('menu').querySelectorAll('.custom-can-transform'), function (el) {
                            el.classList.toggle('pure-menu-horizontal');
                        });
                    }


                    function toggleMenu() {
                        // set timeout so that the panel has a chance to roll up
                        // before the menu switches states
                        if (menu.classList.contains('open')) {
                            setTimeout(toggleHorizontal, 500);
                        } else {
                            toggleHorizontal();
                        }
                        menu.classList.toggle('open');
                        document.getElementById('toggle').classList.toggle('x');
                    }


                    function closeMenu() {
                        if (menu.classList.contains('open')) {
                            toggleMenu();
                        }
                    }

                    document.getElementById('toggle').addEventListener('click', function (e) {
                        toggleMenu();
                        e.preventDefault();
                    });
                    window.addEventListener(WINDOW_CHANGE_EVENT, closeMenu);
                }
            };

this is a quick directive that you can use by simply using <menu></menu> in your HTML page. But there is a lot that you can do to improve this, for example change template for templateUrl: 'path_to_your_html' and change the controller to be more angular-ish (yes, I made-up that word just now). Angular has a jQueryLite build-in that you can use, you could use the $timeout wrapper and change your classes dinamicaly with ng-class.

Carlos Angarita
  • 161
  • 3
  • 11
0

After basically sending my friend a .zip file of the whole thing, we were able to get it working.

Since the JS needed to work on a separate html file, we used AngularJS to make the JS an ng-controller for the external file. We were able to get this to work and it's all good now :)

This is the same as what @DrMints commented on one of the answers posted

zaviiox
  • 33
  • 7