Problem
New to Angular and I'm using "Foundation for Apps: to help with building a business directory in Angular. I'm looking to create routes for a detailed view for each of the businesses, which would look like http://localhost:8080/nameofbusiness.
I've been reading the Angular docs and this example pretty much does exactly what I'm trying to do, I've tried using in a similar snippet (see below) into app.js, but it doesn't seem to be compiling correctly.
Github: https://github.com/onlyandrewn/angular
Snippet
phonecatApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/phones', {
templateUrl: 'partials/phone-list.html',
controller: 'PhoneListCtrl'
}).
when('/phones/:phoneId', {
templateUrl: 'partials/phone-detail.html',
controller: 'PhoneDetailCtrl'
}).
otherwise({
redirectTo: '/phones'
});
}]);
app.js
'use strict';
var myApp = angular.module('application', [
'ui.router',
'ngAnimate',
//foundation
'foundation',
'foundation.dynamicRouting',
'foundation.dynamicRouting.animations'
])
.config(config)
.run(run)
;
config.$inject = ['$urlRouterProvider', '$locationProvider'];
function config($urlProvider, $locationProvider) {
$urlProvider.otherwise('/');
$locationProvider.html5Mode({
enabled:false,
requireBase: false
});
$locationProvider.hashPrefix('!');
}
function run() {
FastClick.attach(document.body);
}
home.html (Main view of all the businesses)
---
name: home
url: /
---
<div ng-controller="MainCtrl">
<header>
<p class="sponsored" id="top">Sponsored by </p>
<img src="http://placehold.it/200x30" class="sponsors" alt="">
<h1>Business Directory</h1>
<div class="find">
<input type="search" placeholder="What are you looking for?" ng-model="query">
</div><!-- /.find -->
</header>
<div class="businesses">
<div class="storeIcon">
<img src="/assets/img/store.png" class="store" alt="">
</div><!-- /.storeIcon -->
<p class="number">Search {{businesses.length}} businesses in Brandon</p><button class="filter button">Filter by <i class="fa fa-chevron-down"></i></button>
<div class="options">
<div class="cat">
<div class="categories">
<div class="group">
<p class="name">Grade Level</p>
<div class="check">
<input type="radio" name=""><p>Auto</p>
<input type="checkbox" name=""><p>Restaurant</p>
<input type="checkbox" name=""><p>Other</p>
</div><!-- /.check -->
</div><!-- /.group -->
<div class="group">
<p class="name">School Type</p>
<div class="check">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div><!-- /.check -->
</div><!-- /.group -->
</div><!-- /.categories -->
</div><!-- /.cat -->
</div><!-- /.options -->
</div><!-- /.businesses -->
<div class="all">
<div class="business large-4.columns" data-ng-repeat="business in businesses | filter:query | orderBy:'name'" >
<div class="overlay">
<img src="http://placehold.it/300x300" class="storefront" alt="">
</div><!-- /.overlay -->
<div class="info">
<p class="name">{{business.name}}</p>
<p class="description">{{business.description}}</p>
<p class="address">{{business.address}}</p>
{{business.website}}
</div><!-- /.info -->
</div>
</div>
<footer>
<hr>
<i class="fa fa-twitter"></i>
<i class="fa fa-facebook"></i>
<div class="backContainer">
<p class="back">Back to top</p>
</div><!-- /.backContainer -->
</footer>
</div>
expanded.html (Detailed view of just one of the businesses)
---
name: expand
url: /:id
---
<div ng-controller="MainCtrl">
<p>This is the expanded view for each of the businesses</p>
</div>
You will need to define a parent view for your expanded template using the simplified built in plugin, then foundation for apps will use that to generate the proper $routeProvider's configuration. You can also use that same plugin to define a wrapper controller for it.
Your expanded.html file may look like this :
---
name: expand
url: /:id
parent: home
controller: EditCtrl
---
<p>This is the expanded view for each of the businesses</p>
<pre> {{$stateParams}}</pre>
now if /#!/home is the url to what you decided to be a parent page or product listing page, then /#!/home/nameofbusiness will take you to it's child page "expanded", and it will set the id value of $stateParams to "nameofbusiness" $stateParams -> {"id":"nameofbusiness"} which will be accessible directly in your expand template or within it's related controller if you need to build some logic on top of it.
You will find more details in Foundation for apps Dynamic Routing documentation
Related
So I have an application and it's working great (MEAN stack), and I'm adding in the <script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script> and <script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script> so that I can use the modal.
The code will be below, but here are some explanations first. I've added angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']); in my angular app declaration. And then in the controller I properly injected it via locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];. I haven't declared an ng-controlleranywhere in the html, so I'm not really sure what the problem may be.
Lastly, a copy of the error:
Error: [$injector:unpr] http://errors.angularjs.org/1.5.5/$injector/unpr?p0=%24modalProvider%20%3C-%20%24modal%20%3C-%20locationDetailCtrl
Below are 4 blocks of code. The first two are locationDetail.controller.js and locationDetail.view.html, the others are the app.js (angular app.js) and index.html.
locationDetail.controller.js
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$modal', 'loc8rData'];
function locationDetailCtrl($routeParams, $modal, loc8rData) {
var vm = this;
vm.locationid = $routeParams.locationid;
loc8rData.locationById(vm.locationid)
.success(function(data) {
vm.data = { location: data };
vm.pageHeader = {
title: vm.data.location.name
};
})
.error(function(e) {
console.log(e);
});
vm.popupReviewForm = function() {
alert("Let's add a review!");
};
}
})();
locationDetail.view.html
<navigation></navigation>
<div class="container">
<page-header content="vm.pageHeader"></page-header>
<div class="row">
<div class="col-xs-12 col-md-9">
<div class="row">
<div class="col-xs-12 col-sm-6">
<p class="rating" rating-stars rating="vm.data.location.rating"></p>
<p>{{ vm.data.location.address }}</p>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Opening hours</h2>
</div>
<div class="panel-body">
<p ng-repeat="time in vm.data.location.openingTimes" ng-switch on="time.closed">
{{ time.days }} :
<span class="opening-time" ng-switch-when="true">closed</span>
<span class="opening-time" ng-switch-default>{{ time.opening + " - " + time.closing }}</span>
</p>
</div>
</div>
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Facilities</h2>
</div>
<div class="panel-body">
<span class="label label-warning label-facility" ng-repeat="facility in vm.data.location.facilities">
<span class="glyphicon glyphicon-ok"></span>
{{ facility }}
</span>
</div>
</div>
</div>
<div class="col-xs-12 col-sm-6 location-map">
<div class="panel panel-primary">
<div class="panel-heading">
<h2 class="panel-title">Location map</h2>
</div>
<div class="panel-body">
<img src="http://maps.googleapis.com/maps/api/staticmap?center={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&zoom=17&size=400x350&sensor=false&markers={{ vm.data.location.coords[1] }},{{ vm.data.location.coords[0] }}&scale=2" class="img-responsive img-rounded">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-primary review-panel">
<div class="panel-heading">
<a ng-click="vm.popupReviewForm()" class="btn btn-default pull-right">Add review</a>
<h2 class="panel-title">Customer reviews</h2>
</div>
<div class="panel-body review-container">
<div class="review" ng-repeat="review in vm.data.location.reviews | orderBy:'createdOn':true">
<div class="row">
<div class="well well-sm review-header">
<span class="rating" rating-stars rating="review.rating"></span>
<span class="reviewAuthor">{{ review.author }}</span>
<small class="reviewTimestamp">{{ review.createdOn | date : 'MMMM d yyyy' }}</small>
</div>
<div class="col-xs-12">
<p ng-bind-html="review.reviewText | addHtmlLineBreaks"></p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-xs-12 col-md-3">
<p class="lead">{{ vm.data.location.name }} is on Loc8r because it has accessible wifi and space to sit down with your laptop and get some work done.</p>
<p>If you've been and you like it - or if you don't - please leave a review to help other people just like you.</p>
</div>
</div>
<footer-generic></footer-generic>
</div>
app.js (angular app.js).
(function() {
angular.module('loc8rApp', ['ngRoute', 'ngSanitize', 'ui.bootstrap']);
function config($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl: 'home/home.view.html',
controller: 'homeCtrl',
controllerAs: 'vm'
})
.when('/about', {
templateUrl: '/common/views/genericText.view.html',
controller: 'aboutCtrl',
controllerAs: 'vm'
})
.when('/location/:locationid', {
templateUrl: '/locationDetail/locationDetail.view.html',
controller: 'locationDetailCtrl',
controllerAs: 'vm'
})
.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
}
angular
.module('loc8rApp')
.config(['$routeProvider', '$locationProvider', config]);
})();
index.html
<!DOCTYPE html>
<html ng-app="loc8rApp">
<head>
<meta name="viewport" content="width=device-width", initial-scale="1.0">
<title>Loc8r</title>
<link rel="stylesheet" href="/bootstrap/css/amelia.bootstrap.css">
<link rel="stylesheet" href="/stylesheets/style.css">
<base href="/">
</head>
<body ng-view>
<script src="/angular/angular.min.js"></script>
<script src="/lib/angular-route.min.js"></script>
<script src="/lib/angular-sanitize.min.js"></script>
<script src="/lib/ui-bootstrap-custom-1.3.3.min.js"></script>
<script src="/lib/ui-bootstrap-custom-tpls-1.3.3.min.js"></script>
<script src="/angular/loc8r.min.js"></script>
<script src="/javascripts/jquery-1.12.2.min.js"></script>
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/javascripts/validation.js"></script>
</body>
</html>
Error tells you there is an unknown provider $modalProvider. That means you are injecting $modal and it isn't defined within the app.
The reason is that angular-ui-bootstrap now uses $uib prefix for services.
Try changing $modal to $uibModal and verify in angular-ui-bootstrap docs
Folder structure is as follows
assets
...........img
...........fonts
...........js
...........css
data
...........data.json
partials
...........main.html
...........contact.html
...........demo.html
...........line-of-business.html
...........product.html
directives
...........nav.html
index.html
The First Snippet is my Angular app.js File
The Second Snippet is my index.html
The Third Snippet is my main.html which is the partial i need to be put when the home page is loaded, similar to this one I have partials for other pages in my website
The Fourth Snippet is my nav custom directive which is placed inside all partials because each partial have a different id in the header
the fifth snippet is the json file I take data from to the partials
The Problem is that the directive is not loading in any of the partials html
var rootCave = angular.module("rootCave", ['ngRoute']);
rootCave.directive('navigation', [
function() {
'use strict';
return {
restrict: "E",
templateUrl: 'directives/nav.html'
};
}
]);
rootCave.service('aboutService', function($http, $q) {
"use strict";
var deferred = $q.defer();
$http.get('data/data.json').then(function(rcdata) {
deferred.resolve(rcdata);
});
this.getAbout = function() {
return deferred.promise;
};
});
rootCave.controller('aboutCtrl', function($scope, aboutService) {
'use strict';
var promise = aboutService.getAbout();
promise.then(function(rcdata) {
$scope.about = rcdata.data.about;
$scope.products = rcdata.data.products;
$scope.mobileProduct = rcdata.data.mobileProduct;
$scope.clients = rcdata.data.clients;
$scope.anytime = rcdata.data.anytime;
$scope.lobProduct = rcdata.data.lobProduct;
$scope.Product = rcdata.data.lobProduct.projectsdetails;
});
});
rootCave.config(['$routeProvider',
function($routeProvider) {
'use strict';
$routeProvider.
when('/main', {
templateUrl: '/partials/main.html',
controller: 'MainCtrl'
})
.when('/contact', {
templateUrl: '/partials/contact.html',
controller: 'ContactCtrl'
})
.when('/demo', {
templateUrl: '/partials/demo.html',
controller: 'DemoCtrl'
})
.when('/line-of-business', {
templateUrl: '/partials/line-of-business.html',
controller: 'LOBCtrl'
})
.when('/mob-app', {
templateUrl: '/partials/mob-app.html',
controller: 'MobAppCtrl'
})
.when('/mobile-apps', {
templateUrl: '/partials/mobile-apps.html',
controller: 'MobileAppsCtrl'
})
.when('/product', {
templateUrl: '/partials/product.html',
controller: 'ProductCtrl'
})
otherwise({
redirectTo: '/main'
})
}
]);
rootCave.controller('MainCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('ContactCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('DemoCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('LOBCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('MobAppCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('MobileAppsCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
rootCave.controller('ProductCtrl', ['$scope',
function($scope) {
'use strict';
}
]);
<!DOCTYPE html>
<html lang="en" ng-app="rootCave">
<head>
<!-- meta tags -->
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- meta tags -->
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[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]-->
<!---- title ---->
<title>RootCave| Software House</title>
<!---- title ---->
<!---- syles ---->
<link rel="stylesheet" href="assets/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="assets/fonts/flaticon/flaticon.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css">
<link rel="stylesheet" href="assets/css/style.css">
<link rel="stylesheet" href="assets/css/responsive.css">
<!---- syles ---->
</head>
<body data-ng-controller="aboutCtrl">
<div ng-controller="MainCtrl">
<div ng-view></div>
</div>
<!-- Footer Start-->
<footer class="footer">
<div class="container">
<div class="row">
<div class="col-sm-4">
<div class="footer-box white">
<img class="img-responsive" src="<?php echo $img; ?>Logo_white.png">
<ul class="social">
<li><i class="fa fa-facebook"></i></li>
<li><i class="fa fa-twitter"></i></li>
<li><i class="fa fa-linkedin"></i></li>
<li><i class="fa fa-google-plus"></i></li>
<li><i class="fa fa-youtube-play"></i></li>
</ul>
<div class="copy">
<br>
<p>Copyright # 2015 - RootCave</p>
</div>
</div>
</div>
<div class="col-sm-4 hidden-xs"></div>
<div class="col-sm-4">
<div class="footer-box white">
<h3 class="upper" style="
margin-left: 45px;" >Reach Us </h3>
<ul class="details">
<li><i class="fa fa-map-marker"></i>6 Gamal Salem St., from Mosadak St., Dokki, Egypt.</li>
<li><i class="fa fa-phone"></i>+(20)100 5399 170</li>
<li><i class="fa fa-envelope"></i>info#rootcave.com</li>
</ul>
</div>
</div>
</div>
</div>
</footer>
<!-- JavaScript Files -->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="assets/js/jquery-1.11.3.min.js"></script>
<!-- angular js -->
<script src="assets/js/angular.min.js"></script>
<script src="assets/js/angular-route.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="assets/js/bootstrap.min.js"></script>
<script src="assets/js/typeit.min.js"></script>
<!-- smoth scroll -->
<script src="assets/js/SmoothScroll.js"></script>
<script src="http://maps.googleapis.com/maps/api/js"></script>
<!-- GOOGLE MAP -->
<script type="text/javascript">
// When the window has finished loading create our google map below
google.maps.event.addDomListener(window, 'load', init);
function init() {
// Basic options for a simple Google Map
// For more options see: https://developers.google.com/maps/documentation/javascript/reference#MapOptions
var mapOptions = {
// How zoomed in you want the map to start at (always required)
zoom: 8,
// The latitude and longitude to center the map (always required)
center: new google.maps.LatLng(29.9773051,31.3105241), // New York
// How you would like to style the map.
// This is where you would paste any style found on Snazzy Maps.
};
// Get the HTML DOM element that will contain your map
// We are using a div with id="map" seen below in the <body>
var mapElement = document.getElementById('googleMap');
// Create the Google Map using our element and options defined above
var map = new google.maps.Map(mapElement, mapOptions);
// Let's also add a marker while we're at it
var marker = new google.maps.Marker({
position: new google.maps.LatLng(29.9773051,31.3105241),
map: map,
title: 'Snazzy!'
});
}
</script>
<script>
$(".nav li a").click(function() {
$('html, body').animate({
scrollTop: $($.attr(this, 'href')).offset().top
}, 2000);
});
</script>
<script>
$(window).load(
function () {
$(".loading").fadeOut(2000, function () {
$(this).parent().fadeOut(2000);
});
}
);
/*--
auto typing plugin
--*/
$('.typing').typeIt({
strings: [
"Tailored to suit your business ",
"Cloud based Software for your business",
"Real time Analytics for data driven business decisions"
],
speed: 150,
breakLines: false,
loop: true,
cursor: false
});
</script>
<!-- JavaScript Files -->
<script src="assets/js/app.js"></script>
<!-- Footer End-->
</body>
</html>
<!-- Header Start ---->
<header class="header" id="header">
<!-- navigation Start -->
<navigation></navigation>
<!-- navigation End -->
<div class="p-overlay"></div>
<div class="container">
<div class="row">
<div class="col-sm-5">
<div class="header-cont">
<h2 class="typing" style="color: white;"></h2>
<a class="btn btn-primary" href="demo.php">Get Started</a>
</div>
</div>
<div class="col-sm-7">
<div style="padding:25% 0">
<img class="img-responsive" src="assets/img/mockups/responsive1.png">
</div>
</div>
</div>
</div>
</header>
<!-- Header ---->
<section class="aboutme padding white" id=aboutUs>
<div class="overlay"></div>
<div class="container">
<div class="row">
<h1 class="text-center">Root Cave at a glance</h1>
<p class="text-center" style="width:60%; margin: auto;">
Root Cave delivers a business application suite for small and medium size companies around the world. , our flexible solutions help you accelerate your business growth. That flexibility allows you to choose to implement the suite on your existing servers or move to a modern cloud implementation. Explore these pages to see why we are now the fastest growing business management solution!
</p>
<br><br>
</div>
<div class="row" ng-repeat="items in about track by $index" ng-if="$index % 2 == 0">
<div class="col-sm-6"
ng-repeat="i in [$index, $index + 1]"
ng-if="about[i]"
>
<div class="about-box">
<div class="col-xs-3">
<i class="{{about[i].icon}}"></i>
</div>
<div class="col-xs-9">
<h3>
{{about[i].title}}
</h3>
<p>
{{about[i].description}}
</p>
</div
</div>
</div>
</div>
</div>
</section>
<section class="green-l padding">
<div class="container">
<div class="row">
<div class="col-sm-6">
<div class="l-box">
<h3 class="white">Web App</h3>
<p class="white">
Lorem ipsum dolor sit amet, perfecto accusata ad qui, amet adhuc everti ut pri. Recusabo periculis patrioque an duo. Suas alienum eos at, at nibh soleat nostrud mel. Eu eam alii sanctus sadipscing, eos nusquam voluptaria et, nominati volutpat maiestatis has ei.
Lorem ipsum dolor sit amet, perfecto accusata ad qui, amet adhuc everti ut pri. Recusabo periculis patrioque an duo. Suas alienum eos at, at nibh soleat nostrud mel. Eu eam alii sanctus sadipscing, eos nusquam voluptaria et, nominati volutpat maiestatis has ei.
</p>
<a class="btn btn-primary" href="/line-of-business">Get Started</a>
</div>
</div>
<div class="col-sm-6">
<div class="l-box">
<img class="img-responsive" ng-src="assets/img/PcColl.png">
</div>
</div>
</div>
</div>
</section>
<section class="mobile padding">
<div class="container">
<div class="row">
<div class="col-sm-6">
<h3>Mobile App</h3>
<p>
Mobile devices are increasingly utilized to access content and interact with brands. So, it is critical that you have a well-designed and solidly executed mobile experience. Root Cave provides clients with brand consistency through and throughout customized mobile websites and applications.
</p>
Get Started
</div>
<div class="col-sm-6">
</div>
</div>
</div>
</section>
<section class='clients padding text-center' id="customers">
<div class="container">
<div class="row" >
<!-- <h1 class="text-center">Customers</h1> -->
</div>
<div class="row" ng-repeat="client in clients track by $index" ng-if="$index % 4 == 0">
<div class="col-sm-3" ng-repeat="i in [$index,$index +1,$index + 2 , $index + 3]"
ng-if="clients[i]">
<img class="img-responsive" ng-src="assets/img/clients/{{clients[i].clientLogo}} " >
</div>
</div>
</div>
</section>
<!-- navigation Start -->
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
<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="#">
<img alt="Brand" src="assets/img/Logo.png">
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>home</li>
<li>about us</li>
<li class="dropdown">
Products <span class="caret"></span>
<ul class="dropdown-menu">
<li>Line Of Business App</li>
<li>Mobile App</li>
</ul>
</li>
<li>customers</li>
<li>contact us</li>
<li class="hidden-md hidden-sm hidden-xs" style="font-size: 35px;color:#696969;margin-top: 15px;">|</li>
<li>Demo</li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!-- navigation End -->
Could it be as simple as having your directive restricted to attribute:
rootCave.directive('navigation', [
function() {
'use strict';
return {
restrict: "A", <-- here you are restricting your directive to attribute
templateUrl: 'directives/nav.html'
};
}
]);
And you are using it as an element:
<!-- navigation Start -->
<navigation></navigation> <-- here you are using it as an element
<!-- navigation End -->
I'm trying to load a form using foundation's reveal modal, i need to run a angular controller inside the form to enable the form submission using ajax and not the default post/refresh behaviour.
this is my main view:
<html lang="es" ng-app="crm">
<body>
<script>
var crmapp = angular.module('crm', ['ng.django.forms',"ui.select"]);
</script>
<a data-reveal-id="idmodal" class="fi-burst" data-reveal-ajax="true" href="/operador/clientes/saldos/anadir/13">Añadir Pago</a>
<div id="idmodal" class="reveal-modal" data-reveal aria-labelledby="modalTitle" aria-hidden="false">
</div>
</body>
and this is my form:
<div class="row" ng-controller="dummy">
<h2>Añadir Pago</h2>
<ng-form>
<label>Fecha de Cobro:</label>
<label>Valor:</label>
<div class="row">
<div class="columns small-offset-5 small-7">
<button class="buttons success round" ng-click="alert(5)">Añadir</button>
</div>
</div>
</ng-form>
</div>
<script>
crmapp.controller('dummy', function($scope) { $scope.greeting = 'Hola!';console.log("bye"); });
</script>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
any "regular" javascript code in the form is called, but the angular controller isnt working. what can i do?
Here is how to work with ng-click and controller:
JSFiddle
HTML:
<div ng-app="myApp">
<div class="row" ng-controller="dummy">
<h2>Añadir Pago</h2>
<ng-form>
<label>Fecha de Cobro:</label>
<label>Valor:</label>
<div class="row">
<div class="columns small-offset-5 small-7">
<button class="buttons success round" ng-click="greeting()">Añadir</button>
</div>
</div>
</ng-form>
</div>
<a class="close-reveal-modal" aria-label="Close">×</a>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', function ($scope) {
$scope.greeting = function () {
console.log("bye");
};
}]);
Problem
I'm using foundation for Apps to create an Angular app. I'm having trouble with using ng-repeat to get the data I want to be presented from the object into the template home.html. Instead of getting the data, I see an error message in the console, which gives me {{business.name}} as opposed to the actually data.
Error message
Error: [ng:areq] Argument 'MainCtrl' is not a function, got undefined
I've included my Github repo below:
Link:: https://github.com/onlyandrewn/angular
app.js
(function() {
'use strict';
angular.module('application', [
'ui.router',
'ngAnimate',
//foundation
'foundation',
'foundation.dynamicRouting',
'foundation.dynamicRouting.animations'
])
.config(config)
.run(run)
;
var myApp = angular.module('myApp',[]);
myApp.controller('MainCtrl', function($scope) {
$scope.businesses = [{
id: 0,
name: "Andrew Nguyen",
description: "I'm a web developer",
address: "322 11th Street, Brandon, MB",
website: "http://andrewnguyen.ca"
},
{
id: 1,
name: "Mary Yacoubian",
description: "I'm a dental hygenist",
address: "18 Wishford Drive",
website: "http://quitecontrary.com"
},
{
id: 2,
name: "John Axon",
description: "I'm a jack of all trades",
address: "1101 Mississauga Rd.",
website: "http://johnaxon.com"
}];
});
config.$inject = ['$urlRouterProvider', '$locationProvider'];
function config($urlProvider, $locationProvider) {
$urlProvider.otherwise('/');
$locationProvider.html5Mode({
enabled:false,
requireBase: false
});
$locationProvider.hashPrefix('!');
}
function run() {
FastClick.attach(document.body);
}
})();
index.html (ng-app="application") lives here
<!doctype html>
<html lang="en" ng-app="application">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Brandon Sun Business Directory</title>
<link href="/assets/css/app.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="grid-frame vertical">
<div class="grid-content shrink" style="padding: 0;">
<div class="primary condense menu-bar">
<div class="logo">
<img src="http://placehold.it/80x45" class="bdnsun" alt="">
<div class="social">
<i class="fa fa-twitter"></i>
<i class="fa fa-facebook"></i>
</div><!-- /.social -->
</div><!-- /.logo -->
</div>
</div>
<div ui-view class="grid-content">
</div>
</div>
<script src="/assets/js/foundation.js"></script>
<script src="/assets/js/templates.js"></script>
<script src="/assets/js/routes.js"></script>
<script src="/assets/js/app.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.isotope/2.2.0/isotope.pkgd.js"></script>
</body>
</html>
home.html (ng-controller="MainCtrl) lives here
---
name: home
url: /
---
<div class="grid-container">
<div class="hero">
<p class="sponsor">Sponsored by </p>
<img src="http://placehold.it/200x30" class="sponsors" alt="">
<h1>Business Directory</h1>
<div class="find">
<label for="looking">
<i class="fa fa-search"></i>
</label>
<input type="search" id="looking" placeholder="What are you looking for?">
<input type="submit">
</div><!-- /.find -->
<ul>
<li class="popular">Popular searches:</li>
<li>tk-category <span>|</li>
<li>tk-category <span>|</span></li>
<li>tk-category <span>|</span></li>
<li>tk-category <span>|</span></li>
<li>tk-category </li>
</ul>
</div><!-- /.hero -->
<div class="businesses">
<p class="number">tk-number of businesses</p><button class="filter button">Filter by <i class="fa fa-chevron-down"></i></button>
<div class="options">
<div class="cat">
<div class="categories">
<div class="group">
<p class="name">Grade Level</p>
<div class="check">
<input type="radio" name=""><p>Auto</p>
<input type="checkbox" name=""><p>Restaurant</p>
<input type="checkbox" name=""><p>Other</p>
</div><!-- /.check -->
</div><!-- /.group -->
<div class="group">
<p class="name">School Type</p>
<div class="check">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
<input type="checkbox">
</div><!-- /.check -->
</div><!-- /.group -->
</div><!-- /.categories -->
</div><!-- /.cat -->
</div><!-- /.options -->
</div><!-- /.businesses -->
<div class="buttons">
<button class="alp">Alphabetically</button>
<button class="exp">Expanded</button>
<button class="con">Condensed</button>
</div><!-- /.buttons -->
<div class="grid-block small-up-3" ng-controller="MainCtrl">
<div class="grid-block">
<img src="http://placehold.it/300x300" class="storefront" alt="">
<p class="name">{{business.name}}</p>
<p class="description">{{business.description}}</p>
<p class="address">{{business.address}}</p>
{{business.website}}
</div>
<div class="grid-block">
<img src="http://placehold.it/300x300" class="storefront" alt="">
<p class="name">{{business.name}}</p>
<p class="description">{{business.description}}</p>
<p class="address">{{business.address}}</p>
{{business.website}}
</div>
<div class="grid-block">
<img src="http://placehold.it/300x300" class="storefront" alt="">
<p class="name">{{business.name}}</p>
<p class="description">{{business.description}}</p>
<p class="address">{{business.address}}</p>
{{business.website}}
</div>
</div>
</div>
There is no "MainCtrl" in the Angular app called "application".
You have defined MainCtrl to be a part of MyApp. Was this a copy/paste error?
// Markup
ng-app="application">
...
ng-controller="MainCtrl">
// JavaScript
var myApp = angular.module('myApp',[]);
myApp.controller('MainCtrl', function($scope) {
I'm new to AngularJS and i don't know whether i'm doing things here right. I have a welcome and a login page. I would like to be able to login on the login page and then be logged on any page of my application. I'm aware that localStorage or cookies would be better than the service to store session data, but i wanted to try this out. When I connect the user using my service in the login partial view, the session variables of the controllers aren't updated. Why?
I guess the issue is quite simple to fix and due to the fact that i missed something.
Thank you in advance for your time.
Harald
Here comes the code:
Template html:
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>Yahoo 2014 - Welcome</title>
<link rel="icon" type="image/png" href="img/favicon.png">
<link rel="stylesheet" href="css/app.css">
<link rel="stylesheet" href="css/bootstrap.css">
<link rel="stylesheet" href="css/animations.css">
<link rel="stylesheet" href="css/template.css">
<script src="lib/jquery/jquery-1.10.2.js"></script>
</head>
<body ng-controller="AppCtrl">
<header>
<nav role="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="navbar-header">
<button type="button" data-toggle="collapse" data-target=".navbar-collapse" class="navbar-toggle"><span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span></button><img src="img/logo.png" alt="Yahoo logo" class="img-responsive navbar-brand"/>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li>Groupe</li>
<li>Services</li>
<li>Logiciels</li>
<li>Secteurs</li>
<li>Rejoignez-nous</li>
<li>Investisseurs</li>
<li>English version</li>
<li ng-hide="connected" >Login</li>
<li ng-hide="!connected"> </li>
</ul>
</div>
</div>
</div>
</div>
</nav>
</header>
<div ng-view></div>
{{connected}}
{{username}}
<footer>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12">
<ul class="nav navbar-nav">
<li>Mentions légales</li>
<li>Plan du site</li>
<li>Contacter l'administrateur</li>
</ul>
</div>
</div>
<div class="row">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<p>© Copyright Yahoo 2014</p>
</div>
</div>
</div>
</nav>
</footer>
<!-- In production use:
<script src="//ajax.googleapis.com/ajax/libs/angularjs/x.x.x/angular.min.js"></script>
-->
<script src="../bower_components/angular/angular.js"></script>
<script src="../bower_components/angular-route/angular-route.js"></script>
<script src="lib/angular/angular-animate.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="lib/bootstrap/bootstrap.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
</body>
</html>
Index.html partial view
<div id="content">
<div class="container-fluid">
<div class="row">
<div class="col xs-12 col-sm-12 col-md-12 col-lg-12"><a id="bannerlink" href="http://www.yahoo.com"><img id="bannerimage" src="img/slider-mobile1.jpg" alt="Banner image" class="img-responsive"></a></div>
</div>
<div class="row">
<div class="articles" ng-repeat="article in articles">
<div class="col xs-4 col-sm-4 col-md-4 col-lg-4">
<h3>{{article.title}}</h3>
<p>{{article.content}}</p>
</div>
</div>
</div>
</div>
</div>
Login html partial view:
<div id="content" ng-controller="LoginCtrl">
<form name="login" action="#" ng-submit="login()">
<table>
<tr>
<td>
<p>Nickname</p>
</td>
<td>
<input type="text" name="nickname" ng-model="nickname" required>
</td>
</tr>
<tr>
<td>
<p>Password</p>
</td>
<td>
<input type="password" name="password" ng-model="password" required>
</td>
</tr>
</table>
<input type="submit" id="submit" value="Submit">
</form>
</div>
App.js:
'use strict';
// Declare app level module which depends on filters, and services
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/index', {templateUrl: 'partials/index.html', controller: 'IndexCtrl'});
$routeProvider.when('/group', {templateUrl: 'partials/group.html', controller: 'GroupCtrl'});
$routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'LoginCtrl'});
$routeProvider.otherwise({redirectTo: '/index'});
}]);
Controllers:
'use strict';
/* Controllers */
angular.module('myApp.controllers', [])
.controller('AppCtrl', ['$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.username="Harald";
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
scope.$watch('connected', function(){
alert("Connected changed!");
});
}])
.controller('IndexCtrl', [ '$scope', 'Article', function(scope, Article) {
scope.articles = Article.query();
}])
.controller('GroupCtrl', [function() {
}])
.controller('LoginCtrl', [ '$scope', 'Session', function(scope, Session) {
scope.connected=Session.isConnected();
scope.login = Session.connect();
scope.disconnect = Session.disconnect();
}]);
Services:
'use strict';
/* Services */
// Demonstrate how to register services
// In this case it is a simple value service.
var myAppServices = angular.module('myApp.services', ['ngResource']).
value('version', '0.1');
myAppServices
.factory('Article', ['$resource',
function(resource){
return resource('articles/:articleId.json', {}, {
query: {method:'GET', params:{articleId:'articles'}, isArray:true}
});
}])
.factory('Session', function() {
var connected = false;
var nickname = "unknown";
return{
isConnected : function() {
return connected;
},
getNickname : function() {
return nickname;
},
connect : function() {
connected = true;
window.alert("Connected service!");
},
disconnect : function() {
connected = false;
}
}
});
isConnected() returns a boolean. When you change connected in your service, you assign it a new value, but that won't affect $scope.connected
You could keep the two in sync by using a watch function:
scope.$watch(Session.isConnected, function(connected){
$scope.connected = connected;
});
From what i understand and correct me if i am wrong. you want to store state in a service and check that state when route changes to see if the user is logged in or not without the use of cookies or local storage. However storing user state in just a service will not work as if the user hits refresh button the service will be undefined and no longer valid.