I am trying to create a multi form/wizard step navigation. I am using ng-switch to create the steps. But I got stuck, this is the relevant code:
HTML:
<div ng-controller="stepCtrl">
<div ng-switch="step">
<div ng-switch-when="1">
<div ng-controller="postAddressDataCtrl">
<form url="users/createaddress" ng-submit="add()">
<label class="input-label">
<span class="label-title">
Line 1
</span>
<input type="text" name="line-1" ng-model="line1" placeholder="Line 1">
</label>
<label class="input-label">
<span class="label-title">
Line 2
</span>
<input type="text" name="line-2" ng-model="line2" placeholder="Line 2">
</label>
<label class="input-label">
<span class="label-title">
City
</span>
<input type="text" name="city" ng-model="city" placeholder="City">
</label>
<label class="input-label">
<span class="label-title">
Postcode
</span>
<input type="text" name="postcode" ng-model="postcode" placeholder="Postcode">
</label>
<label class="input-label">
<span class="label-title">
Country
</span>
<input type="text" name="country" ng-model="country" placeholder="Country">
</label>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<div class="form-group">
{{ Form::button('Save Address', array('type'=>'submit', 'class'=>'btn btn-primary', 'style' => 'width:100%;')) }}
</div>
</form>
</div>
<button ng-click="setStep(2)">Step 2</button>
</div>
<div ng-switch-when="2">
Step 2 - another form
<button ng-click="setStep(1)">Step 1</button>
<button ng-click="setStep(3)">Step 3</button>
</div>
<div ng-switch-when="3">
Step 3 - another form
<button ng-click="setStep(2)">Step 2</button>
</div>
</div>
</div>
Controllers:
stepCtrl
myApp.controller('stepCtrl',function($scope){
$scope.step = 1;
$scope.setStep = function(step){
$scope.step = step;
}
});
postAddressDataCtrl
myApp.controller('postAddressDataCtrl', ['$scope', '$http', 'CSRF_TOKEN', function($scope, $http, CSRF_TOKEN) {
$scope.urlpath = '{{ url('/') }}';
$scope.add = function() {
var line1 = $scope.line1;
var line2 = $scope.line2;
var city = $scope.city;
var postcode = $scope.postcode;
var country = $scope.country;
return $http({
url: "/users/createaddress",
method: "POST",
data: {
'line1': line1,
'line2': line2,
'city': city,
'postcode': postcode,
'country': country,
'_token': CSRF_TOKEN
},
}).success(function(data, status, headers, config) {
console.log(data);
if (data.status == 200) {
// move to the next step
}
}).error(function(data, status, headers, config) {
console.log(data);
});
};
}]);
How can I check if the data entered in the form are valid and if they are then to move in the next step with a single button?
How can I set the step equal to 2 when the data.status is equal to 200, so only then it will move on?
Use Angular's form validation. For example add required to your input field if you want to require the field and ng-minlength or ng-maxlength for character limits. You can also write custom validation if you need specific validation on certain fields.
To change the step you can increment your step variable inside ng-submit.
To increment only if your $http request is successful you can put it directly in your .success function.
<form url="users/createaddress" ng-submit="add()" novalidate>
<label class="input-label">
<span class="label-title">
Line 1
</span>
<input type="text" name="line-1" ng-model="line1" placeholder="Line 1" ng-minlength=3 ng-maxlength=20 required>
</label>
<button type="submit" class="btn btn-primary">Save Address</button>
</form>
postAddressDataCtrl
myApp.controller('postAddressDataCtrl', ['$scope', '$http', 'CSRF_TOKEN', function($scope, $http, CSRF_TOKEN) {
$scope.urlpath = '{{ url('/') }}';
$scope.add = function() {
var line1 = $scope.line1;
var line2 = $scope.line2;
var city = $scope.city;
var postcode = $scope.postcode;
var country = $scope.country;
return $http({
url: "/users/createaddress",
method: "POST",
data: {
'line1': line1,
'line2': line2,
'city': city,
'postcode': postcode,
'country': country,
'_token': CSRF_TOKEN
},
}).success(function(data, status, headers, config) {
console.log(data);
if (data.status == 200) {
// move to the next step
$scope.step += 1;
}
}).error(function(data, status, headers, config) {
console.log(data);
});
};
}]);
Related
My form allows to update and add several emails. The first email field (main email) is mandatory. After filling it's possible to click on a button "Add email" for adding a new email address. By this way it's possible to add 4 others emails (5 emails in total).
The system checks if the format of the email is correct and displays a message if necessary and register the data in a DB.
Here my view (manageContact.html)
<div class="panel-body">
<form name="ContactForm" class="form-horizontal" role="form" novalidate ng-submit="submitForm(contact)">
<!---------------- FOR UPDATING EMAILS FIELDS ------------ START --->
<div ng-repeat="(key, email) in emails | limitTo : 5" style="z-index:6">
<div class="form-group">
<span ng-switch="$index">
<label ng-switch-when="0" for="txtEmail" class="col-sm-2 control-label">Main email</label>
<label ng-switch-default for="txtEmail" class="col-sm-2 control-label">Email {{$index+1}}</label>
</span>
<div class="col-sm-9" ng-switch="$index">
<input ng-switch-when="0" type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter main email"
ng-model="contact.EMAIL">
<input ng-switch-default type="email" class="form-control"
name="txtEmail_{{$index}}" maxlength="100" placeholder="Enter Email {{$index+1}}"
ng-model="contact['EMAIL_'+$index]">
<div class="error-container"
ng-show="ContactForm['txtEmail_' + $index].$dirty && ContactForm['txtEmail_' + $index].$invalid">
<div ng-show="ContactForm['txtEmail_' + $index].$error.email" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
That is not a valid email. Please input a valid email.
</div>
<div ng-show="ContactForm['txtEmail_' + $index].$error.required" class="alert alert-info" role="alert" style="margin-top:10px;">
<span class="glyphicon glyphicon-alert" aria-hidden="true"></span>
<span class="sr-only">Error:</span>
Your email is required.
</div>
</div>
</div>
<div class="col-sm-1" ng-show="$index == 0">
<a href="" ng-click="add()" ng-show="emails.length<5" class="inline btn btn-primary icon_email">
<span class="glyphicon glyphicon-plus icon2"></span><span class="addButton">Add email</span>
</a>
</div>
</div>
</div>
<!---------------- FOR UPDATING EMAILS FIELDS ------------ END --->
</form>
</div>
In order to see all emails registered of the contact, it's necessary with my current script to click on the button "Add email" each time that an email is registered for seeing data.
I would like to display the emails if they exist in the DB - so display each time the row (field + data). If it doesn't exist it's necessary to click on the button for adding an new email.
I have problem for doing that into my ng-switch and I don't how to do that in another way.
Here my controlers "ctrlEditContacts" and module (app.js):
var app=angular.module('ContactsApp', ['ngRoute', 'ui.bootstrap', 'ngDialog']);
app.factory('HttpInterceptor', ['$q', '$rootScope', function($q, $rootScope) {
return {
......
}
};
app.config(function($routeProvider, $httpProvider, ngDialogProvider){
...
});
app.controller('ctrlEditContacts', function ($scope, $routeParams, MyTextSearch, ContactService, ngDialog, $timeout){
//FOR ALLOWING SEVERAL EMAILS
$scope.emails = [
{
}];
$scope.log = function() {
console.log($scope.emails);
};
$scope.add = function() {
var dataObj = {email:''};
$scope.emails.push(dataObj);
}
ContactService.loadPersonById($routeParams.contactId).success(function(contact){
$scope.contact.ID = contact[0].ID;
$scope.contact.EMAIL = contact[0].EMAIL;
$scope.contact.EMAIL_1 = contact[0].EMAIL_1;
$scope.contact.EMAIL_2 = contact[0].EMAIL_2;
$scope.contact.EMAIL_3 = contact[0].EMAIL_3;
$scope.contact.EMAIL_4 = contact[0].EMAIL_4;
})
.error(function (data, status, header, config) {
...
}).finally(function() {
...
});
$scope.submitForm = function(contact){
if($scope.ContactForm.$valid){
ContactService.updatePerson(contact, $routeParams.contactId).success(function(){
alert('Person updated successfully');
})
.error(function (data, status, header, config) {
})
.finally(function() {
});
}
};
});
Sorry if I'm misunderstanding.
In this case, you need to loop for the number of contact's email info.
For example, if you get a kind of data below; you need to loop three times.
$scope.contact.ID = contact[0].ID;
$scope.contact.EMAIL = contact[0].EMAIL; // 'test1#mail.com'
$scope.contact.EMAIL_1 = contact[0].EMAIL_1; // 'test2#mail.com'
$scope.contact.EMAIL_2 = contact[0].EMAIL_2; // 'test3#mail.com'
$scope.contact.EMAIL_3 = contact[0].EMAIL_3; // ''
$scope.contact.EMAIL_4 = contact[0].EMAIL_4; // ''
// So 'emails' should be modified at this timing.
$scope.emails = [];
// Just for loop, so it doesn't matter what value you add.
$scope.emails.push($scope.contact.EMAIL);
$scope.emails.push($scope.contact.EMAIL_1);
$scope.emails.push($scope.contact.EMAIL_2);
After that, changing 'Add email' condition.
ng-show="$index == emails.length - 1"
jsfiddle
I got my angular form all setup and working. The values are set after calling a response to a json request. The form is succesfully populated with the json response. After that i want to 'reset' the form, as in $scope.object.$setPristine. But i get an error:
$scope.object.$setPristine is not a function
I'm using angular 1.4.8.
Here is my HTML:
<div ng-app="myApp" ng-controller="formController" class="ng-scope">
<form name="object" ng-submit="submit()" method="post" action="" novalidate="" class="ng-pristine ng-valid">
<div class="form-group">
<label class="control-label" for="object_name">Name</label>
<input type="text" id="object_name" name="object[name]" ng-model="object.name" class="form-control ng-pristine ng-valid ng-touched" value="Object 2c">
</div>
<div class="form-group">
<label class="control-label" for="object_elements">Elements</label>
<select id="object_elements" name="object[elements][]" ng-model="object.elements" ng-options="opt.id as opt.name for opt in options | orderBy: "id"" class="form-control ng-pristine ng-untouched ng-valid" multiple="multiple"></select></div>
<div class="form-group">
<input ng-disabled="object.$pristine" class="btn btn-primary" value="Save" ng-click="submitForm()">
</div>
</form>
</div>
And here is my .js:
var app = angular.module('myApp', ["ngResource"]).controller('formController', function ($scope, $http, $location) {
var url = $location.absUrl() + '/json'
$http({
method: 'GET',
url: url
}).then(function (response) {
$scope.status = response.status;
$scope.data = response.data;
$scope.object = response.data;
$scope.object.$setPristine();
$('#modal-loading').modal('hide');
}, function (response) {
$scope.data = response.data || "Request failed";
$scope.status = response.status;
$('#modal-loading').modal('hide');
});
});
You overwrite $scope.object with a JSON response, of course it doesn't have any functions attached to it.
$scope.object = response.data;
$scope.object.$setPristine();
This is functionally the same as:
$scope.object = {of_course: "this doesn't work"};
$scope.object.$setPristine();
You probably just need to change your ng-models to reference $scope.data instead of $scope.object
ng-model="data.name"
and then not overwrite your form object.
My way is this...
<form name="newClntForm" id="newClnt" class="add(newClnt, newClntForm)">
<input type="text" class="form-control" ng-model="newClnt.name" placeholder="Contact Person Name" required >
</form>
And Controller Save Function is
function(newClnt, newClntForm){
angular.copy({},newClnt);
// newClntForm is form name
newClntForm.$setPristine();
newClntForm.$setUntouched();
};
I'm trying to make a contact form, and the server side is working pretty well. But I don't know how to connect Angular to the html form and send it with Express. Any would appreciate any help.
My Express
router.get('/sendQuote', function(req, res) {
var data = req.query;
var mailOptions = {
from: 'planacte#gmail.com', // sender address
name: data.contactName,
email: data.contactEmail,
to: data.email, // list of receivers
subject: "Request for a Quote from " + data.contactName, // Subject line
text: data.contactMsg, // plaintext body
html: '<p> email: ' + data.contactEmail +
'</p><p> phone: ' + data.contactPhone + '</p><br>'
+data.contactMsg // html body
};
console.log(mailOptions)
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
});
});
So, my html:
<form id="contact" class="contact-form" ng-submit="sendMail()" novalidate>
<div class="message"></div>
<div class="col-md-5 col-sm-5 col-xs-12 animated hiding" data-animation="slideInLeft">
<div class="form-group">
<input type="text" name="name" class="nameform form-control input-lg" placeholder="name" ng-model="contactName" required>
</div>
<div class="form-group">
<input type="email" name="email" class="emailform form-control input-lg" placeholder="email" ng-model="message.contactEmail" required>
</div>
<div class="form-group">
<input type="text" name="phone" class="phoneform form-control input-lg" placeholder="phone" ng-model="message.contactPhone">
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<div class="form-group">
<textarea name="message" class="messageform form-control input-lg" placeholder="custom text" ng-model="message.contactMsg" required></textarea>
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<input type="submit" class="btn btn-custom up form-button" value="Send Message">
And the main problem is here, how to glue Angular with HTML and Express. I can send emails, but get undefined in the fields of Name, Email and so on. :
app.controller('MainCtrl', ['$scope', '$interval', '$http', '$location', '$anchorScroll',
function($scope, $interval, $http, $location, $anchorScroll) {
$scope.sendMail = function () {
$scope.message = {};
$http.get('/send/sendQuote', $scope.message).
success(function(data, status, headers, config) {
// $scope.message = data.message;
console.log($scope.message)
});
}
}]);
I think you should start by making this request a POST and not a GET request.
router.post('/sendQuote', function(req, res) {
var data = req.body;
var mailOptions = {
from: 'planacte#gmail.com', // sender address
name: data.contactName,
email: data.contactEmail,
to: data.email, // list of receivers
subject: "Request for a Quote from " + data.contactName, // Subject line
text: data.contactMsg, // plaintext body
html: '<p> email: ' + data.contactEmail +
'</p><p> phone: ' + data.contactPhone + '</p><br>'
+data.contactMsg // html body
};
console.log(mailOptions)
// send mail with defined transport object
transporter.sendMail(mailOptions, function(error, info){
if(error){
return console.log(error);
}
console.log('Message sent: ' + info.response);
res.send(200); // let the client know it sent ok.
});
Now, let's take a look at your Angular code. It seems you want the object $scope.message to hold your form fields data. You should define this as an object at the beginning of your controller.
app.controller('MainCtrl', ['$scope', '$interval', '$http', '$location', '$anchorScroll',
function($scope, $interval, $http, $location, $anchorScroll) {
$scope.message = {};
$scope.sendMail = function () {
//$scope.message = {}; -- this was clearing the object
$http.post('/send/sendQuote', $scope.message).
success(function(data, status, headers, config) {
// you can clear $scope.message if you want here
// $scope.message = data.message;
console.log($scope.message)
});
}
}]);
HTML had one ng-model not binding to the message object:
<form id="contact" class="contact-form" ng-submit="sendMail()" novalidate>
<div class="message"></div>
<div class="col-md-5 col-sm-5 col-xs-12 animated hiding" data-animation="slideInLeft">
<div class="form-group">
<input type="text" name="name" class="nameform form-control input-lg" placeholder="name" ng-model="message.contactName" required>
</div>
<div class="form-group">
<input type="email" name="email" class="emailform form-control input-lg" placeholder="email" ng-model="message.contactEmail" required>
</div>
<div class="form-group">
<input type="text" name="phone" class="phoneform form-control input-lg" placeholder="phone" ng-model="message.contactPhone">
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<div class="form-group">
<textarea name="message" class="messageform form-control input-lg" placeholder="custom text" ng-model="message.contactMsg" required></textarea>
</div>
</div>
<div class="col-md-7 col-sm-7 col-xs-12">
<input type="submit" class="btn btn-custom up form-button" value="Send Message">
I am new to angularjs, I am trying to use $http.post and want display the response in the same view or different view by using ng-show directive.
Control is coming to success and displaying divsion and immediatly disappearing. Please help me.
Thanks in advance.
var myapp = angular.module('registrationApp', [ 'ngRoute' ]);
// create angular controller
myapp.controller('mainController', function($scope, $http) {
$scope.regStatus =false;
// function to submit the form after all validation has
// occurred
$scope.submitForm = function() {
user = {
"type" : "admin",
"emailid" : $scope.user.email,
};
var res = $http.post('/fosiness-web/services/user/registeruser', user);
res.success(function(data, status, headers, config) {
alert("Success : " + JSON.stringify({
data : data }));
debugger;
$scope.mydata = data;
$scope.regStatus = true;
});
res.error(function(data, status, headers, config) {
alert("failure message: " + JSON.stringify({
data : data
}));
});
}
});
<div class="container" style="background-color: #E8E8E8;"
ng-app="registrationApp" ng-controller="mainController">
...................
<div class="alert alert-success" ng-show="regStatus">
× Success <strong ng- model="user.message.description">{{mydata}} {{regStatus}}</strong>
</div>
<form id="registrationForm" method="post" method="POST"
novalidate
class="form-horizontal registerForm"
data-bv-feedbackicons-valid="glyphicon glyphicon-ok"
data-bv-feedbackicons-invalid="glyphicon glyphicon-remove"
data-bv-feedbackicons-validating="glyphicon glyphicon-refresh">
<div class="form-group">
<label class="col-sm-3 control-label">Email-Id</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="email"
ng-model="user.email" data-bv-notempty="true"
data-bv-notempty-message="The email address is required and cannot be empty"
data-bv-emailaddress="true"
data-bv-emailaddress-message="The email address is not a valid" />
</div>
......................
<div class="form-group">
<div class="col-sm-9 col-sm-offset-3">
<!-- Do NOT use name="submit" or id="submit" for the Submit button -->
<button type="submit" class="btn btn-info"
ng-click="submitForm()">Sign up</button>
<button type="reset" class="btn btn-warning">Reset</button>
</div>
</div>
</form>
</div>
How do I post data from a form in AngularJS?
<form data-ng-submit="doSomething()">
<input type="text" data-ng-input="do_obj.text"/>
<input type="email" data-ng-input="do_obj.email"/>
<input type="submit" value="Do something"/>
</form>
$scope.doSomething = function () {
$http({url: '/api/oauth2/register', method: 'POST', data: $scope.do_obj}
).then(function (data, status, headers, config) {
$log.info("data = ", data, "status = ", status,
"headers = ", headers, "config = ", config);
}
);
};
Plnkr (bootstrap styled)
See plunker code here
Changed data-ng-input into data-ng-model and updated data-ng-submit to pass in the model into the scope controller for processing.
HTML:
<body data-ng-app>
<div data-ng-controller="DoCtrl" class="container" style="margin: 15px">
<form data-ng-submit="doSomething(do_obj)" role="form" class="form-inline">
<div class="form-group">
<input type="text" data-ng-model="do_obj.bar"
placeholder="Enter text"
/>
</div>
<div class="form-group">
<input class="form-group" type="email"
data-ng-model="do_obj.email"
placeholder="Enter email"
/>
</div>
<div class="form-group">
<input class="btn btn-lg" type="submit"
data-ng-class="{'btn-info': hover}"
data-ng-mouseenter="hover = true"
data-ng-mouseleave="hover = false"
value="Do something"
/>
</div>
</form>
</div>
</body>
The syntax for posting is $http.post({url}, {payload});. I have updated your controller function to take in a parameter to pass to the post.
Controller code:
function DoCtrl($scope, $http, $log) {
$log.info("In DoCtrl");
$scope.do_obj = {};
$scope.doSomething = function (data) {
$http.post('/api/oauth2/register', data)
.success(function(successData){
console.log(successData);
});
}
}