Pass data from angular form to another controller - javascript

I am new to angularjs. I want to pass data from html form to another route.
Here is the part of index.html
<div ng-app="myApp" ng-controller="HomeController">
<div class="container">
<div class="row">
<div class="col-md-12">
<div ng-view=""></div>
</div>
</div>
</div>
</div>
Here are the routes
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'views/home.html',
controller: 'HomeController'
});
$routeProvider.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutController'
});
}]);
When the route is / it hits the views/home.html in which it has a form
<form action="#/about" ng-submit="submitData()">
<input type="text" name="address" ng-model="user.address" />
<input type="submit" />
</form>
I have a user service whose implementation is
myApp.factory("user", function () {
return {};
});
I inject user service in HomeController like
myApp.controller("HomeController", function ($scope, user) {
$scope.user = user;
// and then set values on the object
// $scope.user.address = "1, Mars"; // when uncomment this line it can be accessed on AboutController? Why? Otherwise I cannot access user.address
console.log($scope.user);
});
Don note my comment in above code..
and passes user to AboutController like
myApp.controller("AboutController", function ($scope, user) {
$scope.user = user;
// and then set values on the object
$scope.user.firstname = "John";
$scope.user.secondname = "Smith";
console.log($scope.user);
});
Here is the about.html
<p>
{{ user.address }}
</p>
Problem: {{user.address}} doesn't work on AboutController. I can't see any output... But when i remove the comment from above code.. It only displays hardcoded values in the controller What am I missing?
This is the working demo http://ashoo.com.au/angular/#/

At the moment, all your service does is pass a blank object return {}, to any controller into which it is injected. You need a getter/setter approach, so that in your Home view you can set the data, and in your About view you can retrieve it.
So your service could look something like this:
myApp.factory("user", function () {
var dataObj = {};
return {
setData: function(data) {
dataObj.username = data.username;
},
getData: function() {
return dataObj;
}
};
});
Now you can set the data in your Home controller:
myApp.controller("HomeController", function ($scope, user) {
$scope.submitData = function(data) { //pass in ng-model
user.setData(data); //call 'user' service to set data
}
});
And call it from your About controller:
myApp.controller("AboutController", function ($scope, user) {
$scope.user = user.getData(); //Assign
console.log($scope.user.username);
});
And you html would look like:
<form action="#/about" ng-submit="submitData(user.username)">
<input type="text" name="address" ng-model="user.username" />
<input type="submit" />
</form>

Related

AngularJS Form and $scope not updating each other

I am trying to make a very minimalistic form in AngularJS (version 1).
I am trying to use ng-model and the $scope to update an object I've named fluff. Once a user clicks submit it should be used in this $http call.
I'm highly confused I thought ng-model would bind this to the object in the scope. But it always returns a blank cause the $scope.fluff is not updating.
Yet if I inject {{ fluff.link }} this will update based on the textbox.
Here is my form in the view:
<form name="fluffForm" ng-submit="submitform()">
<span>Link: <input type="text" name="link" ng-model="form.link"></span>
<span>Description: <input type="text" name="description" ng-model="form.desc"></span>
<button type="submit">submit</button>
</form>
</div>
Here is my controller:
(function(){
'use strict';
angular.module('fluff').controller('FormController', FormController);
FormController.$inject = ['$scope', '$rootScope', '$routeParams', '$window', '$http'];
function FormController( $scope, $rootScope, $routeParams, $window, $http){
var form = this;
$scope.fluff = {}; // form data in json object(?) to be posted to mongo database
$scope.submitform = function(){
$scope.fluff.link = form.link;
$scope.fluff.description = form.desc;
console.log('form-data', $scope.fluff);
$http({
method: 'POST',
url: 'http://fluff.link/share',
data: $scope.fluff,
headers: {'Content-type': 'application/x-www-form-urlenconded'}
}).success(function(data){
console.log('Call to API was successful');
if(data.errors){
console.log('Data Errors');
console.log('error:', $data.errors.name);
//show errors - part of the response in the REST API have to make this portion up myself
$scope.errorName = $data.errors.name;
} else {
console.log('returned share id', data);
var fluff = 'fluff/link/'+ data;
$window.location.href = fluff;
}
});
}
}
})();
Here is my route:
(function(){
'use strict';
angular.module('fluff').config(Config);
Config.$inject = ['$routeProvider'];
function Config($routeProvider){
$routeProvider.when('/', {
templateUrl: 'views/index.client.view.html',
controller: 'FormController',
controllerAs: 'form'
});
}
})();
Added some logs from the developer console in chrome:
in submitform FormController {link: "test", desc: "test"}
fluff.form.controller.js:24 form-data Object {link: undefined}
Got it to work! Will update with my answer when it allows!
So my problem here is that I wasn't using the form controller like I should have.
Here I have the template being loaded with the controller as form.
$routeProvider.when('/', {
templateUrl: 'views/index.client.view.html',
controller: 'FormController',
controllerAs: 'form'
});
In the template I have to use form:
<span>Link: <input type="text" name="link" ng-model="form.link"></span>
<span>Description: <input type="text" name="description" ng-model="form.desc"></span>
then in the controller I create a this object:
var vm = this;
vm is now linked to form.
So now I can do this:
var fluff = {};
fluff.link = form.link;
fluff.description = form.desc;
Now fluff has all the data it needs when my user clicks submit.

AngularJS: How to update Variable Values while using Routing

i want to set the flag icon inside the header of my page depending on the selected language, using AngularJS. The language is selected in another .htm-file and its all brought together by AngularJS-routing.
My application uses one controller named "appController". The controller is inserted into the body-tag in "index.html". Inside "index.html" there is a that uses the angular function "setPicUrl()". The value of "appLang" is set by the radio-input in "language.htm", which is inserted into using routing by AngularJS.
The problem is, that the path for the flag icon does not change when i select another language (the variable "appLang" does). The icon is loaded correctly when i start the application.
routing.js
var app = angular.module("angApp", ["ngRoute"]);
app.config(function ($routeProvider) {
$routeProvider
.when("/visualization", {
templateUrl: "htm/visualization.htm",
controller: "appController"
})
.when("/data", {
templateUrl: "htm/data.htm",
controller: "appController"
})
.when("/social", {
templateUrl: "htm/social.htm",
controller: "appController"
})
.when("/about", {
templateUrl: "htm/about.htm",
controller: "appController"
})
.when("/language", {
templateUrl: "htm/language.htm",
controller: "appController"
});
});
controller.js
app.controller("appController", function ($scope, $http, $location) {
$scope.appLang = "english";
$scope.setPicUrl = function () {
if ($scope.appLang === "german") {
return "icons/german.png";
} else if ($scope.appLang === "english") {
return "icons/english.png";
} else {
//TODO Error handling
return;
}
};
index.html
<body ng-app="angApp" ng-controller="appController">
...
<li ng-class="{ active: headerIsActive('/language')}"><a href="#language"><img id="langpic"
ng-src="{{setPicUrl()}}"
class="img-responsive"></a>
...
<div ng-view></div>
</body>
language.htm
<div class="panel panel-default">
<div class="panel-heading">Spracheinstellungen</div>
<div class="panel-body">
<form>
Wählen Sie ihre Sprache aus:
<br/>
<input type="radio" ng-model="appLang" value="german">Deutsch
<br/>
<input type="radio" ng-model="appLang" value="english">Englisch
</form>
</div>
</div>
Thanks for your help! I got a solution:
The problem was, that the controller has been a copy of "appController" in each view and therefore the variables were different ones with the same name and the different views had no access to the same variable.
Now i use a service to share variables with other controllers and use an own controller for each view.
service:
app.factory("sharedProperties", function () {
return {
appLanguage: ""
};
});
langController:
app.controller("langController", function ($scope, sharedProperties) {
$scope.updateSharedProperties = function (){
sharedProperties.appLanguage = $scope.language;
console.log("--> updateSharedProperties(): " + $scope.language);
};
});
headerController:
app.controller("headerController", function ($scope, $http, $location, sharedProperties) {
$scope.setPicUrl = function () {
if (sharedProperties.appLanguage === "german") {
return "icons/german.png";
} else if (sharedProperties.appLanguage === "english") {
return "icons/english.png";
} else {
//TODO Error handling
return;
}
};
});
HTML for changing language (using langController):
<form>
Wählen Sie ihre Sprache aus:
<br/>
<input type="radio" ng-model="language" value="german" ng-click="updateSharedProperties()">Deutsch
<br/>
<input type="radio" ng-model="language" value="english" ng-click="updateSharedProperties()">Englisch
</form>
HTML for displaying flag-icon in header (using headerController):
<li><img id="langpic" ng-src="{{setPicUrl()}}" class="img-responsive"></li>
Try this. You need to execute the setPicUrl:
<input type="radio" ng-click="setPicUrl()" ng-model="appLang" value="german">Deutsch
<br/>
<input type="radio" ng-click="setPicUrl()" ng-model="appLang" value="english">Englisch
Change:
<img id="langpic" ng-src="{{setPicUrl()}}" class="img-responsive">
To:
<img id="langpic" ng-src="icons/{{appLang}}.png" class="img-responsive">
You can use $routeChangeStart or $routeChangeSuccess which are AngularJS built-in functions in bootstrapping function. For example when the route has been changed $routeChangeSuccess will be called automatically and you can change your $rootScope, $localStorage and any other directive's variables.
Try like this code:
//Bootstrapping Func
app.run(function ($window, $rootScope, $location, $route, $localStorage)
{
$rootScope.appLang = "english";
$rootScope.iconLang = "icons/english.png";
// On Route Change End Event
//---------------------------------------------
$rootScope.$on('$routeChangeSuccess', function ()
{
if ($rootScope.appLang === "german") {
$rootScope.iconLang = "icons/german.png";
} else if ($rootScope.appLang === "english") {
$rootScope.iconLang = "icons/english.png";
} else {
//TODO Error handling
}
});
}
Now you can bind the $rootScope.iconLang to the image tag you want like $scope.iconLang.

Using scope from route config within html

As a beginner with AngularJs I am looking into creating a single page application and I am having trouble converting some early code into more professional code. In doing this conversion I moved all my 'page' html into their own .html files. I am using ng-view to then display the proper html page inside of my ng-view div tag. Although after moving all the code something is now wrong with calling my methods. Specifically I think my error is within the app.config for route or within my .html files content for calling this information. If I remove the ng-controller div from my .html how do I still use the default controller set from app.config?
Here is my app.route setup:
app.config(['$routeProvider',
function config($routeProvider) {
$routeProvider
// route for the home page
.when('/', {
templateUrl: 'pages/home.html',
controller: 'mainController'
})
// route for the about page
.when('/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
// route for the contact page
.when('/contact', {
templateUrl: 'pages/contact.html',
controller: 'contactController'
});
}]);
Then here is my mainController setup:
app.controller('mainController', ['$scope', 'LoginService', function ($scope, LoginService) {
//Controller logic goes here
this.isValid = function (username, password) {
var EmailRegex = /^(([^<>()\[\]\.,;:\s#\"]+(\.[^<>()\[\]\.,;:\s#\"]+)*)|(\".+\"))#(([^<>()[\]\.,;:\s#\"]+\.)+[^<>()[\]\.,;:\s#\"]{2,})$/i;
var PasswordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]{8,}$/;
var EmailReg = new RegExp(EmailRegex);
var PasswordReg = new RegExp(PasswordRegex);
var em = EmailReg.test(username);
var pas = PasswordReg.test(password);
//alert("Hello dude! Email:" + em + " Password:" + pas + "\n" + username + " " + password );
if (em && pas) {
return false;
}
else {
return true;
}
};
this.user =
{
Message: 'Sign in',
ButtonMessage: 'Sign in Bailey',
TempUser: '',
TempPassword: '',
FirstName: '',
LastName: '',
Role: '',
AuthHash: null,
FinalUser: $scope.Username,
FinalPassword: $scope.Password,
};
$scope.user = this.user;
this.Authenicate = function (Username, Password) {
LoginService.Login(Username, Password).then(function (ResponseData)
{
var readAbleObject = angular.fromJson(angular.fromJson(ResponseData));
$scope.user.FirstName = readAbleObject.FirstName;
$scope.user.LastName = readAbleObject.LastName;
$scope.user.Role = readAbleObject.Role;
$scope.user.AuthHash = readAbleObject.AuthHash;
$scope.user.Username = readAbleObject.Username;
$scope.user.Password = readAbleObject.Password;
$scope.user.Message = "Welcome " + $scope.user.FirstName;
$scope.user.ButtonMessage = "Sign " + $scope.user.FirstName + " " + $scope.user.LastName + " out";
$scope.clearInput();
});
};
$scope.clearInput = function () {
this.user.TempUser = null;
this.user.TempPassword = null;
};
}]);
My html waiting for views to load into them:
<div id="MainDiv" data-ng-app="GApp">
<div id="LoginDiv" class="wrap" data-ng-view="">
</div>
</div>
My .html files content:
<div data-ng-controller="mainController as ctrl">
<div id="HomeHtml">
<link href="Content/Markup/Styles.css" rel="stylesheet" />
<p class="form-title">{{user.Message}}</p>
<form name="login" class="login" novalidate>
<input type="email" placeholder="Susquehanna Software Email" data-ng-model="user.TempUser" />
<input type="password" placeholder="Password" data-ng-model="user.TempPassword" />
<input type="submit" value="{{user.ButtonMessage}}" class="btn btn-lg btn-warning" data-ng-disabled="isValid(user.TempUser, user.TempPassword)" data-ng-click="Authenicate(user.TempUser, user.TempPassword)" />
</form>
</div>
Since you are using controller as syntax, if you write ctrl.user.TempPassword or generally append ctrl before user, then it should work.
You are on the right track, you do not need to write $scope.user = this.user. Its good practice to use controller as syntax.
.when('/', {
templateUrl: 'pages/home.html',
controller: 'mainController',
controllerAs: 'ctrl'
})
for functions to be visible to your view from the controller they need assigning to the $scope object e.g. $scope.Authenticate = this.Authenticate

Web api method not calling from angularjs

I am new to angularjs.I am building a very simple web application.The code structure is given below.I have a simple view showing candidate list and seraching candidate from data base.
My Javascript controller:
appRoot.controller('CandidateController', function ($scope, $location, $resource) {
var searchcandidates={
Name:$("#txtname").val(),
Email:$("#txtemail").val()
};
var Listcandidates = $resource('/api/Candidate', {Name:$("#txtname").val(), Email:$("#txtemail").val()}, { update: { method: 'GET' } });
$scope.candidateslist = [];
Listcandidates.query(function (data) {
$scope.candidateslist.length = 0;
angular.forEach(data, function (CandidateData) {
$scope.candidateslist.push(CandidateData);
})
});
$scope.SearchCandidates = function () {
alert($("#txtname").val());
var list = $resource('/api/Candidate', { id: "2" } );
}
var init = function () {
}
init();
});
My Cshtml:
#{
Layout = null;
}
<div class="FormHeader"><span class="searCandidate"></span>Search Result</div>
<div class="blank"></div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span2">
<!--Sidebar content-->
Search:
<label>Name</label>
<input type="text" id="txtname" name="name" />
<label>Email</label>
<input type="text" id="txtemail" name="email" />
<input type="button" value="Save" ng-click="SearchCandidates()" />
</div>
<div class="span10">
<!--Body content-->
<ul class="candidates">
<li ng-repeat="candidate in candidateslist"
class="thumbnail phone-listing">
#*<img ng-src="{{phone.imageUrl}}">
{{phone.name}}*#
<div class="item">
<span class="green leftMrg">{{candidate.name}}</span>
<span class="leftMrg">{{candidate.skill}}</span>
<span class="grey leftMrg">Resume ID: {{candidate.id}}</span>
<div class="blank"></div>
<div class="blank"></div>
</div>
<div class="item">
<span class="bold">{{candidate.exporganization}} </span>
<span>Education:{{candidate.eduname}}</span>
<span>{{candidate.totalexperience}}</span>
<span>Preferred Location: {{candidate.location}}</span>
</div>
<p></p>
</li>
</ul>
</div>
</div>
</div>
My app.js:
var appRoot = angular.module('main', ['ngRoute', 'ngGrid', 'ngResource', 'angularStart.directives', 'kendo.directives']); //Define the main module
appRoot
.config(['$routeProvider', function ($routeProvider) {
//Setup routes to load partial templates from server. TemplateUrl is the location for the server view (Razor .cshtml view)
$routeProvider
.when('/home', { templateUrl: '/home/main', controller: 'MainController' })
.when('/contact', { templateUrl: '/home/contact', controller: 'ContactController' })
.when('/about', { templateUrl: '/home/about', controller: 'AboutController' })
.when('/demo', { templateUrl: '/home/demo', controller: 'DemoController' })
.when('/candidate', { templateUrl: '/home/candidate', controller: 'CandidateController' })
.otherwise({ redirectTo: '/home' });
}])
.controller('RootController', ['$scope', '$route', '$routeParams', '$location', function ($scope, $route, $routeParams, $location) {
$scope.$on('$routeChangeSuccess', function (e, current, previous) {
$scope.activeViewPath = $location.path();
});
}]);
My CandidateController.cs
public class CandidateController : ApiController
{
CandidateSearchDAL objCandidateSearchDAL = new CandidateSearchDAL();
// GET api/<controller>
public IEnumerable<CandidateModel> Get()
{
List<CandidateModel> lstCandidates = objCandidateSearchDAL.GetSearchCandidates();
return lstCandidates;
}
// GET api/<controller>/5
public string Get(string id)
{
return "value";
}
// POST api/<controller>
public void Post(string Name, string Email)
{
}
// PUT api/<controller>/5
public void Put(int id, [FromBody]string value)
{
}
// DELETE api/<controller>/5
public void Delete(int id)
{
}
}
The first time when the page loads it shows all the candidates perfectly calling the controller IEnumerable Get() method.But when I click save button it can not call the controller api.
I'm not see call:
$resource.$save()

Angular JS set form field as invalid

I am trying to add some server side form validation to my angular js app. I'm having a hard time invalidating the form field and displaying the error message.
My basic application looks like this:
I have a model 'client' with a controler
Accounts.controller('Client', ['$scope', 'ClientService', function ($scope, ClientService) {
$scope.loading = false;
$scope.errors = null;
$scope.init = function () {
$scope.abn = "some value from API call";
};
$scope.save = function (client) {
$scope.form.abn.$setValidity("server", false);
$scope.errors.abn = "Error message";
}
$scope.init();
}]);
and a form view
<form name="form">
<div class="form-group">
<label>ABN Number</label>
<input type="text" name="abn" ng-model="client.abn">
<span ng-show="form.abn.$error.server">{{client.errors.abn}}</span>
</div>
<button ng-click="save(client)">Save</button>
</form>
and an app like so
var Accounts = angular.module('Accounts', [
'ngRoute',
'ui.select2',
'ui.router'
])
.config(function ($stateProvider, $routeProvider) {
$routeProvider.otherwise('/404');
$stateProvider
.state('client', {
url: "/client",
templateUrl: "client",
controller: 'Client'
})
.state('404', {
url: "/404",
templateUrl: "/error/e404/"
});
});
Is someone able to provide me with an example of how I should be setting the abn field as invalid and displaying an error message?
The way to display the error should be like this:
changed from $error.server to $invalid:
<span ng-show="form.abn.$invalid">{{client.errors.abn}}</span>
I added a style for ng-invalid class and created a plunkr where the field gets red and the errorMessage is displayed, once you press the save button. There was also another error when setting a property on $scope.errors because it was null.
http://plnkr.co/fDWF5g

Categories