ng-click and ng-submit doesn't work - javascript

i have a angular application with phonegap where i have a login form and login controller.
The problem is that the ng-submit doesn't work. Normaly the submit call the fonction formConnexion() but nothing happens. So, i tried with just a alert, but it's the same result...
After i tried with a ng-click and same result. Then, i wanted try to call a sample variable in the scope in the template ($scope.test) and it doesn't display. And the console.log('salut!!') doesn't dispaly when i am on the login page.
Which made me think that my controller it doesn't associate to the template.
But i have the ng-controller in my div with the good name controller.
Then, i thought that angular it's was worse installing but no because the other directives work (ng-if, ng-src, ...)
So, if you have a idea to solve this problem, I do not mind :)
here the code for the template :
login.html
<div class="row jumbotron" style="margin:10px" ng-controller="LoginCtrl">
<div class="col-lg-8 col-lg-offset-2 col-md-8 col-md-offset-2 col-sm-8 col-sm-offset-2 col-xs-8 col-xs-offset-2">
<h1>{{ test }}</h1>
<form class="form-horizontal" ng-submit="alert('alert')">
<div class="form-group">
<label for="login" class="control-label">Login</label>
<input type="text" name="login" class="form-control" ng-model="formData.login">
</div>
<div class="form-group">
<label for="password" class="control-label">Password</label>
<input type="password" name="password" class="form-control" ng-model="formData.password">
</div>
<button type="submit" class="btn btn-md btn-success">Connexion</button>
</form>
click
<img ng-src="images/accueil.png" class="accueil img-responsive">
</div>
</div>
and here the controller :
login.js
'use strict';
appStat.controller('LoginCtrl', function ($scope, $rootScope, $http, $location) {
console.log("salut!!");
$scope.formData = {};
$scope.test = "test";
$scope.toto = function() { alert('alert'); };
/**
* Connect l'user
*/
$scope.formConnexion = function () {...}
});
and here my app.js :
app.js
'use strict';
var appStat = angular.module('posStatsPhoneGap', [
'ngCookies',
'ngResource',
'ngSanitize',
'ngRoute',
'ngResource',
'ui.bootstrap',
'ngMessages',
'ngAnimate',
'ngAria',
'ngTouch',
'picardy.fontawesome'
])
.config(['$routeProvider', '$compileProvider', function ($routeProvider, $compileProvider) {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|tel):/);
$compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|tel):/);
$routeProvider
.when('/', {
templateUrl: 'views/login.html',
controller: 'LoginCtrl'
})
.when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/stat', {
templateUrl: 'views/stat.html',
controller: 'StatCtrl'
})
.otherwise({
redirectTo: '/'
});
}
]);
Thank you in advance !

Following from my comment Try something like this:
Create a Controller file & a controller within it Create a angular
module within the controller file
Create a controller.js file then create a angular module see code below:
//Within your controller.js file
var myApp = angular.module('myApp', []);
myApp.controller('myController', function($scope, $http){
$scope.Data = "Alert Alert";
// Create a function within the scope of the module
$scope.myFunc = function(){
alert($scope.Data)
};
});
Then within your HTML file call the function on-Click see code below:
Note: Don't forget to add the controller you created into your HTML code. I usually add it in the body tag
<body ng-controller="myController">
<button ng-click="myFunc()">Make Request Button</button>
</body>
See a live example here:
http://plnkr.co/edit/sQ0z7TlyWv5fM5XyfujK?p=preview
Also a note: ng-click is mostly used for any click events you are trying to perform within your angular app but ng-submit is mostly used when working with a HTML form submission.

Use ng-submit in you form as:
<form ng-submit="submit()">
function Ctrl($scope) {
$scope.list = [];
$scope.text = 'hello';
$scope.submit = function () {
if ($scope.text) {
$scope.list.push($scope.text);
$scope.text = '';
}
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div ng-controller="Ctrl">
<form ng-submit="submit()">Enter text and hit enter:
<input type="text" ng-model="text" name="text" />
<input type="submit" id="submit" value="Submit" /> <pre>list={{list}}</pre>
</form>
<button ng-click="submit()">Submit 2</button>
</div>
</div>

I found the error. It was caused by having 2 controllers with the name 'LoginCtrl'. It was a stupid copy/paste error.

I have created one working code for the above question for 4 different type of HTML element, for complete code please follow the below URL -
http://plnkr.co/edit/Tm2Rtbt3xsv4pKzcPQCw?p=preview
<body ng-controller="ExampleController">
<button ng-click="setButton()">set button</button>
<div content="snippetContentFirst"></div>
<div content="snippetContentSecond"></div>
<div content="snippetContentThird"></div>
<div>
<ul content="snippetContentFour"></ul>
</div>
</body>

Related

Angular giving a weird templateURL

I am trying to navigate to another page by using the selected objectID.
Angular Routing,
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider.when('/',{
controller: 'BooksController',
templateUrl: 'views/books.html'
})
.when('/books/details/:id',{
controller: 'BooksController',
templateUrl: 'views/book_details.html'
})
});
Angular Controller:
var myApp = angular.module('myApp');
myApp.controller('BooksController', ['$scope', '$http', '$location', '$routeParams', function($scope, $http, $location, $routeParams){
console.log('BooksController loaded...');
// This To get request all the books: it works fine
$scope.getBooks = function(){
$http.get('/api/books').then(function(response){
$scope.books = response.data;
});
}
// This to get request a book with specific id it works fine
$scope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
}
}]);
And then I have this html page which work also fine accept the button in the page, this button supposed to give me a clean templateUrl to navigate to another html page but it give me weird URL:
<div class="panel panel-default" ng-init="getBooks()">
<div class="panel-heading">
<h3 class="panel-title">Latest Books</h3>
</div>
<div class="panel-body">
<div class="row">
<div ng-repeat="book in books">
<div class="col-md-6">
<div class="col-md-6">
<h4>{{book.title}}</h4>
<p>{{book.description}}</p>
<a class="btn btn-primary" href="#/books/details/{{book._id}}">View Details</a>
</div>
<div class="col-md-6">
<img class="thumbnail" src="{{book.image_url}}">
</div>
</div>
</div>
</div>
</div>
And once I press the button I'm supposed to get a clean url such as:
http://localhost:3000/#!/books/details/599701c1f3da51117535b9ab
but instead I get this url!
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
Seems like you have hashprefix !, then your URL should also have ! after hash(#)
href="#!/books/details/{{book._id}}"
Since Angular 1.6 hashprefix is defaulted to !, you can disable this behavior by setting hashPrefix to ''(blank).
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('');
}
]);
Its because your url is getting converted into codes. %2f means a /.
You need to have this configuration to avoid this behavior of angular
myApp.config(['$locationProvider', function($locationProvider) {
$locationProvider.hashPrefix('');
}]);
You have Prefix in url which is converting into character i.e url encoding.
So you need to fix $locationProvider's hashPrefix property by replacing its value with empty/blank string
$locationProvider.hashPrefix('');

ui-router nested state won't load

This is a pretty standard question, however I can't seem to find a solution in anything online. Below is the router/index.html page I'm using. I'm not getting any errors in the console, however when the url resolves, correctly, to the login page the entire page is blank. Any ideas, looking at the code below, as to what I'm missing?
router
(function(){
'use strict'
var app = angular.module('app.core');
app.config(AppRouter);
AppRouter.$inject = ['$stateProvider', '$urlRouterProvider'];
function AppRouter($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('main', {
url: '/main',
abstract: true,
resolve:{
Config: 'Config',
config: function(Config){
console.log(Config);
return Config;
}
}
})
.state('main.login', {
url: '/login',
templateUrl: 'app/components/login/login.html',
controller: 'LoginController',
controllerAs: 'vm',
reloadOnSearch: false
})
}
})();
index.html
<div class="slide-animation-container">
<div ui-view id="ng-view" class="slide-animation"></div>
{{scrollTo}}
</div>
login.html
<div class="container" ui-view>
<div class="row vertical-center-row">
<form id="loginForm" class="form-signin" style="max-width:300px;" autocomplete="off" ng-if="attemptLogin">
<h2 class="form-signin-heading" style="font-size:22px">Please Sign In</h2>
<div class="input-group">
<span class="input-group-addon"><i class="fa fa-user"></i></span></span>
<input type="text" class="form-control" id="username" placeholder="User Name" ng-model="user.username" required>
</div>
</form>
</div>
</div>
EDIT
The router above resides in my config.js file for my core module:
core.module.js
(function(){
'use strict'
angular.module('app.core', ['angulartics', 'angulartics.google.analytics', 'angulartics.scroll', 'ngRoute', 'ngAnimate', 'ng.deviceDetector', 'ui.router',
'ui.bootstrap', 'ngTable', 'ngSanitize', 'ngCsv', 'toastr', 'angular.chosen', 'rzModule', 'publicServices']);
})();
Your otherwise logic changes the url to /login when no states match.
$urlRouterProvider.otherwise('/login');
However, your state definitions do not have a url that matches /login.
Because main.login is a child of main, it inherits the URL from main.
Therefore, you should use the full URL for main.login in your otherwise() call.
$urlRouterProvider.otherwise('/main/login');
Your module should have injected ui.router as a dependency ,
var app = angular.module('app',['ui.router']);
DEMO

How do I refresh my ng-repeat?

I have a controller (called "catalogueController") that manages my search box and my search page. I have the controller initially set the page to automatically call the search function defined in "catalogueController" when the app loads to pre-load my array of items (called Inventory) to be repeated via ng-repeat in the page.
The process runs like this:
1. I submit the search form.
2. "catalogueController" will send the search term to my factory (called "Search").
3. "Search" will have a function which will make a server call to query my database for that particular search.
4. The database will send the results of the search to the "Search" factory.
5. The "Search" factory will send the results to the "catalogueController" controller.
6. "catalogueController" will update the $scope.Inventory to be equal to the new result that I was received.
My problem is that ng-repeat does not refresh itself to display my new and updated $scope.Inventory array. $scope.Inventory definitely is updated (I have made sure of this through various console logs).
I have also tried to use $scope.$apply(). It did not work for me.
Thank you in advance for your help!
Here is my code:
HTML Template
<form role="search" class="navbar-form navbar-left" ng-controller="catalogueController" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<main ng-view></main>
catalogue.html partial
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
"app.js" Angular App
var myApp = angular.module('qcbApp', ['ngRoute', 'ngCookies', 'appControllers']);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/login', {
templateUrl: 'html/partials/login.html',
controller: 'registrationController'
}).
when('/sign-up', {
templateUrl: 'html/partials/sign-up.html',
controller: 'registrationController'
}).
when('/catalogue', {
templateUrl: 'html/partials/catalogue.html',
controller: 'catalogueController'
}).
when('/', {
templateUrl: 'html/partials/qcbhome.html'
}).
otherwise({
redirectTo: '/'
});
}]);
"catalogueController" Controller
myApp.controller('catalogueController', ['$scope', 'Search', function($scope, Search) {
var time = 0;
var searchCatalogue = function(search) {
$scope.inventory = null;
console.log("Controller -- "+search);
Search.searchCatalogue(search)
.then(function(results) {
console.log(results);
$scope.inventory = results;
});
};
if(time == 0)
{
searchCatalogue('');
time++;
}
$scope.search = function(term) {
searchCatalogue(term);
}
}]);
"Search" Factory
myApp.factory('Search', ['$http', '$q', function($http, $q) {
function searchCatalogue(term) {
var deferred = $q.defer();
console.log("Factory -- "+term);
$http.post('/catalogue_data', {term: term}, {headers: {'Content-Type': 'application/json'}})
.success(function(result) {
console.log(result[0].SKU);
deferred.resolve(result);
console.log("Factory results -- "+result);
});
return deferred.promise;
}
return {
searchCatalogue: searchCatalogue
}; //return
}]);
I think the problem is the ng-repeat can not access the inventory in scope. You have to create a div which contains both the form and the ng-repeat.
The html should be:
<div ng-controller="catalogueController">
<!-- Move the controller from the form to parent div -->
<form role="search" class="navbar-form navbar-left" ng-submit="search(search_term)">
<div class="form-group">
<input type="text" placeholder="Search" class="form-control" ng-model="search_term">
</div>
<button type="submit" class="btn btn-default">Search</button>
</form>
<div id="main" class="margin-top-50 clearfix container">
<div ng-repeat="items in inventory" class="row-fluid">
<div class="col-sm-6 col-md-3">
<div class="thumbnail"><img src="image.jpg" alt="..." class="col-md-12">
<div class="caption">
<h3>{{ items.itemName }}</h3>
<p>{{ items.description }}</p>
<p>Buy <a href="#" role="button" class="btn btn-default">More Info</a></p>
</div>
</div>
</div>
</div>
</div>
I've seen the situation a few times where when you are updating a property directly on the $scope object there are interesting problems around databinding to that value (such as inventory). However if you databind to an object property of an object then the databinding works as expected. So for example use a property on $scope. I believe this is a copy by value vs copy by reference issue.
Update all your inventory references as follows
$scope.data.inventory = result;
Also don't forget to update your inventory reference in the html template:
<div ng-repeat="items in data.inventory" class="row-fluid">
Update: I made this plunk to figure it out - http://plnkr.co/edit/0ZLagR?p=preview
I think the primary problem is you have the controller specified twice. I removed it from the form and it started working.

Argument controller is not function, got undefined at Error

I'm using AngularJS + Laravel for my web-application. AngularJS install in public/app folder, the view for my web-application is not from public/app, is from Laravel/app/view folder.
-views
--web-app
---partials
---chat-rooms.blade.php
--index.blade.php
Index.blade.php
<body ng-app='chatApp'>
<div class="page-header">
<h1> Chat application </h1>
</div>
<div ng-view class="container"></div>
{{ HTML::script('app/libs/angular/angular.min.js')}}
{{ HTML::script('app/libs/angular-route/angular-route.min.js')}}
{{ HTML::script('app/scripts/app.js')}}
{{ HTML::script('app/scripts/controllers/chat-rooms.js')}}
</body>
Chat-rooms.blade.php
<div class="row">
<div class="col-md-12">
<select class="form-control" ng-model="selectedChatRoom" ng-options="chatRoom.name for chatRoom in chatRooms">
</select>
<button type="button" ng-click="selectChatRoom(selectedChatRoom)">Select chat room</button>
</div>
<div class="col-md-12">
<input type="text" class="form-control" ng-model="chatRoom.name" placeholder="Enter chat room name">
<button type="button" ng-click="createChatRoom(chatRoom)">Create</button>
</div>
My app.js is from public/app folder :
'use strict';
angular.module('chatApp', ['ngRoute'])
.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'partials/chat-rooms',
controller: 'ChatRoomsCtrl'
})
.when('/chat-room/:chatRoom', {
templateUrl: 'partials/chat-room.html',
controller: 'ChatRoomCtrl'
});
});
The problem now is "ChatRoomsCtrl" cause this problem, the function is undefined.
Here's the js:
'use strict';
angular.module('chatApp')
.controller('ChatRoomsCtrl', function($scope, ChatRoom, $location) {
var chatRoomsLoaded = function(chatRooms) {
$scope.chatRooms = chatRooms;
}
var handleErrors = function(response) {
console.error(response);
}
$scope.selectChatRoom = function(chatRoom) {
$location.path('chat-room/' + chatRoom.id);
}
$scope.createChatRoom = function(chatRoom) {
ChatRoom.create(chatRoom).then($scope.selectChatRoom);
}
ChatRoom.getAll()
.then(chatRoomsLoaded)
.catch(handleErrors);
});
Again, everything seems work, the front-end can work, but the backends couldn't. The create button "ng-click" doesn't toggle at all. Seems like controller is causing this.
Part of my index.blade.php is actually put inside my video template.
My video template consist of videoController and route...
VideoController
public function getChatRoom()
{
return View::make('chat-app.partials.chat-rooms');
}
Route
Route::get('video/{slug}', array(
'as' => 'showVideo',
'uses' => 'VideoController#show'
));
Route::get('video/partials/chat-rooms', array(
'uses' => 'VideoController#getChatRoom'
));
When I load the chat-rooms, the web address must be video/partials/chat-rooms.. Currently I'm surfing the video template, part of it was chat-app, the web address is video/{slug}/ which slug could be any name...
ERROR : Click here to view the error

NgRoute is not working in jsfiddle

I'm new to angular and I'm about to write my first hello world App in jsfiddlle.
I managed to load content by using ng-include but I still have problem with using ngRoute:
I'm getting
Cannot read property 'insertBefore' of undefined
in the following code:
HTML
<div ng-app="myApp">
1Panel
2Panel
<div ng-include src="'main.html'"><div>
<div ng-view></div>
<script type="text/ng-template" id="first_panel.html">
First Panel
</script>
<script type="text/ng-template" id="second_panel.html">
Second Panel
</script>
<script type="text/ng-template" id="main.html">
<div ng-controller="MainCtrl as mainCtrl">
Main {{mainCtrl.foo}} <br/>
<input type="text" ng-model="mainCtrl.foo"/>
<br/>
</div>
</script>
</div>
JS
var myApp = angular.module('myApp', ['ngRoute']);
var my = {};
my.MainCtrl = function() {
this.foo = 'foo';
}
my.SecondPanelCtrl = function() {
}
my.FirstPanelCtrl = function() {
}
var routeProvider = function($routeProvider) {
$routeProvider.
when('/firstPanel', {
templateUrl: 'first_panel.html',
controller: 'FirstPanelCtrl',
controllerAs: 'firstPanelCtrl'
}).
when('/secondPanel', {
templateUrl: 'second_panel.html',
controller: 'SecondPanelCtrl',
controllerAs: 'secondPanelCtrl'
}).
otherwise({redirectTo: '/firstPanel'});
};
myApp.config(routeProvider);
// register all controllers
myApp.controller('MainCtrl', my.MainCtrl);
myApp.controller('FirstPanelCtrl', my.FirstPanelCtrl);
myApp.controller('SecondPanelCtrl', my.SecondPanelCtrl);
And here is my jsfiddle:
http://jsfiddle.net/ccTd6/14/
It is an error in your HTML syntax that messes things up:
<div ng-include src="'main.html'"></div>
^
here you missed the `/`__|
Note:
At least in Chrome that I tried that, it is the browser that gets confused and removes the ngView div altogether - so it is not Angular's fault in any case.

Categories