Stweet
Stweet

Reputation: 703

Angular modal instance can't read DOM elements

Hi im playing with angular modal instance..

But when i declare a querySelector in the modal controler it gives console error of Cannot read property 'querySelector' of null

HTML

      <body>

            <div id="signature-pad">

                    <canvas width="300" height="300"></canvas>

                    <div class="description">Sign above</div>
                    <button class="button clear" data-action="clear">Clear</button>

            </div>



</body>

    <div class="modal-footer">
        <button class="btn btn-success btn-lg" ng-click="ok();">Gem & Godkend</button>
        <button class="btn btn-warning btn-lg" ng-click="cancel()">Annuler</button>
   </div>

JS - ModalInstanceController

var ModalInstanceCtrl = function ($scope, $modalInstance) {


            $scope.init = function() {
                var wrapper = document.getElementById("signature-pad"),
                    clearButton = wrapper.querySelector("[data-action=clear]"),
                    canvas = wrapper.querySelector("canvas"),
                    signaturePad;

                signaturePad = new SignaturePad(canvas);

                clearButton.addEventListener("click", function (event) {
                    signaturePad.clear();
                });
                $scope.ok = function () {
                    $modalInstance.close(signaturePad.toDataURL());
                };

                $scope.cancel = function () {
                    $modalInstance.dismiss('cancel');
                };


            };

        $modalInstance.opened.then($scope.init);

        };

So it seams like it, can't find dom elements in model .. :s As you i can i tried to load, model into dom first with $modalInstance.opened.then($scope.init); But this dosen't work either

Upvotes: 3

Views: 4254

Answers (3)

Wadi Diaz-wong
Wadi Diaz-wong

Reputation: 121

I concur with dfsk, that's a more elegant solution, just make sure that, if this is is part of a bootstrap ui-tab, do not forget to add an ng-if="activeTab=2", where 2 is the zero-indexed tab where the signature-pad lives. activeTab is a scope variable containing the current tab. And wait till the DOM updates (via $timeout(fn(){})). That's when the right dimensions of the canvas element can be accessed and handled nicely.

Upvotes: 0

Stweet
Stweet

Reputation: 703

Umm seams that DOM elements needed to be loaded first.. found my answer here https://github.com/angular-ui/bootstrap/issues/2586

    $scope.init = function() {
var wrapper = document.getElementById("signature-pad"),
...
}
$modalInstance.opened.then($scope.init);

this initialize the dom elemtens first, so query selector can see the dom elements ! :)

i just need'ed <div ng-init="init()"> in html

Upvotes: 3

dfsq
dfsq

Reputation: 193271

Controller is instantiated before template is loaded and injected in DOM. In general this is not very good idea do perform such DOM manipulations in controller. You should create directive for this. For example:

add.directive('signaturePad', function() {
    return {
        link: function(scope, element) {

            var wrapper = element[0],
                clearButton = wrapper.querySelector("[data-action=clear]"),
                saveButton = wrapper.querySelector("[data-action=save]"),
                canvas = wrapper.querySelector("canvas"),
                signaturePad;

            signaturePad = new SignaturePad(canvas);

            clearButton.addEventListener("click", function (event) {
                signaturePad.clear();
            });
        }
    };
});

and use it like this:

<div signature-pad id="signature-pad">
    <canvas width="100" height="100"></canvas>
    <div class="description">Sign above</div>
    <button class="button clear" data-action="clear">Clear</button>
    <button class="button save" data-action="save">Save</button>
</div>

Upvotes: 0

Related Questions