I am trying nodeJS, SailsJS & Angular. I want use this loading bar:
http://chieffancypants.github.io/angular-loading-bar/
https://github.com/chieffancypants/angular-loading-bar
I read the loading bar handle http request are automatically.
so i do this :
npm install angular-loading-bar.
I put the jss and css in assets.
Here my LoginModule :
var LoginModule = angular.module('LoginModule', ['angular-loading-bar']);
And my LoginController :
angular.module('LoginModule')
.controller('LoginController', LoginController);
LoginController.$inject = ['$scope', '$http', 'cfpLoadingBar'];
function LoginController($scope, $http, cfpLoadingBar) {
// Get CSRF token and set as header
$http.defaults.headers.post['X-CSRF-Token'] = document.getElementsByName('_csrf')[0].value;
$scope.submitLoginForm = function() {
$scope.start();
$http.post('/login', {
identifiant: $scope.login.identifiant,
password: $scope.login.password
})
.then(function onSuccess() {
window.location = '/home/';
})
.catch(function onError(response) {
console.log(response);
})
}
$scope.start = function() {
cfpLoadingBar.start();
};
$scope.complete = function() {
cfpLoadingBar.complete();
};
}
But when i login on my form :
<div class="container-fluid" ng-app="LoginModule" ng-controller="LoginController" ng-cloak>
<div class=" col-lg-offset-4 col-lg-4">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">Connexion</h3>
</div>
<div class="panel-body">
<h5 class="col-lg-12" style="text-align: center">Admin !</h5>
<form ng-submit="submitLoginForm()" class="col-lg-offset-3 col-lg-6 form-group" name="loginForm">
<input type="text" class="form-control" id="inputLogin" name="inputLogin" placeholder="Identifiant" ng-model="login.identifiant">
<input type="password" class="form-control" id="inputPassword" name="inputPassword" placeholder="Mot de passe" ng-model="login.password">
<br>
<button type="submit" class="btn btn-primary" style="float: right">Connexion</button>
<input type="hidden" name="_csrf" value="<%= _csrf %>">
</form>
</div>
</div>
</div>
</div>
I don't see the loading bar when i submit the form (form working) :( why ? Also when i try to load ngAnimate in LoginModule i have an error
I tried also the function start() on element HTML but nothing..
You Must include angular-animate.min.js to make it work
as also include in git repository example. when I removed this line
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular-animate.min.js"></script>
it stopped working please make sure you include animation file. that's why ngAnimate also giving error
Related
I have modal code (below) wrapped in nav.html and it works as expected (login, logout...works).
<div class="modal fade" id="authModal" role="dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-body">
<form class="form-signin" role="form">
<input ng-model="user.email" type="email" class="form-control" placeholder="Email address" required="" autofocus="">
<input ng-model="user.password" type="password" class="form-control" placeholder="Password" required="">
<div class="checkbox checkbox-success">
<input ng-model="checkbox.signup" ng-init="checkbox.signup=false" type="checkbox">
<label> Sign Up for first-timer </label>
</div>
<div class="text-center">
<button ng-click="login($event)" class="btn btn-lg btn-primary" type="button">Sign In</button>
</div>
</form>
</div>
</div>
But when I move all modal content to a file named md.html and include it to nav.html via
<div class="navbar-header" ng-controller="MainCtrl">
<div ng-include="'views/modals/md.html'"></div>
</div>
It is absolute that I have it included in the ng-controller div.
On testing, I got error of unable to reference to user.password for the Controller. The controller works fine previously and I didn't change anything on it. For this question, I m posting a simplified version of modal and controller code.
$scope.login = function($event){ $event.preventDefault();
// console.log("cond ", cond, ".checkbox.signup ", $scope.checkbox.signup);
if (!$scope.logged)
fn.login($scope.user, function(){
if ($scope.checkbox.signup) fn.signup($scope.user);
});
};
var fn = {
login: function(user, cb){
if (Auth.authData) return;
if (!user.password) {
fn.alert("please type password");
return;
}
if (fn.valid_email(user.email))
Auth.ref_ds1.authWithPassword(user, function(error, authData) {
if (error) {
fn.alert(error);
cb();
} else {
authData.email = $scope.user.email;
console.log("Authenticated successfully on:", authData.email);
fn.greet("Hello " + authData.email.split("#")[0]);
$scope.logged = true;
window.location.href = "/";
}
});
}
}
How to reference them correctly?
It looks like you could be seeing issues with your ng-include creating another scope and you're not able to reference the previously defined user object.
One way I avoid confusion with scopes is using "Controller as" syntax to reference a scope specifically (see http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/). Here's a tiny example:
// in the controller
app.controller('MainController', function() {
var vm = this;
this.somevalue = 'something';
})
// markup
<div ng-controller="MainCtrl as ctrl">
{{ ctrl.somevalue }}
<div ng-controller="SecondCtrl as secondCtrl">
{{ ctrl.somevalue }}
{{ secondCtrl.anothervalue }}
</div>
</div>
Using "Controller as" will really help unwind scope problems you're having, but it would take some re-tooling of your original controller.
I'm building an app which uses vue.js and Laravel 5 to persist data into a database. So far, it can successfully save data.
My problem
I'm having trouble with displaying errors when the user validation fails using the 'out of the box' authorisation that Laravel has. I keep getting the error:
[Vue warn]: Error when evaluating expression "form.errors.length > 0"
(referring to errors.js in my code below)
Piecing it together
So how this should work...a user enters their details into the registration page and Vue (using vue-resource) makes an AJAX request to the 'out of the box' Laravel AuthController#postRegister method. On error, Laravel nicely spits out the JSON error messages we all expect. Now in theory, the sendRegistration method within my subscription.js file should detect the errors that Laravel spits out (I've tested this with console.log's and it works) and pass them into the errors.js component to display the errors within the <spark-errors> tags. In order to do this, it uses a setErrorsOnForm: function within my <head> tag. However it's not working as expected and I cannot workout why.
My code
My code consists of a registration page:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Laravel Spark Globals -->
<script>
window.Spark = {
// Laravel CSRF Token
csrfToken: '{{ csrf_token() }}',
// Flatten errors and set them on the given form
setErrorsOnForm: function (form, errors) {
if (typeof errors === 'object') {
form.errors = _.flatten(_.toArray(errors));
} else {
form.errors.push('Something went wrong. Please try again.');
}
}
}
</script>
</head>
<body>
<div id="spark-app">
<spark-subscription-register-screen inline-template>
<div class="panel panel-default">
<div class="panel-heading">Your Information</div>
<div class="panel-body">
<spark-errors form="#'{'{ registerForm '}'}"></spark-errors>
<form class="form-horizontal" role="form" id="subscription-basics-form">
<div class="form-group">
<label class="col-md-4 control-label">Your Name</label>
<div class="col-md-6">
<input type="text" class="form-control spark-first-field" name="name" v-model="registerForm.name">
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">E-Mail Address</label>
<div class="col-md-6">
<input type="email" class="form-control" name="email" v-model="registerForm.email">
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password" v-model="registerForm.password">
</div>
</div>
<div class="form-group">
<label class="col-md-4 control-label">Confirm Password</label>
<div class="col-md-6">
<input type="password" class="form-control" name="password_confirmation" v-model="registerForm.password_confirmation">
</div>
</div>
<div v-if="freePlanIsSelected">
<div class="form-group">
<div class="col-sm-6 col-sm-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" v-model="registerForm.terms"> I Accept The Terms Of Service
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-sm-6 col-sm-offset-4">
<button type="submit" class="btn btn-primary" v-on:click="register" :disabled="registerForm.registering">
<span v-if="registerForm.registering">
<i class="fa fa-btn fa-spinner fa-spin"></i> Registering
</span>
<span v-if=" ! registerForm.registering">
<i class="fa fa-btn fa-check-circle"></i> Register
</span>
</button>
</div>
</div>
</div>
</form>
</div>
</div>
</spark-subscription-register-screen inline-template>
</div>
</body>
</html>
From a vue.js perspective there is a subscription.js file:
Vue.component('spark-subscription-register-screen', {
/*
* Initial state of the component's data.
*/
data: function () {
return {
registerForm: {
nhs_org: '', team_name: '', name: '', email: '', password: '', password_confirmation: '',
plan: '', terms: false, coupon: null, invitation: null,
stripe_token: null, errors: [], registering: false
},
};
},
methods: {
/*
* Initialize the registration process.
*/
register: function(e) {
var self = this;
e.preventDefault();
this.registerForm.errors = [];
this.registerForm.registering = true;
return this.sendRegistration();
},
/*
* After obtaining the Stripe token, send the registration to Spark.
*/
sendRegistration: function() {
this.$http.post('/register', this.registerForm)
.success(function(response) {
window.location = '/';
})
.error(function(errors) {
this.registerForm.registering = false;
Spark.setErrorsOnForm(this.registerForm, errors);
});
},
}
});
and there is an errors.js Vue component:
/*
* Common Error Display Component.
*/
Vue.component('spark-errors', {
props: ['form'],
template: "<div><div class='alert alert-danger' v-if='form.errors.length > 0'>\
<strong>Whoops!</strong> There were some problems with your input.<br><br>\
<ul>\
<li v-for='error in form.errors'>\
{{ error }}\
</li>\
</ul>\
</div></div>"
});
Now the Vue files which piece all of this together (in the correct order):
app.js:
require('./core/dependencies');
if ($('#spark-app').length > 0) {
new Vue(require('./core/spark.js'));
}
core/dependencies.js:
/*
* Load Vue & Vue-Resource.
*
*/
if (window.Vue === undefined) window.Vue = require('vue');
require('vue-resource');
Vue.http.headers.common['X-CSRF-TOKEN'] = Spark.csrfToken;
/*
* Load Underscore.js, used for map / reduce on arrays.
*/
if (window._ === undefined) window._ = require('underscore');
/*
* Load jQuery and Bootstrap jQuery, used for front-end interaction.
*/
if (window.$ === undefined || window.jQuery === undefined) window.$ = window.jQuery = require('jquery');
require('bootstrap-sass/assets/javascripts/bootstrap');
core/spark.js:
/*
* Load the Spark components.
*/
require('./components');
/**
* Export the Spark application.
*/
module.exports = {
el: '#spark-app',
/*
* Bootstrap the application. Load the initial data.
*/
ready: function () {
$(function() {
$('.spark-first-field').filter(':visible:first').focus();
});
}
}
and core/components.js:
require('./../auth/registration/subscription');
require('./../common/errors');
I had the same issue, and instead of using the out of the box errors from spark, I defined my own component:
<template>
<div v-if="errors">
<div class="alert alert-danger" v-if="formattedErrors.length > 0">
<strong>Whoops!</strong> There were some problems with your input.<br><br>
<ul>
<li v-for="error in formattedErrors">
{{ error }}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
props: ['errors'],
computed: {
formattedErrors() {
return this.format(this.errors);
}
},
methods: {
format(errors) {
if (typeof errors === 'undefined') {
return [];
}
if (typeof errors === 'object') {
return _.flatten(_.toArray(errors));
}
}
}
}
</script>
Then you bind in your html:
<form-errors :errors="registerForm.errors"></form-errors>
It makes sense because your component just need the to now about errors, and nothing else about the registerForm.
Hope this helps.
Every time I tried to log in use the following angular js code, it always returns this error "post https //api.parse.com/1/logout 400 (bad request)". And I checked the session and it looked right, just won't redirect. But if I click the submit again, it will log in and redirect, but on a different session (of course).
Please help. Thanks a lot.
My view (logIn.html) looks like this:
<form name="logInForm" class="form-horizontal">
<div class="control-group">
<label class="control-label" for="logInUsername">Username</label>
<div class="controls">
<input type="text" ng-model="user.username" id="logInUsername"/>
</div>
</div>
<div class="control-group">
<label class="control-label" for="logInPassword">Password</label>
<div class="controls">
<input type="password" ng-model="user.password" id="logInPassword"/>
</div>
</div>
<br/>
<div>
<button class="btn btn-primary" ng-click="logMeIn(user)">Log In</button>
Sign Up
</div>
</form>
My controller (logInController.js) looks like this:
(function() {
Parse.initialize("applicationId", "key");
var logInController = function ($scope, $location, $window) {
$scope.logMeIn = function(form) {
Parse.User.logIn(form.username, form.password, {
success: function(user) {
$window.alert("Yay, logged in!");
var sessionToken = Parse.User.current()._sessionToken;
return $location.path("/landing");
},
error: function(user, error) {
$window.alert("Oh, NO");
}
});
};
};
logInController.$inject = ['$scope', '$location', '$window'];
angular.module('customerApp')
.controller('logInController', logInController);
}());
I want to post data to my asp.net webapi controller, by using $save() method that belong to ngResource i am getting this error:
"TypeError: $scope.product.$save is not a function at n.$scope.saveProduct "
when i used $http(), data is getting saved but $save() is giving me error, other methods like $query() and $get() are working properly only $save() is causing an error.
code:
// first file (module)
var app = angular.module('commonServices', ['ngResource'])
.constant('appSettings', {
serverPath: 'http://localhost:29904/'
});
//second file (factory)
(function(){
angular.module('commonServices')
.factory('productResource', ['$resource', 'appSettings', productResource])
function productResource($resource, appSettings) {
return $resource(appSettings.serverPath + "api/Products/:id",
null,
{
'update': { method: 'PUT' },
});
}
}());
// third file (controller)
myApp.controller('editProductController', ['$scope', '$routeParams', '$http', 'productResource',
function ($scope, $routeParams, $http, productResource) {
$scope.num = $routeParams.id;
$scope.alertUser = false;
$scope.saveProduct = function () {
$scope.product.$save(function(data){});
}
};
}]);
// some markup from template
<div class="form-group ">
<label class="col-md-2 control-label"
for="inputProductName">Product Name</label>
<div class="col-md-4">
<input class="form-control"
id="inputProductName"
name="inputProductName"
type="text"
placeholder="Product Name (required)"
required
ng-model="product.productName" />
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label" for="inputProductCode">Product Code</label>
<div class="col-md-4">
<input class="form-control"
id="inputProductCode"
name="inputProductCode"
type="text" ng-model="product.productCode">
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="inputAvailabilityDate">Availability</label>
<div class="col-md-4">
<div class="form-control">
{{product.releaseDate}}
</div>
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label"
for="inputDescription">Description</label>
<div class="col-md-4">
<textarea class="form-control"
id="inputDescription"
name="inputDescription"
placeholder="Description"
rows="3" ng-model="product.description"></textarea>
</div>
<br />
</div>
<div class="form-group">
<div class="col-md-4 col-md-offset-2">
<span>
<button class="btn btn-primary"
style="width:80px;margin-right:10px" ng-click="saveProduct()">
Save
</button>
</span>
to use $save() without calling get what i do is here:
productResource.save($scope.product, function(data) {
});
Thanks #TzachOvadia for providing me a clue :)
Try this:
$scope.product = productResource.get({ id: $scope.num });
$scope.saveProduct = function () {
$scope.product.$save(function (response) {...});
}
I can't seem to find why the "start" and "finish" part of my form isn't being rendered. This is the first time I've ever worked with AngularJS, and after following quite a few tuts online, I used to yo meanjs generator with the articles example. I then took the articles example and tried to port it over to this scheduling thing. It really doesn't matter though, I just want to know why the last two inputs in the form aren't being rendered in my view.
Any help is much appreciated
Here's the code for my view:
<section data-ng-controller="SchedulesController">
<div class="page-header">
<h1>New Schedule</h1>
</div>
<div class="col-md-12">
<form name="scheduleForm" class="form-horizontal" data-ng-submit="create()" novalidate>
<fieldset>
<div class="form-group" ng-class="{ "has-error": scheduleForm.title.$dirty && scheduleForm.title.$invalid }">
<label class="control-label" for="title">Title</label>
<div class="controls">
<input name="title" type="text" data-ng-model="title" id="title" class="form-control" placeholder="Title" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="content">Content</label>
<div class="controls">
<textarea name="content" data-ng-model="content" id="content" class="form-control" cols="30" rows="10" placeholder="Content"></textarea>
</div>
</div>
<div class="form-group">
<label class="control-label" for="start">Start</label>
<div class="controls">
<input name="finish" value="" type="date" data-ng-model="start" class="form-control" required>
</div>
</div>
<div class="form-group">
<label class="control-label" for="finish">Finish</label>
<div class="controls">
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
</div>
</div>
<div class="form-group">
<input type="submit" class="btn btn-default">
</div>
<div data-ng-show="error" class="text-danger">
<strong data-ng-bind="error"></strong>
</div>
</fieldset>
</form>
</div>
</section>
Here's the code for my controller:
'use strict';
angular.module('schedules').controller('SchedulesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Schedules',
function($scope, $stateParams, $location, Authentication, Schedules) {
$scope.authentication = Authentication;
$scope.create = function() {
var schedule = new Schedules({
title: this.title,
content: this.content,
start: this.start,
finish: this.finish
});
schedule.$save(function(response) {
$location.path('schedules/' + response._id);
console.log('hola!');
$scope.title = '';
$scope.content = '';
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.remove = function(schedule) {
if (schedule) {
schedule.$remove();
for (var i in $scope.schedules) {
if ($scope.schedules[i] === schedule) {
$scope.schedules.splice(i, 1);
}
}
} else {
$scope.schedule.$remove(function() {
$location.path('schedules');
});
}
};
$scope.update = function() {
var schedule = $scope.schedule;
schedule.$update(function() {
$location.path('schedules/' + schedule._id);
}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
$scope.find = function() {
$scope.schedules = Schedules.query();
};
$scope.findOne = function() {
$scope.schedule = Schedules.get({
scheduleId: $stateParams.scheduleId
});
};
}
]);
Um... Well guys.... I don't know WHY this worked, and everything in me tells me this wasn't the problem, BUT:
Notice line
<input name="finish" value ="" type="date" data-ng-model="finish", class="form-control" required>
The "," was a mistake (I wrote a script that ported everything from articles into schedule, maintining code structure and just changing all mentions of [Aa]rticle{s} -> [Ss]chedule{s}, and this was left over in that (for some reason, don't know where it came in). Anyway, I deleted the comment and ran grunt build && grunt test && grunt and it worked. I'm now getting the correct render.