AngularJS move part of Controller to Service - javascript

Consider the following code.
HTML:
<!doctype html>
<html ng-app="todoApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/css/bootstrap.min.css" rel="stylesheet">
<link href="/css/overlay-control.css" rel="stylesheet">
<link href="/css/list-control.css" rel="stylesheet">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!--<script src="/js/Services/UserService.js"></script>-->
<script src="/js/Controllers/MainController.js"></script>
<!--<script src="/js/Controllers/UserController.js"></script>-->
<script src="/js/bootstrap.min.js"></script>
</head>
<body ng-controller="MainController as myControl">
<div id="overlaycover" ng-click="myControl.showUpd(0)"></div>
<div id="overlaybox">
<div class="col-md-12">
<h4>Update:</h4>
<form ng-submit="myControl.updTodo()">
<div class="form-group">
<label for="updContent">Note:</label>
<textarea rows="5" cols="30" class="form-control" id="updContent" name="updContent" ng-model="noteupd.content"></textarea>
</div>
<div class="form-group">
<label for="updDeadline">Deadline (format YYYY-MM-DD HH:MM:SS):</label>
<input type="text" class="form-control" id="updDeadline" name="updDeadline" ng-model="noteupd.deadline" />
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="updCompleted" name="updCompleted" ng-model="noteupd.completed" /> - Completed
</label>
</div>
<div class="form-group">
<input type="hidden" id="updID" ng-model="noteupd.id" /><br/>
<button type="submit" class="btn btn-info">Update</button>
</div>
</form>
Click utside the square to close.
</div>
</div>
<div class="container">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12" id="listDiv">
<h1>Todo-list:</h1>
<p>
<img src="/images/legend-normal.png"> - Unfinished 
<img src="/images/legend-completed.png"> - Finished 
<img src="/images/legend-late.png"> - Late
</p>
<table class="table" id="list-table">
<tr>
<th>Note:</th>
<th>Author:</th>
<th>Project:</th>
<th>Created:</th>
<th>Deadline:</th>
<th colspan="2">Modify:</th>
</tr>
<tr ng-repeat="todo in myControl.todos" ng-class="rowClass(todo.completed, todo.deadline)">
<td> {{ todo.content }} </td>
<td> {{ todo.user }} </td>
<td> {{ todo.project }} </td>
<td> {{ todo.created }} </td>
<td> {{ todo.deadline }} </td>
<td><button type="button" class="btn btn-info" ng-click="myControl.showUpd(todo.id)">Update</button></td>
<td><button type="button" class="btn btn-danger" ng-click="myControl.delTodo(todo.id)">Delete</button></td>
</tr>
</table>
</div>
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12" id="formDiv">
<h3>Add new note:</h3>
<form ng-submit="myControl.addTodo()">
<div class="form-group">
<label for="newUser">User:</label>
<select ng-model="noteadd.user" class="form-control" id="newUser" name="newUser">
<option ng-repeat="user in myControl.users" value="{{ user.id }}">{{ user.name }}</option>
</select><br/>
</div>
<div class="form-group">
<label for="newProject">Project:</label>
<select ng-model="noteadd.project" class="form-control" id="newProject" name="newProject">
<option ng-repeat="project in myControl.projects" value="{{ project.id }}">{{ project.name }}</option>
</select><br/>
</div>
<div class="form-group">
<label for="newContent">Note:</label>
<textarea rows="5" cols="30" ng-model="noteadd.content" class="form-control" id="newContent" name="newContent"></textarea><br/>
</div>
<div class="form-group">
<label for="newDeadline">Deadline (format YYYY-MM-DD HH:MM:SS):</label>
<input type="text" ng-model="noteadd.deadline" class="form-control" id="newDeadline" name="newDeadline" /><br/>
</div>
<div class="form-group">
<button type="submit" class="btn btn-info">Add</button>
</div>
</form>
</div>
</div>
</body>
</html>
AngularJS Controller:
angular.module('todoApp', []).controller('MainController', function($scope, $http) {
var thisApp = this;
$scope.noteadd = {};
var noteadd = $scope.noteadd;
$scope.noteupd = {};
var noteupd = $scope.noteupd;
// Get all notes:
$http({method : 'GET', url : 'http://localhost:8000/notes'})
.then (function(response) {
thisApp.todos = response.data;
}, function() {
alert("Error getting todo notes");
});
// Get all users:
$http({method : 'GET',url : 'http://localhost:8000/users'})
.then(function(response) {
thisApp.users = response.data;
}, function() {
alert("Error getting users");
});
// Get all projects
$http({method : 'GET', url : 'http://localhost:8000/projects'})
.then(function(response) {
thisApp.projects = response.data;
}, function() {
alert("Error getting projects");
});
// Add note to database
thisApp.addTodo = function(noteadd)
{
$http({
method : 'PUT',
url : 'http://localhost:8000/notes',
data : $.param($scope.noteadd),
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
location.reload();
}, function() {
alert("Couldn't add note. Please try again!");
});
};
// Hide note by setting removed to 1
thisApp.delTodo = function(noteID)
{
var r = confirm("Are you sure?");
if (r == true) {
var noteObj = JSON.parse('{"id":' + noteID + '}'); // JSON for req
$http({
method : 'DELETE',
url : 'http://localhost:8000/notes',
data : $.param(noteObj),
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
location.reload();
}, function() {
alert("Couldn't delete note. Please try again!");
});
}
};
// Show overlay with form for updating a note
thisApp.showUpd = function(noteID)
{
var overlaycover = document.getElementById("overlaycover");
var overlaybox = document.getElementById("overlaybox");
overlaycover.style.opacity = .65;
if(overlaycover.style.display == "block" || noteID == 0){ // For toggling overlay
overlaycover.style.display = "none"; // Hide div overlaycover
overlaybox.style.display = "none"; // Hide div overlaybox
} else {
$http({method : 'GET', url : 'http://localhost:8000/notes/' + noteID})
.then (function(response) {
noteupd.content = response.data.content; // Update fields in form
noteupd.deadline = response.data.deadline;
noteupd.id = response.data.id;
if (response.data.completed == 1) {
noteupd.completed = true;
} else {
noteupd.completed = false;
}
overlaycover.style.display = "block"; // Show div overlaycover
overlaybox.style.display = "block"; // Show div overlaybox
}, function() {
alert("Error getting todo note");
});
}
}
// Update a note
thisApp.updTodo = function(noteupd)
{
$http({
method : 'POST',
url : 'http://localhost:8000/notes',
data : $.param($scope.noteupd),
headers : {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function(response) {
location.reload();
}, function() {
alert("Couldn't add note. Please try again!");
});
}
// Check if deadline passed for each note in list
$scope.rowClass = function(completed, deadline)
{
var nowTime = Math.floor(Date.now()/1000);
var deadTime = new Date(deadline);
var deadUTC = Math.floor(deadTime/1000);
if (completed == 1) {
return "success"; // Note is completed
} else if (deadUTC < nowTime) {
return "danger"; // Note is not completed, deadline passed
} else {
return "active"; // Note is not completed, still time left
}
}
});
What I would like to do is to move all $http-calls to a service instead of having them in the controller like I have it now. I have searched the internet but I don't really understand the solutions i've found there.
Second, in several functions, as you can see, I use location.reload();. I would like to use ng-bind instead, but as the sam, I don't understand how this works.
Can someone please explain how I should do these two things?

Ok , let's for example create a Users factory and put all Users api related stuff inside:
'use strict';
angular
.module('todoApp')
.factory('Users', factory);
function factory($http) {
var service = {
get: get,
//edit: edit ...
};
return service;
function get() {
return $http({method : 'GET',url : 'http://localhost:8000/users'})
.then(function(response) {
return response.data;
});
}
//function edit(user) {
// return $http({method : 'PUT...
//}
}
What you have to do next is inject that factory wherever you want to call it.
So in your controller you essentially have to do this:
angular.module('todoApp', [])
.controller('MainController', function($scope, Users) {
//.....
function getUsers() {
Users.get().then(function(data){
thisApp.users = response.data;
}, function() {
alert("Error getting users");
});
}
getUsers();
//...
Repeat the same by creating the appropriate services for notes and projects.
To not bloat the main app.js move this services to seperate files, users.service.js etc..
I would also advise you to move the controllers to seperate files too.
Just be careful:
this is a module creation
angular.module('todoApp', [])
You create a module once.
to attach a service/factory/controller/anything, when you are in that separate file, to that module you use this:
angular.module('todoApp').anything
Second, I assume you use location.reload to update the view with the new data.
Let's say you edit/delete a User. Instead of reloading the page, call getUsers() in the then() of put/delete/create User.
Hope it makes sense to you!
PS: This styleguide by John Papas have been very helpful to me, I suggest you give it a read !

I've already used service factory solution for such kind of problem.
angular.module('data-service').factory('dataService', ['$http',function ($http) {
var url = 'http://localhost:8000/';
return {
getData: function(type) {
return $http({method : 'GET', url : url + type});
},
allData: function() {
return $q.all({
notes: this.getData('notes'),
users: this.getData('users'),
projects: this.getData('projects')
});
}
}
}]);
usage:
dataService.getData('notes').then(function (data) { ... });
also you can use angular promise $q.
dataService.allData().then(function(data) { /* data.notes, data.users, data.projects */ }

Related

update the data dynamically in AngularJS

I have two end points
http://localhost:3000/entry (POST)
Keys are :- fname, lname and age . We can submit a form by sending a POST request to this URL.
http://localhost:3000/entries (GET)
It will return the existing data from the database in a JSON.
[
{
"_id": "5b48a137c3b2a3454b853a3c",
"fname": "John",
"lname": "Jose",
"age": "28",
"__v": 0
},
{
"_id": "5b506cc7d9105012f59c87e6",
"fname": "Alex",
"lname": "Cruz",
"age": "27",
"__v": 0
}
]
I can successfully submit a form. In my HTML, I also have a table. I want to update the data in the table whenever I submit an entry without reloading the whole page.
Actually, data in this API http://localhost:3000/entries is dynamic, sometimes, I insert into database directly. So, whenever there is a change, it should reflect in the table without reloading the whole page.
I am using AngularJS 1.
index.html :-
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="script.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="style.css">
<div ng-app="myApp">
<div class="container">
<div class="row">
<div class="col-sm-12">
<h3>
Dashboard
</h3>
</div>
</div>
<form name="saveTemplateData" action="#" ng-controller="FormCtrl" ng-submit="submitForm()" >
<div class="col-sm-12">
<div class="form-group">
<label>FirstName</label>
<input type="text" class="form-control" value="" ng-model="form.fname" />
</div>
<div class="form-group">
<label>LastName</label>
<input type="text" class="form-control" value="" ng-model="form.lname" />
</div>
<div class="form-group">
<label>Age</label>
<input type="text" class="form-control" value="" ng-model="form.age" />
</div>
</div>
<div class="col-sm-12">
<input type="submit" class="btn btn-success" ngClick="Submit">
</div>
</form>
<!-- Table Start -->
<div class="row">
<table style="width:100%">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Age</th>
</tr>
<tr>
<!-- item.fname -->
<td>{{item.fname}}</td>
<!-- item.lname -->
<td>{{item.lname}}</td>
<!-- item.age -->
<td>{{item.age}}</td>
</tr>
</table>
</div>
<!-- Table END -->
</div>
</div>
script.js :-
var app = angular.module('myApp', []);
app.controller('FormCtrl', function ($scope, $http) {
$scope.submitForm = function()
{
$http({
url: "http://localhost:3000/entry",
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $.param($scope.form)
}).then(function (response) {
$scope.status = status;
}), function (error) {
$scope.status = status;
};
}
});
If I understand your question and problem(s), you'll need to do a number of things to resolve your issues.
Firstly, you'll want to make some extensions to your controller. The main one being to fetch the data from your API:
app.controller('FormCtrl', function ($scope, $http, $interval) {
/*
Add this method to get data from server
*/
$scope.fetchData = function() {
// It is best practice to handle error responses as well (not
// shown here)
$http.get('http://localhost:3000/entries').then(function(response) {
// Set the data items in your scope. Doing this should now
// cause them to be listed in your view
$scope.items = response.data;
});
}
$scope.submitForm = function($event) {
// Adding this prevents the browser from reloading on form submit
$event.preventDefault()
$http({
url: "http://localhost:3000/entry",
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $.param($scope.form)
}).then(function (response) {
$scope.status = status;
}), function (error) {
$scope.status = status;
});
}
// Fetch data once controller is set up, on a regular 2 second
// interval
$interval(function() {
$scope.fetchData()
}, 2000)
});
You'll also need to update your HTML/view:
<!-- Add $event as an argument to you ng-submit callback -->
ng-submit="submitForm($event)"
And:
<!-- Doing this causes the data in the items array to be iterated
and displayed in a list-wise fashion in the table -->
<tr ng-repeat="item in items">
<!-- item.fname -->
<td>{{item.fname}}</td>
<!-- item.lname -->
<td>{{item.lname}}</td>
<!-- item.age -->
<td>{{item.age}}
</td>
</tr>
Finally, the most important thing is to wrap the table and form with your FormCtrl controller. You can do this by moving ng-controller="FormCtrl" from your <form> element, to your <div class="container"> element in your view.

Get token with Angularjs

I'm working on an Angularjs + Moodle + WebService APP
I have done a little Login page and have a question.
I'm getting the Token of my user via $.ajax and I can see it in my chrome console.
The thing is, I want to save that token for using it in WS moodle fuctions and I'm usin JSON.strungify to get the token, but I have not successed.
I just get -> {readystate: 1} as an alert, instead get a token. but in my console.info(response); I got the token as show the next image :
Thi is my code:
controller.js
var app = angular.module('mainApp', ['ngRoute', 'toaster', 'ngAnimate']);
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'login.html'
})
.when('/dashboard', {
resolve: {
"check": function($location, $rootScope) {
if(!$rootScope.loggedIn){
$location.path('/');
}
}
},
templateUrl: 'dashboard.html'
})
.otherwise({
redirectTo: '/'
});
});
app.controller('loginCtrl',
function($scope, $location, $rootScope) {
$scope.submit = function() {
/*if($scope.username == 'admin' && $scope.password == 'admin') {
$rootScope.loggedIn = true;
$location.path('/dashboard');
} else {
alert('Wrong Stuff');
}*/
$rootScope.loggedIn = true;
var username = $scope.username;
var password = $scope.password;
postCredentials(username, password/*, createSession*/);
};
function postCredentials(username, password, callback) {
if (username!==null || password!==null) {
var serverurl = 'https://comunidaddeaprendizaje.cl/ac-cap/login/token.php';
var data = {
username: username,
password: password,
service: 'moodle_mobile_app' // your webservice name
}
var response = $.ajax(
{ type: 'POST',
data: data,
url: serverurl,
dataType: 'JSON'
}
);
console.info(response);
dataString = JSON.stringify(response);
alert(dataString);
if (dataString.indexOf('error') > 0) {
alert('Invalid user credentials, please try again');
};
} else {
alert('Something Wrong');
}
}
}
);
login.html
div class="breadcrumbs" id="breadcrumbs">
<ul class="breadcrumb">
<li>
<i class="ace-icon fa fa-home home-icon"></i>
Home
</li>
<li class="active">Login</li>
</ul>
</div>
<div class="page-content">
<div class="row">
<div class="space-6"></div>
<div class="col-sm-10 col-sm-offset-1">
<div id="login-box" class="login-box visible widget-box no-border">
<div class="widget-body">
<div class="widget-main">
<h4>Login ACCAP</h4>
<div ng-controller="loginCtrl">
<form action="/" class="form-horizontal" id="myLogin">
<div class="form-group">
UserName:
<input type="text" class="form-control" id="username" ng-model="username" required focus><br>
Password:
<input type="password" class="form-control" id="password" ng-model="password" required>
</br>
<button type="button" class="width-35 pull-right btn btn-sm btn-primary" ng-click="submit()">
<div class="col-sm-7">
<i class="ace-icon fa fa-key"></i>
Login
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Login APP</title>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/1.1.0/toaster.min.css" rel="stylesheet" />
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.7/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.3/angular-route.js"></script>
<script src="https://code.angularjs.org/1.2.0/angular-animate.min.js" ></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angularjs-toaster/1.1.0/toaster.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.6.4.js"></script>
<script src="controller.js"></script>
</head>
<body ng-app="mainApp">
<div ng-view></div>
</body>
</html>
Thanks for your help!
The response variable is an object which contains a lot of information about the response. It is not the same as your response text.
Your second mistake is that your AJAX call is asynchronous, so you cannot obtain your response immediately after AJAX call. You need to wait for the response. Instead of
var response = $.ajax({
type: 'POST',
data: data,
url: serverurl,
dataType: 'JSON'
});
console.info(response);
dataString = JSON.stringify(response);
alert(dataString);
if(dataString.indexOf('error') > 0) {
alert('Invalid user credentials, please try again');
};
you should write
var response = $.ajax({
type: 'POST',
data: data,
url: serverurl,
dataType: 'JSON',
success: function(response) {
console.info(response);
dataString = JSON.stringify(response);
alert(dataString);
if(dataString.indexOf('error') > 0) {
alert('Invalid user credentials, please try again');
};
}
});

How to share data between controllers in AngularJS? [duplicate]

This question already has answers here:
Share data between AngularJS controllers
(11 answers)
Closed 6 years ago.
I have a team_list page and a team page. A user will have a list of teams they are in in the team_list page and then click on one of the teams to go to its team page. I am not sure how to send the data that the team page that the user is going to is Team A's teampage or Team B's team page. So how do I share data between controllers?
I know I should be using services but I'm not sure how to use them in this context..I've tried some methods and commented out some but I'm still not sure how to go about this.
Using node.js and express framework for backend
team_list.html:
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<head>
<title>Team List</title>
</head>
<body>
<h1>
Welcome to Your Team List Page!
</h1>
<!--<div ng-app="teamListPage" ng-controller="listController">
<fieldset>
<legend>Your Teams</legend>
<ul>
<li ng-repeat="x in [dave, david, darrell]">{{x}}</li>
<input type="button" id="enter" name="enter" value="Enter Home Page" ng-click="enterTeamPage()"/>
</ul>
</fieldset>
</div>-->
<div ng-app="teamListPage" ng-controller="listController">
<li ng-repeat="x in records">
{{x.team_name}}<br/>
<input type="button" id="enter" name="enter" value="Enter Home Page" ng-click="enterTeamPage()"/>
</li>
<input type="button" id="Create" name="Create" value="Create New Team" ng-click="enterCreateTeamPage()" />
</div>
<script>
var page = angular.module('teamListPage', []);
/*page.factory('myService', function() {
var user_id = [];
var setUserID = function(newObj) {
user_id.push(newObj);
};
var getUserID = function(){
return user_id;
};
return {
setUserID: setUserID,
getUserID: getUserID
};
});*/
page.factory('myService', function(){
return {
data: {
user_ID: ''
},
update: function(userID) {
// Improve this method as needed
this.data.user_ID = userID;
}
};
});
page.controller('listController', function($scope, $http, $window, myService) {
console.log(myService.data);
var login_http = $http({
method: 'GET',
url: '/team_req',
params: { user_id: 1 }
}).then(
function (response) {
//$window.alert(response.data[0].team_name);
$scope.records = response.data;
//console.log($scope.records[1]);
//alert('successfull ...');
}, function (response) {
$window.alert('wrong username/password');
}
)
$scope.enterTeamPage = function() {
$window.location.href = '/teamPage';
};
$scope.enterCreateTeamPage = function() {
$window.location.href = '/createTeamPage';
};
})
</script>
</body>
</html>
team_page.html:
<!DOCTYPE html>
<html lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<head>
<meta charset="UTF-8">
<title>Team Page</title>
</head>
<body>
<h1>
Team Page
</h1>
<div ng-app="teamPage" ng-controller="teamController">
<form id="Communication Board">
<fieldset>
<legend>COMMUNICATION BOARD</legend>
<h3>
chat feature coming up!
</h3>
<legend>videocall</legend>
<h4>
video call feature coming up!
</h4>
<legend>screenshare</legend>
<h5>
screenshare feature coming up!
</h5>
</fieldset>
</form>
<form id="Data Board" action="">
<fieldset>
<legend>DATA BOARD</legend>
<h6>
calendar feature coming up!
</h6>
<legend>announcements</legend>
<h7>
All features are coming up very soon!
</h7>
</fieldset>
</form>
<p>
<input type="button" id="CodingZone" name="CodingZone" value="Go to Coding Zone" ng-click="enterCodingPage()" />
</p>
</div>
<script>
var page = angular.module('teamPage', []);
page.controller('teamController', function($scope, $http, $window) {
//get the history of the chat board
$scope.getChatHistory = function() {
var create = $http({
method: 'Get',
url: '/chatHistory'
}).then(
function successful(response) {
$scope.theResponse = response.data;
}, function unsuccessful(response) {
alert('got an error back from server');
$scope.theResponse = response;
});
}
$scope.enterCodingPage = function() {
$window.location.href = '/codingPage';
};
})
</script>
</body>
</html>
Also should I put my service in app.js or index.js?
The best way to share data between controllers or components (wrappers for directives) is to use angular services and inject them into controllers. Cuz services are singletons so each of them presents single state for all components where it will be injected.

Angular - Form Validation - Cannot read property 'name' of undefined

so I have a form with an input and some other stuff and I'm trying to do some angular validation to make sure that the entered information is actually there (not blank). To do so, I'm using an if statement.
The error message I get is:
Cannot read property 'name' of undefined
It seems as if it can't read an <input> tag name if it's left blank. The function works when I fill in the , but not the others (which are a and . I'm just trying to use an if statement to see if they've been filled out. Here's the html and angular code below:
reviewModal.view.html (shortened form version)
<div class="modal-content">
<div role="alert" ng-show="vm.formError" class="alert alert-danger">{{ vm.formError }}</div>
<form id="addReview" name="addReview" role="form" ng-submit="vm.onSubmit()" class="form-horizontal">
<label for"name" class="col-xs-2 col-sm-2 control-label">Name</label>
<div class="col-xs-10 col-sm-10">
<input id="name" name="name" ng-model="vm.formData.name" class="form-control">
</div>
<button type="submit" class="btn btn-primary">Submit review</button>
</form>
</div>
reviewModal.controller.js
(function() {
angular
.module('loc8rApp')
.controller('reviewModalCtrl', reviewModalCtrl);
reviewModalCtrl.$inject = ['$uibModalInstance', 'locationData'];
function reviewModalCtrl($uibModalInstance, locationData) {
var vm = this;
vm.locationData = locationData;
vm.onSubmit = function() {
vm.formError = "";
if(!vm.formData.name || !vm.formData.rating || !vm.formData.reviewText) {
vm.formError = "All fields required, please try again";
return false;
} else {
console.log(vm.formData);
return false;
}
};
vm.modal = {
cancel : function() {
$uibModalInstance.dismiss('cancel');
}
};
}
})();
locationDetail.controller.js
(function() {
angular
.module('loc8rApp')
.controller('locationDetailCtrl', locationDetailCtrl);
locationDetailCtrl.$inject = ['$routeParams', '$uibModal', 'loc8rData'];
function locationDetailCtrl($routeParams, $uibModal, 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() {
var modalInstance = $uibModal.open({
templateUrl: '/reviewModal/reviewModal.view.html',
controller: 'reviewModalCtrl as vm',
resolve : {
locationData : function() {
return {
locationid : vm.locationid,
locationName : vm.data.location.name
};
}
}
});
};
}
})();
vm.formData must be defined before you can assigned/read name property in the html. Update code in reviewModalCtrl to init vm.formData:
vm.formData = {};
Use angular validation instated validating things in controller as follows.
<div class="modal-content">
<div role="alert" ng-show="addReview.$submitted && addReview.$invalid" class="alert alert-danger">All fields required, please try again</div>
<form id="addReview" name="addReview" role="form" ng-submit="vm.onSubmit()" class="form-horizontal">
<label for"name" class="col-xs-2 col-sm-2 control-label">Name</label>
<div class="col-xs-10 col-sm-10">
<input id="name" name="name" ng-model="vm.formData.name" class="form-control" required>
</div>
<button type="submit" class="btn btn-primary">Submit review</button>
</form>
</div>
I have used required in text box and show the error message on top with
ng-show="addReview.$invalid"
You do not need any code on controller.

How to load data in ngDialog

I have a requirement where I need to open a dialog from a jsp page and while opening the dialog, I need to load it with some prepopulated data from the server (using an AJAX call). If I make the AJAX call before opening the dialog, I get the data but the dialog loads like a new page. If I try to get the data in the new controller, the dialog still does not reflect the data. What should I use to make sure the dialog reflects the data that I am getting from the server
<div class="container-fluid" ng-controller="EditUserController">
<div class="text-center container-fluid">
<label class="sub-header">Edit User: {{userEmail}}</label>
</div>
<form action="editUser" method="post" name="editForm">
<div>
<div class="pull-right">
<label>Delete User</label><br> <a href="#"
class="btn btn-block btn-sm btn-danger" ng-click="deleteUser(userEmail)">{{userEmail}}</a>
</div>
<div>
<label>Change Role</label>
</div>
<div>
<label>
<input type="checkbox" ng-model="superVisor" name="superVisorFlag"
ng-true-value="1" ng-false-value="0" value="${existingUser.superVisorFlag}">
Make a Supervisor</label>
</div>
<div>
<input type="text" class="form-control" ng-model="email"
name="emailAddress" ng-disabled = "true"
ng-options="email for email in userEmail"
value="${existingUser.emailAddress}"
placeholder="Enter New User Email Address" bs-typeahead>
</div>
<div>
<input type="text" class="form-control" ng-model="firstName"
name="firstName" value="${existingUser.firstName}"
placeholder="Enter First Name" bs-typeahead>
</div>
<div>
<input type="text" class="form-control" ng-model="lastName"
name="lastName" value="${existingUser.lastName}"
placeholder="Enter Last Name" bs-typeahead>
</div>
<div>
Save Changes
</div>
</div>
</form>
</div>
<script type="text/javascript"
src="<c:url value="/resources/scripts/admin.js"/>"></script>
The above is a jsp for the dialog. Below is my js file -
var app = angular.module('scc-admin', [ 'ngDialog', 'mgcrea.ngStrap' ]);
app.factory("UserList", function() {
var UserList = {};
UserList.data = [ {
userId : 111,
userFirstName : "xxx",
userLastName : "yyy",
userEmail : "xxx.yyy#zzz.com",
userRole : "Admin"
}, {
userId : 222,
userFirstName : "second",
userLastName : "last",
userEmail : "second.last#zzz.com",
userRole : "Manager"
}];
return UserList;
});
app.controller('UserSettingsController', function($scope, ngDialog, UserList,$http) {
// variable for the bashboard list
$scope.userList = UserList;
$scope.editUser = function(userEmail) {
$scope.userEmail = userEmail;
ngDialog.open({
template : 'editUser' ,
className : 'ngdialog-theme-default',
controller : 'EditUserController',
closeByEscape : true,
scope : $scope
});
};
$scope.addUser = function() {
ngDialog.open({
template : 'addUser',
className : 'ngdialog-theme-default',
controller : 'AddUserController',
closeByEscape : true,
scope : $scope
});
};
});
app.controller('EditUserController', function($scope, ngDialog, $http) {
ngDialog.template = $scope.output;
ngDialog.$modelValue = $scope.output;
var responsePromise = $http.get("initUser?email=" + $scope.userEmail);
responsePromise.success(function(data, status, headers, config) {
$scope.output = data;
console.log(data);
});
console.log($scope);
$scope.deleteUser = function(){
$scope.cfdump = "";
var str = {emailAddress : $scope.userForm.emailAddress.$modelValue};
str = JSON.stringify(str);
var request = $http({
method: 'post',
url: "deleteUser?formData=" + str,
data: ({formData:str})
});
request.success(function(html){
alert("success");
});
request.error(function(errmsg){
alert("Unable to delete user");
});
}
});
I am opening a dialog in usersettings controller and trying to load it with default data. I tried setting the new dialog's template to the output of the AJAX call, it did not work. What am I missing here?
After consulting the documentation, I learned following solution. It should work for you like it did for me.
To pass data (JSON Object) for ng-model inside the ngDialog, you can declare your ngDialog as following.
ngDialog.open({
template: 'my-template.html',
className: 'ngdialog-theme-plain',
data: $scope.myJSONObject
});
Now, with the above part done, you need to bind the data in your popup ngDialog, so go and put ngDialogData.myJSONObjectFieldName in your ng-model.
Consider following example for further elaboration. We assume that we have myJSONObject as following.
myJSONObject={
first_name: 'John',
last_name: 'Doe'
};
To use first_name inside your ngDialog's ng-model, simply put ng-model="ngDialogData.first_name".
To check whether the controller(VM) data is received in Modal Dialog use this
<pre>{{vm|json}}</pre>
Module and Controller:
var app = angular.module("DemoApp",['ngDialog']);
app.controller("DemoController",["$rootScope","ngDialog","productService",function($rootScope,ngDialog,productService){
var vm=this;
$rootScope.ngDialog = ngDialog; // to close Dialog using "ngDialog.close();" in ProductDialog.html
/* vm.products=[{brand:"Apple", price:60000, os:"iOS"},
{brand:"Samsung", price:35000, os:"Android"},
{brand:"Microsoft Lumia", price:30000, os:"Windows 10"}
];
*/
vm.getProductDetails=function() {
productService.getData().then(function (response) {
if (response.data) {
vm.products=response.data;
vm.ProdDialog();
}
});
};
vm.productPopup = function(x){
ngDialog.open({
template: 'ProductDialog.html',
className:'ProductDetailsDialog'
scope:$scope,
data:x,
closeByDocument:true
});
}
vm.getProductDetails();
}]);
Service:
app.factory("productService",["$http",function($http){
return {
getData: function() {
return $http.get("http://xxxxxxx/xxx/xxxxx");
}
};
}]);
DemoController.html
/* <table>
<tr>
<th>Brand</th>
<th>Price</th>
<th>OPerating System</th>
<th>Open ngDialog</th>
</tr>
<tr ng-repeat="x in vm.products">
<td ng-bind="x.brand"></td>
<td ng-bind="x.price| currency:"₹":2"></td>
<td ng-bind="x.os"></td>
<td><button ng-click="vm.productPopup(x)"></button></td>
</tr>
</table>
*/
ProductDialog.html:
<div class="ProductDetailsDialog">
<div class="ngdialog-content" role="document">
<div class="modal-header">
<button type="button" class="close" ng-click="ngDialog.close();">×</button>
<h4 class="modal-title">Product Detials</h4>
</div>
// <pre>{{vm|json}}</pre> //
<div class="modal-body">
<h4>Brand:<span ng-bind="ngDialogData.brand"></span></h4>
<h4>Price:<span ng-bind="ngDialogData.price | currency:"₹":2"></span></h4>
<p>Operating System:<span ng-bind="ngDialogData.os"></span></p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default">OK</button>
</div>
</div>
</div>

Categories

Resources