Angular code not seeing controller - angularjs

I'm somewhat new to Angular so this may be something obvious I'm missing but...
I have a page with three main sections: top,middle, bottom. Nav buttons on the top make calls to JS functions that use $.ajax() to find pages and then populate the middle section. However, the angular references in the included file aren't working. It's like it can't see the controller. The ng-controller is on the body tag, but I also put it on the div in the included file in case that was the cause, but to no avail.
Does the angular code not know about the controller since it was loaded after the main page?
How can I get the angular code in the included file to work? I'm specifically using ng-click and ng-controller, but I also tried just outputting a variable from inside the controller and it simply outputs {{nav.sidelink}} to the screen.
app.js:
(function(){
var app = angular.module('vetSite', []);
app.controller('NavController', function(){
var subtab = 1;
var sidelink = 1;
this.setTab = function(st){
this.tab = st;
}
this.isSet = function(ct){
return this.tab === ct;
}
this.setSubTab = function(st){
this.subtab = st;
}
this.isSetSub = function(ct){
return this.subtab === ct;
}
this.setSideLink = function(sl){
this.sidelink = sl;
}
this.isSetSideLink = function(cl){
return this.sidelink === cl;
}
});
})();
HTML of included file:
<div id="subcontent">
<div ng-show="nav.isSetSideLink(1)">
Prairie has quality machines in our laboratory that can give us blood cell counts, electrolytes, and blood chemistry to check internal organs. This enables us to diagnose and treat patients rapidly, and to monitor response to treatment without waiting 24 hours for the bloodwork to come back from an outside laboratory. Having this information can make a huge difference in our success.
</div>
<div ng-show="nav.isSetSideLink(2)">
Being able to evaluate joint fluid for infection allows us to make a diagnosis and start treatment rapidly, increasing the chances of a positive outcome.
</div>
<div ng-show="nav.isSetSideLink(3)">
Real time evaluation of abdominal fluid can help with the diagnosis of colic. Increases in white blood cells and changes in abdominal fluid chemistries can indicate that the gut is becoming damaged. Getting these horses to colic surgery more quickly can result in a better outcome.
</div>
<div ng-show="nav.isSetSideLink(4)">
Running cultures in house enables us to know what type of bacteria is involved in an infection within 24-48 hours of an examination and can help direct treatment. Obtaining an antibiotic sensitivity for that bacteria rapidly improves the chances for a quick, full recovery. Sending cultures to an outside laboratory delays this information 36-48 hours.
</div>
</div>
<div id="subsidenav">
<div class="side_subnavbutton" ng-class="{ side_navbutton_selected:nav.isSetSideLink(1) }"><a href ng-click="nav.setSideLink(1);">In-House Blood Analysis</a></div>
<div class="side_subnavbutton" ng-class="{ side_navbutton_selected:nav.isSetSideLink(2) }">In-House Joint Fluid Analysis</div>
<div class="side_subnavbutton" ng-class="{ side_navbutton_selected:nav.isSetSideLink(3) }"><a href ng-click="nav.setSideLink(3);">In-House Abdominal Fluid Analysis</a></div>
<div class="side_subnavbutton" ng-class="{ side_navbutton_selected:nav.isSetSideLink(4) }"><a href ng-click="nav.setSideLink(4);">In-House Cultures</a></div>
</div>
It's totally ignoring all references to nav. All four paragraphs are showing up, and none of the links are changing class (despite nav.sidelink being initialized)
How do I make it see the controller?
Thanks.
EDIT: Some potentially important information:
here is the originally loaded page:
<html ng-app="vetSite">
<head>
<title>Welcome!</title>
<link rel="stylesheet" href="/css/style.css" type="text/css" media="all">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script language="javascript1.2" src="/js/angular.min.js"></script>
<script language="javascript1.2" src="/js/app.js"></script>
<script language="javascript1.2" src="/js/divs.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body ng-controller = "NavController as nav">
<div id="top_area">
<div id="header">
<img src="/images/headerlogo.gif" align="left" />
<img src = "/images/mastheads/fronthall_clearMH.jpg" align="right" /> <br clear="all"/>
<div>
<div class="buttondiv" style="left:50%;" ng-class="{ buttondiv_selected:nav.isSet(1) }">HOME</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(2) }">STAFF</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(3) }">SERVICES</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(4) }">FACILITY</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(5) }">LOCATION</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(6) }">CONTACT</div>
<div class="buttondiv" ng-class="{ buttondiv_selected:nav.isSet(7) }">CAREER</div>
</div>
<br/>
<br clear="all"/>
<div id="separatordiv"> </div>
</div>
</div>
<div id="middle_area">
<br clear="all" />
<div id="subnav" ng-show="nav.isSet(3);" style="margin-left: 20px;">
<div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(1) }">Sports<br/>Medicine</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(2) }">Surgery</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(3) }">Diagnostic<br/>Imaging</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(4) }">Laboratory<br/>Services</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(5) }">Reproduction</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(6) }">Dentistry</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(7) }">Complementary<br/>Medicine</div>
<br/>
<br clear="all" />
</div>
<div id="subnav" ng-show="nav.isSet(4);" style="margin-left: 20px;">
<div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(1) }">Laboratory</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(2) }">Pharmacy</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(3) }">Hospital</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(4) }">Exam<br/>Room</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(5) }">Surgery<br/>Room</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(6) }">Indoor<br/>Arena</div><div class="subbuttondiv" ng-class="{ subbuttondiv_selected:nav.isSetSub(7) }">Outdoor<br/>Arena</div>
<br/>
<br clear="all" />
</div>
<div id="content">
(original content ofmain page)
<br clear="all" />
</div>
</div>
<div id="bottom_area">
<div id="separatordiv"> </div>
<div id="footer">
<br/>
</div>
</div>
</body>
</html>
Everything you see here works. It's when I click on one of those subnav items (that only show up when I click certain tabs) and the SUB page of HTML content loads, that the Angular in there doesn't work.

I finally figured out that I needed to recompile the page once I reloaded the new code to make Angular see it as not just text.
Thanks, all for your suggestions.

Related

AngularJS - ng-click buttons not working

I am new to AngularJS. I'm trying to toggle a modal into view using ng-if and ng-click.
Essentially, in my controller, I have a scoped variable called "aboutOn". When it is true, the modal is displayed. When it's false, it's not. Simple.
The ng-if part works. But the ng-click part is causing trouble. Sometimes, it just doesn't work.
To open the modal I have this:
<div id="about-link-container" ng-click="aboutOn=true">
<p><i class="far fa-info-circle"></i> About</p>
</div>
This does not work how I want it to work. If I click on the actual text, nothing happens. It only triggers when I click around the border, not directly on the link. If I put the ng-click on the p tag, it doesn't work at all.
Then inside the modal, I have this to close it:
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
This doesn't work at all. What's going on here? Here is my controller, if that's possibly related:
angular.module('myApp', [])
.controller('myController', ['$scope', function myController($scope) {
$scope.female_name = "female name";
$scope.position = "position";
$scope.tedious_task = "tedious task";
$scope.dirty_task = "dirty task";
$scope.female_name = "female name";
$scope.celebrity = "celebrity";
$scope.useless_skill = "useless skill";
$scope.aboutOn = false;
}]);
Here is the entire view:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link href="https://fonts.googleapis.com/css?family=Gamja+Flower|Oswald" rel="stylesheet">
<script data-require="angular.js#1.3.10" data-semver="1.3.10" src="https://code.angularjs.org/1.3.10/angular.js"></script>
<script defer src="https://use.fontawesome.com/releases/v5.0.8/js/all.js"></script>
<script src="main.js"></script>
<link rel="stylesheet" type="text/css" href="styles.css" />
</head>
<body ng-app="myApp">
<div ng-controller='myController'>
<div class="form">
<div id="about-link-container" ng-click="aboutOn=true">
<p><i class="far fa-info-circle"></i> About</p>
</div>
<h1>M<img src="angular-logo.png" class="logo" />DLIBS</h1>
<div class="form-inner">
<h2>Provide the following words:</h2>
<input ng-model="female_name" />
<input ng-model="position" />
<input ng-model="tedious_task" />
<input ng-model="dirty_task" />
<input ng-model="celebrity" />
<input ng-model="female_name" />
<input ng-model="useless_skill" />
</div>
</div>
<div class="display">
<p>{{ female_name }} was a {{ position }}. Although she loved parts of her job,
she absolutely hated {{tedious_task}} and {{dirty_task}}. So, {{female_name}} met
with her life mentor {{celebrity}} who told her to learn how
to {{useless_skill}} at school. Her school didn't offer a
course on {{useless_skill}} so she studied programming instead.
</p>
</div>
<div ng-if="aboutOn" class="about">
<div class="about-main">
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
<h2 class="about-title"><i class="fas fa-info-circle"></i> About</h2>
<p class="about-p">Madlibs is an AngularJS application. When user fill in the words in
the form above, those words will automatically populate the paragraph below.
Try different combinations!
<br />
<br />
This application was made in 2018 by Jack Seabolt. It was constructed using AngularJS.
</p>
</div>
</div>
</div>
</div>
</body>
</html>
There are two problems that give you this issue.
ng-if creates its own scope.
So if you want to reach controller's scope, you need to have ng-click="$parent.aboutOn=false"
FA icons replace DOM (?). You cannot have ng-click on an icon.
Wrap your icon with <div> (as you already do) and put ng-click on it
The code that you need to change, from this:
<div class="about-close">
<i class="fas fa-times about-close-icon" ng-click="aboutOn=false"></i>
</div>
to this:
<div class="about-close" ng-click="$parent.aboutOn=false">
<i class="fas fa-times about-close-icon"></i>
</div>

Angular Material Contact Chips validation ng-minlength/maxlength/required

I've been trying to trigger a validation error on <md-contact-chips> for ng-minlength/maxlength/required but haven't been able to implement this effectively.
Is there a straight forward way to implement this myself? -- it seems for some reason that the contact chips directive in Angular Material does not support these validations.
See codepen here:
http://codepen.io/anon/pen/YqdRNw
<form name='myForm'>
<div ng-controller="ContactChipDemoCtrl as ctrl" layout="column" ng-cloak="" class="chipsdemoContactChips" ng-app="MyApp">
<md-content class="md-padding autocomplete" layout="column">
<md-contact-chips ng-model="ctrl.contacts" ng-minlength='1' ng-required='true' ng-maxlenght='3' name='contacts' md-contacts="ctrl.querySearch($query)" md-contact-name="name" md-contact-image="image" md-contact-email="email" md-require-match="true" md-highlight-flags="i" filter-selected="ctrl.filterSelected" placeholder="To" >
</md-contact-chips>
<p ng-show="myForm.contacts.$error.required" class="text-danger">You did not enter a contact</p>
<p ng-show="myForm.contacts.$error.minlength" class="text-danger">Your contact list is too short</p>
<p ng-show="myForm.contacts.$error.maxlength" class="text-danger">Your contact list is too long</p>
</md-content>
</div>
</form>
You cannot use this attribute directly. you have to use custom validation for it.
<md-contact-chips ng-model="ctrl.contacts" md-transform-chip="customvalidation($chip)"> </md-contact-chips>
<p ng-show="ctrl.contacts.length == 0 && ctrl.contacts.$touched"> Required </p>
<p ng-show="ctrl.contacts.length < 3 && ctrl.contacts.$touched"> Minimum 2 Contacts are required </p>
<p ng-show="ctrl.contacts.length > 5 && ctrl.contacts.$touched"> Maximum 5 Contacts can be added </p>
Inside controller you can define customvalidation function and add extra condition if you want.
function customvalidation(chip){
if(satisifedCondition(chip)){
return null //It will add chip
} else { return undefined } // It will not add chip
}
For the time being, you will need to write your own validation. Currently, md-chips only supports md-max-chips validation. Other forms of validation are currently pending. md-chips api
You can use the chips length property to get the number of chips in the array. With this you can use ng-show on your error messages to perform the necessary validation checks.
Ex: ng-show="myForm.contacts.length == 0"
Additionally, you can use md-on-add or md-on-remove to write your own validation.
Thats the how can I handle required validation with md-chips and md-contact-chips
I don't test code completely but I wrote that for give you an idea. I hope it helps you !
angular.module('MyApp', ['ngMaterial'])
.controller("ContactChipDemoCtrl", ['$scope', function ContactChipDemoCtrl($scope) {
$scope.formRequiredError = {};
$scope.sendButton = function(form) {
$scope.formRequiredError = {
"required": $scope.contacts.length <= 0;
};
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.22/angular.min.js"></script>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.js"></script>
<html lang="en" ng-app="MyApp">
<head>
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/angular_material/0.8.3/angular-material.min.css">
</head>
<body layout="column" ng-controller="ContactChipDemoCtrl as ctrl">
<form name='myForm'>
<div layout="column" ng-cloak="" class="chipsdemoContactChips">
<md-content class="md-padding autocomplete" layout="column">
<md-contact-chips ng-model="ctrl.contacts" ng-minlength='1' ng-required='true' ng-maxlenght='3' name='contacts' md-contacts="ctrl.querySearch($query)" md-contact-name="name" md-contact-image="image" md-contact-email="email" md-require-match="true" md-highlight-flags="i"
filter-selected="ctrl.filterSelected" placeholder="To">
</md-contact-chips>
<p ng-show="myForm.contacts.$error.minlength" class="text-danger">Your contact list is too short</p>
<p ng-show="myForm.contacts.$error.maxlength" class="text-danger">Your contact list is too long</p>
</md-content>
</div>
<div class="custom-error" ng-if="ctrl.contacts.length <= 0">
<div ng-messages="formRequiredError">
<div ng-message="required" translate='form_user_empty'></div>
</div>
</div>
</form>
</body>
</html>
Simple workaround:
<md-contact-chips
ng-class="{'myError': object.fieldName !== undefined && object.fieldName.length == 0}"
ng-model="object.fieldName"
otherStuff></md-contact-chips>
In CSS
.myError input::placeholder {
color: rgb(221,44,0) !important;
}

ng-repeat just doesnt work

<div ng-init="offers = [
{state:'Zabiorę', from:'Warszawa', to:'Wrocław', date:'30/04/16', size:'S:8 M:4 L:2 XL:0'},
{state:'Wyśle', from:'Wrocław', to:'Warszawa', date:'31/04/16', size:'S:0 M:1 L:0 XL:0'}]">
<div ng-repeat="offer in offers">
<hr class="featurette-divider">
<div class="announcement row">
<div class="col-md-1"><strong>{{offer.state}}</strong></div>
<div class="col-md-2">
<img class="img-circle"
src="data:image/gif;base64,R0lGODlhAQABAIAAAHd3dwAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw=="
alt="Generic placeholder image" width="70" height="70">
</div>
<div class="col-md-1">{{offer.from}}</div>
<div class="col-md-1"><span class="glyphicon glyphicon-arrow-right" aria-hidden="true"></span></div>
<div class="col-md-1">{{offer.to}}</div>
<div class="col-md-2">{{offer.date}}</div>
<div class="col-md-2">{{offer.size}}</div>
<div class="col-md-2">
<button type="button" class="btn btn-primary">Szczegóły</button>
</div>
</div>
</div>
</div> // </div ng-cloak>
Hello, i just wrote some code in my jhipster project, i wrote that in one of my project template and it just doesnt work, it shows nothing. When on jsfiddle.net it works.
#edit
Entire code, controller and state:
- http://pastebin.com/2tkvbiwG - template.html
- http://pastebin.com/kV4E7x0G - state.js
- http://pastebin.com/XF5rBmK7 - controller.js
Your code should work just fine. Please check that you have included angular.js and that you have defined your ng-app and ng-controller
Here is a plunker:
https://plnkr.co/edit/JLIQJQoEM9q4iAztY7KQ?p=preview
EDIT
In controller.js you need to define ui-router like this.
angular
.module('deliveritApp', ['ui.router'])
.controller('SearchOfferController', SearchOfferController);
Also name your function SearchController to function SearchOfferController.
In state.js you need to add the $stateProvider in the config like this:
angular
.module('deliveritApp')
.config(['$stateProvider', stateConfig])

ng-style not working inside nested ng-repeat

I've got the following markup:
<li ng-repeat="month in months">
<!-- NOTE THAT THIS IS WORKING IN ALL BROWSERS -->
<div class="cm-month-grid" ng-style="{width:{{month.pos.width}}+'px', left:{{month.pos.left}}+'px'}">
<div class="cm-month-title" title="{{month.date.format('DD.MM.YY')}} {{month.pos | json}}">{{month.date.format('MMM.YY')}}</div>
<div class="cm-month-border"></div>
</div>
</li>
that runs fine, but this is not:
<li ng-repeat="unit in units | filter: filter.text">
<div class="cm-periods">
<!-- BUT THIS IS NOT WORKING... WHY....
<div ng-repeat="period in unit.periods" class="cm-period" ng-style="{width:{{period.pos.width}}+'px', left:{{period.pos.left}}+'px'}" data-period="{{.}}}">
<span >{{period.start.format('DD.MM.YY')}}</span>
<div style="background: pink;" ng-style="{width:{{period.pos.width}}+'px', left:{{period.pos.left}}+'px'}">jalla</div>
</div>-->
<!-- WORKING IN CHROME ONLY -->
<div ng-repeat="period in unit.periods" class="cm-period" style="width:{{period.pos.width}}px; left:{{period.pos.left}}px;" data-period="{{.}}}">
<span>{{period.start.format('DD.MM.YY')}}</span>
</div>
<!-- -->
</div>
</li>
Full example could be seen here: http://plnkr.co/edit/aZsZEM?p=preview
I know there are issues with style and IE, that's why I'm using the ngStyle, but it does not update it style (try clicking on the zoom in the full example in IE)
Thanks for any help
Larsi
You are using ng-style with double curly brackets. As far as I know that's not valid in an expression.
Try this:
<div ng-repeat="period in unit.periods" class="cm-period" ng-style="{'width':period.pos.width+'px', 'left':period.pos.left+'px'}" data-period="{{.}}}">
<span >{{period.start.format('DD.MM.YY')}}</span>
<div style="background: pink;" ng-style="{'width':period.pos.width+'px', 'left':period.pos.left+'px'}">jalla</div>
</div>
</div>
Hmm, still looks messy to me. But, HEY! it zooms! (in FF)
Uh, forgot: Forked Plunk

AngularJS Showing/Hiding content and swapping an image

I have a basic widget block:
<div class="matter ng-controller="ProductsCtrl">
<div class="container-fluid">
<div class="widget">
<div class="widget-head">
<div class="pull-left">Browse live products</div>
<div class="widget-icons pull-right">
<a class="wminimize" href="#" ng-click="showContent = !showContent"><i class="icon-chevron-up"></i></a>
</div>
<div class="clearfix"></div>
</div><!--widget-head-->
<div class="widget-content" ng-class="{ 'hidden': !showContent }">
<div class="padd">
<div>
{{content}}
</div>
</div>
<div class="widget-foot"></div>
</div><!--widget-content-->
</div><!--widget-->
</div>
</div>
And here is the empty controller:
appAdmin.controller("ProductsCtrl", function($scope){
});
I'm using ng-click to hide/show the content, but I am trying to default the content to be visible, and also try to swap the image for the icon chevron down whenever it's hidden. I am very new to Angular and am looking for some direction in adding models and things to make these simple features work.
Any help would be appreciated.
EDIT: Made default visible by switching ng-class="{ 'hidden' : !showContent }" to ng-class="{ 'hidden' : showContent }"
For the content to be visible by default, I would set $scope.showContent to true in the controller. You can use ng-class to change the chevron icon class based on the value of showContent in the following way: <i ng-class="{'icon-chevron-up': showContent, 'icon-chevron-down': !showContent}"></i>. Only the keys of the truthy values will be applied, so it will be either icon-chevron-up or icon-chevron-down. Let me know if I misunderstood your question!

Resources