Avatar of DanteAdmin
DanteAdmin
Flag 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

JScriptScripting LanguagesJavaScriptBootstrap

Avatar of undefined
Last Comment
Kevin Robinson

8/22/2022 - Mon
Alexandre Simões

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!
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
Alexandre Simões

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?
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
Kyle Hamilton

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.
Kyle Hamilton

btw, you are calling jquery twice, so if you do decide to jquery, you still have to remove one of them.
DanteAdmin

ASKER
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

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Kyle Hamilton

does the click action even enter the function? put a log at the top of the function
Kyle Hamilton

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
DanteAdmin

ASKER
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
All of life is about relationships, and EE has made a viirtual community a real community. It lifts everyone's boat
William Peck
Alexandre Simões

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.
DanteAdmin

ASKER
Path works fine in the other code so I guess it should be fine

If I change the path slightly it throws errors

Error-change-of-path.JPGRelative.JPG
Exact-path.JPG
ASKER CERTIFIED SOLUTION
Kevin Robinson

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.