I have a signup template/view written using ionic framework but whenever I submit the Signup form the value of ng-model $scope.account remains Undefined. According to me the main reason for this is that I am not able add controller name (SingupController) in signup.html. Whenever I add ng-controller="SingupController" and run the app browser get closed with a message "Unable to attache. Operation is timeout"
I am using Visual Studio 2013, AngularJS, Ionic and Adobe PhoneGap.
Here is a is the code which I am using.
singup.html:
<ion-header-bar>
<button class="button" ng-click="closeSignup()">Cancel</button>
<h1 class="title">Sign up</h1>
</ion-header-bar>
<ion-content ng-controller="SignupController">
<form ng-submit="doSignup()">
<div class="list list-inset">
<label class="item item-input">
<input type="text" placeholder="First Name" ng-model="account.firstName">
</label>
<label class="item item-input">
<input type="text" placeholder="Last Name" ng-model="account.lastName">
</label>
<label class="item item-input">
<input type="email" placeholder="Email" ng-model="account.email">
</label>
<label class="item item-input">
<input type="text" placeholder="School" ng-model="account.school">
</label>
<label class="item item-input">
<input type="text" placeholder="Country" ng-model="account.country">
</label>
</div>
<div class="list list-inset">
<label class="item item-input">
<input type="password" placeholder="Password" ng-model="account.password">
</label>
<label class="item item-input">
<input type="password" placeholder="Confirm Password" ng-model="account.confirmPassword">
</label>
<p>Minimum 8 characters a-Z, 0-9</p>
</div>
<label class="item">
<input type="submit" class="button button-block button-balanced" value="Sign up" />
</label>
</form>
</ion-content>
And my controller code in controller.js is as follows:
angular.module('angularApp.controllers', [])
.controller('SignupController', ['$scope', '$ionicModal', '$timeout', '$http', function ($scope, $ionicModal, $timeout, $http) {
// Form data for the login modal
$scope.account = {};
// Create the signup modal that we will use later
$ionicModal.fromTemplateUrl('templates/signup.html', {
scope: $scope
}).then(function (modal) {
$scope.modal = modal;
});
// Triggered in the signup modal to close it
$scope.closeSignup = function () {
$scope.modal.hide();
};
// Open the signup modal
$scope.signup = function () {
$scope.modal.show();
};
$scope.doSignup = function () {
var config = {
method: "POST",
url: "http://localhost:60923/api/account/",
data: $scope.account
};
$http(config).success(function (data) {
$scope.mydate = data;
});
};
}])
Index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/main.css" rel="stylesheet" />
<link href="css/app-overrides.css" rel="stylesheet" />
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<script src="scripts/platformOverrides.js"></script>
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="scripts/ng-cordova.min.js"></script>
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="scripts/app.js"></script>
<script src="scripts/controllers.js"></script>
</head>
<body ng-app="angularApp">
<ion-nav-view></ion-nav-view>
</body>
</html>
I am really not sure where the problem is? Please advice me if you see any problem inside my code. Thanks in advance.
In your controller simply add $scope.account = { } to the initialization code. The issue is almost certainly that the account is being dynamically defined on a child scope. I can't prove that because I don't see the resulting HTML in the post, but I've seen this many times before.
Related
I am using Angularjs 1 in my project.i am validating the form inside angular,so i am using form.$valid to check the form submitted is valid or not,but it is not working properly,not sure what i am missing
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<title> Learning AngularJS Filters </title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
<script>
"use strict";
angular.module("myApp",[]);
angular.module("myApp").controller("SampleController",[function(){
this.user = {}
this.submitForm = function(form){
if(form.$valid){
window.alert("Valid")
}else{
window.alert("In Valid");
}
}
}]);
</script>
</head>
<body>
<div ng-controller="SampleController as sm" class="container">
<form name="sampleForm" novalidate>
<div class="form-group">
<label for="exampleInputEmail1"> Username </label>
<input type="text" class="form-control" ng-model="sm.user.name" id="exampleInputEmail1" placeholder="Enter Username" required>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" ng-model="sm.user.pwd" id="exampleInputPassword1" placeholder="Password" required>
</div>
<button type="submit" ng-click="sm.submitForm('sampleForm')" class="btn btn-primary">Submit</button>
<p> {{ sm.user }} </p>
</form>
</div> <!--/ container -->
</body>
</html>
I am always getting the alert message from the else part which states form invalid
Form directive is bounded to scope, so you need to write it as $scope.sampleForm.$valid. Since your name is dynamic, you can use a bracket notation: $scope[form].$valid. But either way you need to inject $scope into your controller.
Here is a demo:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<title> Learning AngularJS Filters </title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.2/angular.min.js"></script>
<script>
"use strict";
angular.module("myApp", []);
angular.module("myApp").controller("SampleController", ['$scope', function($scope) {
this.user = {}
this.submitForm = function(form) {
if ($scope[form].$valid) {
window.alert("Valid")
} else {
window.alert("In Valid");
}
}
}]);
</script>
</head>
<body>
<div ng-controller="SampleController as sm" class="container">
<form name="sampleForm" novalidate>
<div class="form-group">
<label for="exampleInputEmail1"> Username </label>
<input type="text" class="form-control" ng-model="sm.user.name" id="exampleInputEmail1" placeholder="Enter Username" required>
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" ng-model="sm.user.pwd" id="exampleInputPassword1" placeholder="Password" required>
</div>
<button type="submit" ng-click="sm.submitForm('sampleForm')" class="btn btn-primary">Submit</button>
<p> {{ sm.user }} </p>
</form>
</div>
<!--/ container -->
</body>
</html>
You are passing form as a string in ng-click method not a form Object.So u have to pass the form object without Single-cotts.
ng-click="sm.submitForm('sampleForm')" to ng-click="sm.submitForm(sampleForm)"
Here Is My Angular controller where I am getting the list of value
$scope.Trucks=result.data.Trucks;
Below is the html
<div class="form-group col-md-5">
<label for="name" class="col-sm-5">Truck Number </label>
<div class="input-group">
<div class="input-group-addon"><i class="fa fa-user fa-fw"></i></div>
<input style="max-width: 600px !important;" class="form-control required" ng-model="Trucknumber" type="text" placeholder="Truck Number" id="trucknumber"/>
</div>
</div>
Do google with keyword: "angucomplete"
And create an element like this:
<angucomplete id="ex1"
placeholder="Search trucks"
pause="100"
selectedobject="Trucknumber"
localdata="Trucks"
searchfields="yourfieldname"
titlefield="yourfieldname"
minlength="2"
inputclass="form-control form-control-small"/>
Here,I made working demo for autocomplete search as you want please check below link:
codepen.io
HTML
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title>Truck Number</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1/themes/flick/jquery-ui.css" rel="stylesheet" />
</head>
<body>
<div class="form-group col-md-5" ng-app="autoSearch"
ng-controller="autoSearch">
<label for="name" class="col-sm-5">Truck Number </label>
<div class="input-group">
<div class="input-group-addon">
<i class="fa fa-user fa-fw"></i>
</div>
<input style="max-width: 600px !important;"
class="form-control required" type="text" placeholder="Truck Number"
id="searchLocation" auto-complete ui-items="number"
ng-model="selected" />
</div>
</div>
</body>
</html>
Angular JS:
var app = angular.module('autoSearch', []);
app.controller('autoSearch', function($scope) {
$scope.number = ['2122','2322','4343','32323','43434'];
}).directive('autoComplete', function($timeout) {
return function(scope, iElement, iAttrs) {
iElement.autocomplete({
source: scope[iAttrs.uiItems],
minLength:2,
select: function(e, ui) {
$timeout(function() {
scope.selected = ui.item.value;
}, 100);
}
});
};
});
Please check that code and let me know if you have any query in that.
I hope that will work for you
Thanks.
I am trying to learn AngularJs, I am trying to run a very simple example like below,
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Angular Forms</title>
<!-- LOAD BOOTSTRAP CSS -->
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.2/css/bootstrap.min.css" type="text/css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.min.js"></script>
<script src="js/common.js" type="text/javascript"></script>
</head>
<body ngApp="formApp" ngController="formController">
<div class="container">
<div class="col-md-6 col-md-offset-3">
<!-- PAGE TITLE -->
<div class="page-header">
<h1>Submitting Forms with Angular</h1>
</div>
<!-- SHOW ERROR/SUCCESS MESSAGES -->
<div id="messages"></div>
<!-- FORM -->
<form ngSubmit="process()">
<!-- NAME -->
<div id="name-group" class="form-group">
<label>Name</label>
<input type="text" name="name" class="form-control" placeholder="Bruce Wayne" ngModel="formData.name"/></div>
<!-- SUPERHERO NAME -->
<div id="superhero-group" class="form-group">
<label>Superhero Alias</label>
<input type="text" name="superheroAlias" class="form-control" placeholder="Caped Crusader" ngModel="formData.superhero"/></div>
<!-- SUBMIT BUTTON -->
<button type="submit" class="btn btn-success btn-lg btn-block">Submit!</button>
</form>
</div>
</div>
<script type="text/javascript">
var app = angular.module('formApp',[]);
app.controller('formController', ['$scope','$http', function ($scope, $http) {
console.log("form controller called");
$scope.formData = {};
$scope.process = function() {
console.log("test.php?" + JSON2Params($scope.formData))
$http({method:"GET",
url: "test.php?" + JSON2Params($scope.formData),
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
})
};
}]);
</script>
</body>
</html>
However, I am not getting any indication that angular js is working. For example, I don't see anything logged to console, or application making a http get request that I want to make.
You have a syntax error
Change
From
<body ngApp="formApp" ngController="formController">
To
<body ng-app="formApp" ng-controller="formController">
TOOLS I USE : I am working ionic and I use chrome and ubutu os.
I am trying to do a demo project for data binding please check my plunknr https://plnkr.co/edit/CFSgfWDH5UY0XaDjRoBK?p=preview
Here i am trying to bind the user entered data into the formPost object but in console.log i am getting undefined like({Username: undefined, Name: undefined, EmailID: undefined, Password: undefined}) if some one find any error please let me know
Here is the HTMl
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="app.js"></script>
</head>
<body ng-app="starter">
<ion-pane ng-controller="formValidation">
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">User Name</span>
<input type="text" placeholder="John" ng-model="username">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" placeholder="Suhr" ng-model="name">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Email</span>
<input type="text" placeholder="john#suhr.com" ng-model="emailid">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Password</span>
<input type="text" placeholder="john#suhr.com" ng-model="password">
</label>
</div>
<button class="button button-block button-positive" ng-click="submit(username,name,emailid,password)">
sign up
</button>
</ion-content>
</ion-pane>
</body>
</html>
JS
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.controller('formValidation',function($scope,$http){
$scope.submit=function(username,name,emilid,password){
var formPost = {
"Username":username,
"Name":name,
"EmailID":emilid,
"Password":password
};
console.log(formPost);
$http.post("http://aflaree.com/qrcodeservice/Service1.svc/Signupsupervisor",formPost)
.success(function(response){
console.log(response);
})
.error(function(response){
console.log(response);
});
};
});
Working Pluknr
EDIT
In pure Angular ,
the way you showed in Question will be worked you can see this JsFiddle for reference .
But while coming to ionic this may not be working as Expected because
The problem is specific with ion-content because of the way this directive is defined in the Ionic source code. It specifically creates it's own child scope.
.directive('ionContent', [
'$parse',
'$timeout',
'$ionicScrollDelegate',
'$controller',
'$ionicBind',
function($parse, $timeout, $ionicScrollDelegate, $controller, $ionicBind) {
return {
restrict: 'E',
replace: true,
transclude: true,
require: '^?ionNavView',
scope: true,
template:
'<div class="scroll-content">' +
'<div class="scroll"></div>' +
'</div>',
Because of this and the way inheritance works in JavaScript, you cannot use 2 way binding. Basically your $scope.submit is defined in you controller and is just created as a new primitive to the scope of ion-content. It is not copied by reference like an object would be.
Read this article . It's critical in understanding how this all works and overcoming these issues.
First of all you have a typo in your "EmailID":$scope.emilid, it should be $scope.emailid
The issue was with the ng-controller, it should be defined as a child for <ion-content> you can check the code below:
HTML:
<body ng-app="starter">
<ion-pane >
<ion-header-bar class="bar-stable">
<h1 class="title">Ionic Blank Starter</h1>
</ion-header-bar>
<ion-content>
<div ng-controller="formValidation">
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">User Name</span>
<input type="text" placeholder="John" ng-model="username">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" placeholder="Suhr" ng-model="name">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Email</span>
<input type="text" placeholder="john#suhr.com" ng-model="emailid">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Password</span>
<input type="text" placeholder="john#suhr.com" ng-model="password">
</label>
</div>
<button class="button button-block button-positive" ng-click="submit()">
sign up
</button>
</div>
</ion-content>
</ion-pane>
Angular:
var app = angular.module('starter', []);
app.controller('formValidation', function($scope) {
$scope.submit=function(){
var formPost = {
"Username":$scope.username,
"Name":$scope.name,
"EmailID":$scope.emailid,
"Password":$scope.password
};
console.log(formPost);
}
});
The simplest way to bind your data to the HTML template is below:
Template:
<input [(ngModel)]="name">
.ts code:
name:any= "Tanzeel"
So [()] used for two way binding.
I can't use $scope in ionic, it seems that's $scope is not working.
Let's see very simple example :
App.js :
angular.module('TestApp', ['ionic','TestCtrl'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: "/login",
templateUrl: "views/login.html",
controller : "login"
});
$urlRouterProvider.otherwise('/login');
});
Login.js :
angular.module('TestCtrl',[])
.controller('login', function($scope,$rootScope) {
$scope.giveClass = function() {
console.log($scope.email.length);
}
});
Index.html :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="controllers/login.js"></script>
</head>
<body ng-app="TestApp">
<ion-nav-view></ion-nav-view>
</body>
</html>
Login.html :
<ion-view>
<ion-header-bar class="bar-calm">
<h1 class="title" ng-model="test">Login</h1>
</ion-header-bar>
<ion-content>
<form ng-submit="postLogin()" name="loginForm">
<div class="list list-inset">
<label class="item item-input" ng-class="giveClass()">
<i class="icon icon-fixed-width ion-at placeholder-icon"></i>
<input type="email" name="email" ng-model="email" placeholder="Veuillez entrer votre adresse email" required/>
</label>
<label class="item item-input">
<i class="icon ion-key icon-fixed-width placeholder-icon"></i>
<input type="password" name="password" ng-model="password" placeholder="Veuillez entrer votre mot de passe" required/>
</label>
<div class="list">
<label class="item">
<button class="button button-block button-positive" type="submit">Se connecter</button>
</label>
<label class="item">
<button class="button button-block button-royal" type="submit">S'enregistrer</button>
</label>
</div>
</div>
</form>
</ion-content>
</ion-view>
When I execute this application console (console.log(...) in login.js) return
"Cannot read property 'length' of undefined"
It is not sure, where you plan to set your model property email. I mean, the 'email', which you pass to the ng-model in the Login.html:
<ion-view>
...
// here is expected model 'email'
<input type="email" name="email" ng-model="email"
placeholder="Veuillez entrer votre adresse email" required/>
...
In case, that angular won't find it - it will create that, but on the $scope. And the scope will be the first param not the second here Login.js:
.controller('login', function($scope,$rootScope) {
$scope.giveClass = function() {
// here we can expect 'email' to be created for us
// but not on $rootScope
// it will be available on $scope
console.log($rootScope.email.length);
So, that all means:
there is no explict set of the $rootScope.email
nor of the $scope.email
because we used ng-model="email" we can expect, that angular will create such property for us, but on $scope, not on $rootScope
And that all together will end up with
Cannot read property 'length' of undefined
if we use $rootScope.email.length, or even $scope.email.length. Both of these should be init first or checked if they exist:
Solution: the way to go would be to initiate such property test (it is not needed, but we know what is happening). And even better, to use some Model (and have a dot - check more here: Model in a modal window in angularjs is empty)
.controller('login', function($scope,$rootScope) {
$scope.Model = {};
// if possible - init it,
// $scope.Model.email= "init value";
$scope.giveClass = function() {
// if we need user to init that,
// we have to check if that value was set
if($scope.Model.email){
console.log($scope.email.length);
}
}
and the view
ng-model="Model.email"
Thanks to Radim, I need to use a dot in ng-model, as an object ,and input-type="mail" will bound only if email match to regexp
So working example is :
Apps.js:
angular.module('TestApp', ['ionic','TestCtrl'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: "/login",
templateUrl: "views/login.html",
controller : "login"
});
$urlRouterProvider.otherwise('/login');
});
Login.js:
angular.module('TestCtrl',[])
.controller('login', function($scope,$rootScope) {
$scope.Model = {};
$scope.giveClass = function() {
if($scope.Model.email){
console.log($scope.email.length);
}
});
Index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="css/style.css" rel="stylesheet">
<script src="lib/ionic/js/ionic.bundle.js"></script>
<script src="cordova.js"></script>
<script src="js/app.js"></script>
<script src="controllers/login.js"></script>
</head>
<body ng-app="TestApp">
<ion-nav-view></ion-nav-view>
</body>
</html>
Login.html:
<ion-view>
<ion-header-bar class="bar-calm">
<h1 class="title">Login</h1>
</ion-header-bar>
<ion-content>
<form ng-submit="postLogin()" name="loginForm">
<div class="list list-inset">
<label class="item item-input" ng-class="giveClass()">
<i class="icon icon-fixed-width ion-at placeholder-icon"></i>
<input type="text" name="email" ng-model="Model.email" placeholder="Veuillez entrer votre adresse email" required/>
</label>
<label class="item item-input">
<i class="icon ion-key icon-fixed-width placeholder-icon"></i>
<input type="password" name="password" ng-model="password" placeholder="Veuillez entrer votre mot de passe" required/>
</label>
<div class="list">
<label class="item">
<button class="button button-block button-positive" type="submit">Se connecter</button>
</label>
<label class="item">
<button class="button button-block button-royal" type="submit">S'enregistrer</button>
</label>
</div>
</div>
</form>
</ion-content>
</ion-view>