Link to home
Start Free TrialLog in
Avatar of DanteAdmin
DanteAdminFlag for United Kingdom of Great Britain and Northern Ireland

asked on

Angular JS ng-click stops responding

I'm fairly new to Angular.JS but making some nice progress and getting some smaller Apps

Now I'm working on another one and for some reason ng-click randomly stops working as I build ... so I think I'm missing something fundamental here

I think after I've moved it to an external include file it stopped working, but not sure

Can't the include file read controller.js any longer? Is there a way to make it or am I doing it all in the wrong way?

HTML PAGE
<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="favicon.ico">

    <title>Booking System</title>

    <!-- Bootstrap core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="navbar-fixed-top.css" rel="stylesheet">
    
    <link rel="stylesheet" href="css/ngDialog.css"/>
    <link rel="stylesheet" href="css/ngDialog-theme-default.css"/>

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    
	<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
	<script> 
    $(function(){
      $("#includeMenu").load("inc/WhyQ-menu.htm"); 
    });
    </script> 
  </head>

  <body ng-controller="PostsCtrl" style="background:#000;">

    <!-- INCLUDE MENU -->
        <div id="includeMenu"></div>
        <!-- INCLUDE MENU END -->

    <div style="width:100%;">
  	
    <h1 style="text-align:center;"><img src="img/clientlogo/{{LoggedInGlobalLogo}}" alt="Please wait..." style="padding:0 0 10px 0;"/></h1>
    <table class="table table-striped table-bordered table-hover" style="background:#fff;">
	    <thead>
		    <tr>
		    	<th>Id | QueueId</th>
			    <th>Name</th>
			    <th>Est.</th>
			    <th>Phone</th>
			    <th>#</th>
			    <th> </th>
			    <th>Status</th>
			    <th> </th>
			    <th> </th>
			    <th>PIN</th>
			    <th>Notes</th>
		    </tr>	
	    </thead>
	    <tbody>
		    <tr ng-repeat="customer in customers.queueDetails">
			    <td>{{customer.user.id}} | {{customer.id}}</td>
			    <td><button type="submit" class="btn btn-default" ng-click='setSessionUser(customer.user.phoneNumber, customer.id, customer.notes)'>{{customer.user.name}}</button></td>
			    <td>{{customer.estimatedWaitingTime}}</td>
			    <td>{{customer.user.phoneNumber}}</td>
			    <td>{{customer.partySize}}</td>
			    <td><button type="submit" class="btn btn-success" ng-click='notifyUser(customer.user.id)' style="display:inline;">Notify</button></td>
			    <td>{{customer.entryStatus}} (<div ng-if="customer.entryStatus == 'NOTIFIED'" style="margin:0; display:inline;">{{customer.notifiedTime.slice(11,16)}}</div><div ng-if="customer.entryStatus == 'WAITING'" style="margin:0; display:inline;">{{customer.timeinQueue | limitTo: 5}}</div>)</td>
			    <td><button type="submit" class="btn btn-danger" ng-click='removeUser(customer.user.phoneNumber)' style="display:inline;">Remove</button></td>
			    <td><button type="submit" class="btn btn-primary" ng-click='seatUser(customer.user.id)' style="display:inline;">Seat</button> <input type="text" class="form-control" maxlength="3" style="width:50px; height:33px; display:inline;" ng-model="seatednumber"> {{seatednumber}} {{enteredSeatedNumber}}</td>
			    <td><button type="submit" class="btn btn-default" ng-click='pinUser()'>{{customer.user.pin}}</button></td>
			    <td><button type="submit" class="btn btn-default" ng-click='showNotes(customer.notes)'>{{customer.notes | limitTo: 10}}</button></td>
		    </tr>
	    </tbody>
    </table>
    <a href="queueHistory.php"><button type="submit" class="btn btn-info" ng-click=''>Queue History</button></a>
	
	<br/><br/>
	<center>
  		<div class="alert alert-success" ng-show="showSuccessAlert" style="color:#000;">
	   <button type="button" class="close" data-ng-click="switchBool('showSuccessAlert')" >×</button>
		{{successTextAlert}}
	 </div>

	<div class="alert alert-danger" ng-show="showFailureAlert" style="color:#000;">
	   <button type="button" class="close" data-ng-click="switchBool('showFailureAlert')" >×</button>
		{{failureTextAlert}}
	 </div>
	 </center>
</div> <!-- /container -->
	

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script> 
    
	<script src="vendor/select2-3.4.6/select2.min.js"></script>
	<script src="js/controllers.js"></script>
	<script src="/js/ngDialog.js"></script>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <!--<script src="js/ie10-viewport-bug-workaround.js"></script>-->
  </body>
</html>

Open in new window


INCLUDED PAGE
<!-- Fixed navbar -->
    <div class="navbar navbar-default navbar-fixed-top" role="navigation">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="/viewQueue.php"><img src="img/WhyQ.eu-whitebg-logo.png" style="height:50px; margin-top:-18px;" /></a>
        </div>
        <div class="navbar-collapse collapse">
          <ul class="nav navbar-nav">
            <li><a href="viewQueue.php">View Queue</a></li>
            <li><a href="addBooking.php">New Customer</a></li>
          </ul>
          <ul class="nav navbar-nav navbar-right">
            <li><a href="https://www.facebook.com/pages/Whyq-Limited/497617086939859?fref=ts"><img src="img/social/fb.png" style="height:40px; float:left; margin:-8px 0 0 0;" /></a></li>
            <li style="height:40px; float:left; padding:9px 0 0 0;"><button type="submit" class="btn btn-info" ng-click='LogOutClient()'>Log Out</button></li>
          </ul>
        </div><!--/.nav-collapse -->
      </div>
    </div>

Open in new window


CONTROLLER.JS
/* CLEAR ALL sessionStorage and log out client */
	$scope.LogOutClient = function() {
		sessionStorage.clear();
		
		$window.location.href = '/';
	}

Open in new window

Avatar of Alexandre Simões
Alexandre Simões
Flag of Switzerland image

This is how you're including that navbar html?
$(function(){
      $("#includeMenu").load("inc/WhyQ-menu.htm"); 
    });

Open in new window

This doesn't work because it's not being handled asynchronously using jquery.
You need to use one of the 2 available options that Angular provides, that are ng-include directive or create your own directive for the menu.

ng-include
For this option you just need to:
1. delete the jquery load code (lines 30 to 33).
2. replace line 39 by:
<div ng-include="inc/WhyQ-menu.htm"></div>

Open in new window


Create your directive
This is the best option and the one that allows to properly isolate your code. On the other hand it's also the one that requires more work because in order to do it properly you should move some code from the Controller into the directive.

... a third option
Your existing code can still work but you need to "tell" Angular that you did some changes to the DOM and want it to have a look. For that you would need to use $scope.$apply(); and move line 31 into the controller making it something like:
$("#includeMenu").load("inc/WhyQ-menu.htm", function(){
$scope.$apply();
});

Open in new window

This technique is the last resource, like in the cases where none of the above apply.

If you're getting serious about AngularJS I strongly recommend you to take some time to learn it properly and in depth. I leave you the 2 main training resources I usually recommend:
PluralSight
EggHead.io

Cheers!
Avatar of DanteAdmin

ASKER

Hi Alexandre

And thanks again for your help

I did try that before without luck and the same now - no error code and nothing is included

Is there anything else I'm missing that has to be defined or activated ?

You are right and I'm trying to look up each task and do it the proper Angular JS way, sometimes I run out of time and have to cheat but I'm looking forward to my next "not so busy" period to do some proper Angular JS reading up

Regards,
Markus
Some questions:
The ng-include isn't working?
Is the HTML being displayed?
Can you show me your HTML now that you changed it to use the ng-include directive?
when you use ng-include you create a chil scope, so that might be part of your issue.

you would be much better off using ui-router (which is eventually going to be built right into angular) and define views.

you have to break out of the jquery frame of mind altogether. my advice would be to remove jquery from your page until you are a point where you know how to integrate it into your app properly by writing directives.

there is no point in taking shortcuts with angular - you will create more headaches than it's worth. for better or worse, angular is a very opinionated framework. that's why everyone talks about doing things the 'angular way'. as much as i dislike doing thing things anybody's way, this is a time when doing it their way will really benefit you in the long run. and doing it any other way is unintuitive and complicated.
btw, you are calling jquery twice, so if you do decide to jquery, you still have to remove one of them.
I think I did per instructions i.e. delete the old lines in the head and replaced the include code with the ng control instead

<!DOCTYPE html>
<html lang="en" ng-app="MyApp">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="favicon.ico">

    <title>Booking System</title>

    <!-- Bootstrap core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet">

    <!-- Custom styles for this template -->
    <link href="navbar-fixed-top.css" rel="stylesheet">
    
    <link rel="stylesheet" href="css/ngDialog.css"/>
    <link rel="stylesheet" href="css/ngDialog-theme-default.css"/>

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
    
	<script type="text/javascript" src="http://code.jquery.com/jquery.js"></script>
  </head>

  <body ng-controller="PostsCtrl" style="background:#000;">

    <!-- INCLUDE MENU -->
        <div ng-include="inc/WhyQ-menu.htm"></div>
        <!-- INCLUDE MENU END -->

    <div style="width:100%;">
  	
    <h1 style="text-align:center;"><img src="img/clientlogo/{{LoggedInGlobalLogo}}" alt="Please wait..." style="padding:0 0 10px 0;"/></h1>
    <table class="table table-striped table-bordered table-hover" style="background:#fff;">
	    <thead>
		    <tr>
		    	<th>Id | QueueId</th>
			    <th>Name</th>
			    <th>Est.</th>
			    <th>Phone</th>
			    <th>#</th>
			    <th>&nbsp;</th>
			    <th>Status</th>
			    <th>&nbsp;</th>
			    <th>&nbsp;</th>
			    <th>PIN</th>
			    <th>Notes</th>
		    </tr>	
	    </thead>
	    <tbody>
		    <tr ng-repeat="customer in customers.queueDetails">
			    <td>{{customer.user.id}} | {{customer.id}}</td>
			    <td><button type="submit" class="btn btn-default" ng-click='setSessionUser(customer.user.phoneNumber, customer.id, customer.notes)'>{{customer.user.name}}</button></td>
			    <td>{{customer.estimatedWaitingTime}}</td>
			    <td>{{customer.user.phoneNumber}}</td>
			    <td>{{customer.partySize}}</td>
			    <td><button type="submit" class="btn btn-success" ng-click='notifyUser(customer.user.id)' style="display:inline;">Notify</button></td>
			    <td>{{customer.entryStatus}} (<div ng-if="customer.entryStatus == 'NOTIFIED'" style="margin:0; display:inline;">{{customer.notifiedTime.slice(11,16)}}</div><div ng-if="customer.entryStatus == 'WAITING'" style="margin:0; display:inline;">{{customer.timeinQueue | limitTo: 5}}</div>)</td>
			    <td><button type="submit" class="btn btn-danger" ng-click='removeUser(customer.user.phoneNumber)' style="display:inline;">Remove</button></td>
			    <td><button type="submit" class="btn btn-primary" ng-click='seatUser(customer.user.id)' style="display:inline;">Seat</button> <input type="text" class="form-control" maxlength="3" style="width:50px; height:33px; display:inline;" ng-model="seatednumber"> {{seatednumber}} {{enteredSeatedNumber}}</td>
			    <td><button type="submit" class="btn btn-default" ng-click='pinUser()'>{{customer.user.pin}}</button></td>
			    <td><button type="submit" class="btn btn-default" ng-click='showNotes(customer.notes)'>{{customer.notes | limitTo: 10}}</button></td>
		    </tr>
	    </tbody>
    </table>
    <a href="queueHistory.php"><button type="submit" class="btn btn-info" ng-click=''>Queue History</button></a>
	
	<br/><br/>
	<center>
  		<div class="alert alert-success" ng-show="showSuccessAlert" style="color:#000;">
	   <button type="button" class="close" data-ng-click="switchBool('showSuccessAlert')" >×</button>
		{{successTextAlert}}
	 </div>

	<div class="alert alert-danger" ng-show="showFailureAlert" style="color:#000;">
	   <button type="button" class="close" data-ng-click="switchBool('showFailureAlert')" >×</button>
		{{failureTextAlert}}
	 </div>
	 </center>
</div> <!-- /container -->
	

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script> 
    
	<script src="vendor/select2-3.4.6/select2.min.js"></script>
	<script src="js/controllers.js"></script>
	<script src="/js/ngDialog.js"></script>

    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <!-- IE10 viewport hack for Surface/desktop Windows 8 bug -->
    <!--<script src="js/ie10-viewport-bug-workaround.js"></script>-->
  </body>
</html>

Open in new window

does the click action even enter the function? put a log at the top of the function
you still have two calls to jquery: line 28, and line 98 in the code posted above. This may not be the cause of the problem described, but it will definitely cause other problems
I've removed the bottom one so only one call there now

The include is not displaying any data so I can't test the click

If I simply include the code on the page the click works fine

I think I will spend this morning looking at the directives etc as I feel they will come in handy plenty of times

Still a bit worried re the rest of my code if a simple call like "<div ng-include="inc/WhyQ-menu.htm"></div>" isn't working
The include is not displaying any data so I can't test the click
Does that path work? Remember that the path must be relative to the main HTML page, not the view or anything else.
Path works fine in the other code so I guess it should be fine

If I change the path slightly it throws errors

User generated imageRelative.JPG
Exact-path.JPG
ASKER CERTIFIED SOLUTION
Avatar of Kevin Robinson
Kevin Robinson

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial