I have a one-page application using angularJS.
I have in my controller a user object defined like this :
this.user = {
'name':'Robert',
'age':'30'
}
I made a form to update those informations prefilled with those user's informations on my page such like this :
<form name="userForm" ng-submit="userForm.$valid && pageCtrl.userForm(user)" novalidate>
<label for="name">Name *</label>
<input type="text" name="name" ng-model='pageCtrl.user.name' class="form-control" required/>
<label for="age">Age *</label>
<input type="text" name="age" ng-model='pageCtrl.user.age' class="form-control" required/>
<span ng-if='!userForm.$valid' class="error">Invalid form</span>
<input type="submit" value="Save my informations" class="btn btn-success"/>
</form>
My problem is the following : in the header bar of the page the username is displayed ({{pageCtrl.user.name}}).
When the user acts on the form by changing his name, this is updating before the form is saved.
I'd like to wait for the form submission to see the username updated. But i still want to get my form prefilled with user's informations.
Do you have any idea about how to do this?
Thank you by advance
You can use a copied object to only apply the changes when the user save the form :
var app = angular.module('app', []);
app.controller('pageCtrl', function() {
var vm = this;
vm.user = {
'name':'Robert',
'age':'30'
};
vm.tmpUser = {};
vm.update = function() {
vm.user = angular.copy(vm.tmpUser);
};
vm.reset = function() {
vm.tmpUser = angular.copy(vm.user);
};
vm.reset();
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="app" ng-controller="pageCtrl as pageCtrl">
<form name="userForm" ng-submit="userForm.$valid" novalidate>
<label for="name">Name *</label>
<input type="text" name="name" ng-model='pageCtrl.tmpUser.name' class="form-control" required/>
<label for="age">Age *</label>
<input type="text" name="age" ng-model='pageCtrl.tmpUser.age' class="form-control" required/>
<span ng-if='!userForm.$valid' class="error">Invalid form</span>
<input type="submit" ng-click="pageCtrl.update()" ng-disabled="!userForm.$valid" value="Save my informations" class="btn btn-success" />
</form>
<pre>user = {{pageCtrl.user | json}}</pre>
<pre>tmpUser = {{pageCtrl.tmpUser | json}}</pre>
</body>
Use your ng-model to bind to a temp object , like :
this.tmpUser = {
'name':'Robert',
'age':'30'
}
Your form would be:
<form name="userForm" ng-submit="userForm.$valid && pageCtrl.userForm(user)" novalidate>
<label for="name">Name *</label>
<input type="text" name="name" ng-model='pageCtrl.tmpUser.name' class="form-control" required/>
<label for="age">Age *</label>
<input type="text" name="age" ng-model='pageCtrl.tmpUser.age' class="form-control" required/>
<span ng-if='!userForm.$valid' class="error">Invalid form</span>
<input type="submit" value="Save my informations" class="btn btn-success"/>
</form>
keep your user object :
this.user = {
'name':'Robert',
'age':'30'
}
And when you submit the form, update the user object.
Let's say this is your header,
<header><span ng-show="pageCtrl.formSubmitted">{{ pageCtrl.user.name }}</span></header>
In the pageCtrl.userForm(user) function just make the pageCtrl.formSubmitted true once your form is successfully submitted. Cool things, is you can use this boolean for other purposes as well.
Related
<form id="projectForm" onsubmit="return ptitle.value = new Project(this);">
<div class="form-row">
<label for="ptitle">Title: </label>
<input type="text" id="ptitle" name="ptitle"><br>
</div>
<div class="form-row">
<label for="pdescription">Discription: </label>
<input type="text" id="pdescription" name="pdescription"><br>
</div>
<div class="form-row">
<label for="pdueDate">Due Date</label>
<input type="date" id="pdueDate" name="pdueDate"><br>
</div>
<div class="form-row">
<label for="high">High</label>
<input type="radio" id="high" name="priority">
<label for="low">Low</label>
<input type="radio" id="low" name="priority"><br>
<input id="submit" type="submit" value="submit">
</div>
</form>
So I would like to take the data submitted from this form and call a constructor method within the Projects class. I'd also like to be able to dynamically generate the variable name from the title value of the form. Here's the JavaScript code. I'll need to use plain JS as that is what's required for the project! We're also required to use a constuctor class or factory function to generate the projects. As you can see I've tried to take a stab at it but unfortunately it hasn't worked. Thanks in advance.
class Project {
constructor(form) {
this.title = form.ptitle.value;
this.description = form.pdescription.value;
this.dueDate = form.pdueDate.value;
this.priority = form.priority.value;
}
todoList = {};
addTodoList(value, description) {
this.todoList[value] = description;
}
removeTodoList(key) {
delete this.todoList[key];
}
}
Thanks again!!!
I'd also like to be able to dynamically generate the variable name from the title value of the form That sounds like a terrible idea...
Well here you go
class Project {
constructor(form) {
this.title = form.ptitle.value;
this.description = form.pdescription.value;
this.dueDate = form.pdueDate.value;
this.priority = form.priority.value;
}
todoList = {};
addTodoList(value, description) {
this.todoList[value] = description;
}
removeTodoList(key) {
delete this.todoList[key];
}
}
<form id="projectForm" onsubmit="window[ptitle.value] = new Project(this);return false">
<div class="form-row">
<label for="ptitle">Title: </label>
<input type="text" id="ptitle" name="ptitle"><br>
</div>
<div class="form-row">
<label for="pdescription">Discription: </label>
<input type="text" id="pdescription" name="pdescription"><br>
</div>
<div class="form-row">
<label for="pdueDate">Due Date</label>
<input type="date" id="pdueDate" name="pdueDate"><br>
</div>
<div class="form-row">
<label for="high">High</label>
<input type="radio" id="high" name="priority">
<label for="low">Low</label>
<input type="radio" id="low" name="priority"><br>
<input id="submit" type="submit" value="submit">
</div>
</form>
I created a registration page, and each field requires entry and validation. I used the onsubmit event to call my js function to validate the form if the field is empty, however it still submits even though it has not been validated properly.
function validate() {
var streetName = document.getElementById("sN").value;
if (streetName == "" || streetName == null || streetName == undefined) {
window.alert("Sorry");
return false;
}
}
<form name="myForms" action="https://httpbin.org/post " method="post" class="form" onsubmit="return validate()">
<div id="fN">
<label>First Name</label>
<input type="text" name="firstName" placeholder="Enter first name" required>
</div>
<br>
<div class="lN">
<label>Last Name</label>
<input type="text" name="lastName" placeholder="Enter last name" required="">
</div>
<br>
<div class="sN">
<label>Street name</label>
<input type="text" name="streetname" placeholder="Enter your street name">
</div>
// Somemore inputs
<input class="buttons" type="submit" name="submit" value="Sign up" onclick="validate()">
</form>
I expect a window to pop up saying "this entry is wrong and for this reason", but it submits anyway
EDIT: I apologize I should've been clearer in my post. I will use required in some of the inputs, however I will eventually need to write js code to ensure a phone number is all digits and password = passwordconfirm and a postal code is an actual postal code. In the JS file I just showed what I basically tried doing.
Several things
You have validate on the submit AND on the form submit
You should NEVER call anything in a form "submit" since it will hide the submit event/method
You need to get the correct field
Give the form an ID and use unobtrusive code like this
window.addEventListener("load", function() {
document.getElementById("myForm").addEventListener("submit", function(e) {
var errors = false;
var streetName = this.streetname.value.trim(); // no more action needed
if (!streetName) errors = true;
// more validations
if (errors) {
window.alert("Sorry");
e.preventDefault();
}
});
});
<form id="myForm" action="https://httpbin.org/post " method="post" class="form">
<div id="fN">
<label>First Name</label>
<input type="text" name="firstName" placeholder="Enter first name" >
</div>
<br>
<div class="lN">
<label>Last Name</label>
<input type="text" name="lastName" placeholder="Enter last name" >
</div>
<br>
<div class="sN">
<label>Street name</label>
<input type="text" name="streetname" placeholder="Enter your street name">
</div>
<input class="buttons" type="submit" name="SubmitButton" value="Sign up">
</form>
var streetName = document.getElementById("sN").value;
There is no element with that id in the document.
There is an element with sN as its class name, but getElementById won't find an element by its class and the value of <div class="sN"> will always be undefined. It is the input that will have a value.
I am creating basic angular form and onsubmit trying to retrieve the form value, but my case instead of getting value I am getting value as object.
Note: copied the code with some example.
can you please let me know why i am getting object instead of value?
Please find my below code:
html:
<div class="container">
<h2> User Data </h2>
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value)">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ngModel>
</div>
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" ngModel>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
component:
onSubmit(value: any) {
console.log("Form Value : " + value);
}
Your userForm.value contains two values which are name and email.
So when you do console.log(userForm.value);, it will return something like this:
{
name: 'Surjeet',
email: 'suri#yopmail.com'
}
To access the particular value you can do:
userForm.value.name => It will return 'Surjeet'
userForm.value.email => It will return 'suri#yopmail.com'
So what you can do now:
Two things you can do in your case:
First one: (get the value by its property)
onSubmit(value: any) {
//get the value by its property
console.log("Name: " + value.name);
console.log("Email: " + value.email);
}
Second one: (pass only those value which you need)
//(ngSubmit)="onSubmit(userForm.value.name)"
<div class="container">
<h2> User Data </h2>
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value.name)">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ngModel>
</div>
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" ngModel>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
The value has to be an object. The form contains multiple elements , hence has multiple values.
Try this:
onSubmit(value: any) {
console.log("Form Value : ",value);
console.log(value.name);
console.log(value.email);
}
Your input field should be something like this:
<input class="form-control" type="text" [(ngModel)]="name" formControlName="name">
and then in submit function get it's value like
onSubmit(post){
console.log(post.name);
}
--> in HTML file
<div class="container">
<h2> User Data </h2>
<form #userForm="ngForm" (ngSubmit)="onSubmit(userForm.value.name,userForm.value.email)">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" name="name" ngModel>
</div>
<div class="form-group">
<label>Email</label>
<input type="text" class="form-control" name="email" ngModel>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
--> in TS file
onSubmit(name:any, email:any) {
console.log('Name = ' + name);
console.log('Email = ' + email);
}
--> By this code you can get specific value in form either by button triggering (should mention required properties to submit and also in receiving method) or by entire form submit.
I created a php form that works well.
BUT, (yes there is always a BUT) I handle the submit event to call a link that insert datas in another database.
When Js run, my form creates a lot of empty lines in my personal database. I don't understand why.
I give you my code :
PHP :
public function displayForm() {
$output = '<div id="form-popup-newsletter">
<center>
<form id="nl_form" method="post">
<legend>Abonne-toi à la Newsletter<span id="cross-close">X</span></legend>
<div class="btn-group" data-toggle="buttons">
<label class="btn btn-primary">
<input id="civility" type="radio" name="civility" value="madame"> Madame
</label>
<label class="btn btn-primary">
<input id="civility" type="radio" name="civility" value="monsieur"> Monsieur
</label>
</div>
<div>
<label for="surname">Prenom</label>
<input id="surname" type="text" name="surname" value="Surname" />
<span id="w-surname"></span>
</div>
<div>
<label for="name">Nom</label>
<input id="name" type="text" name="name" value="Name"/>
<span id="w-name"></span>
</div>
<div>
<label for="birthdate">Date de Naissance</label>
<input id="birthdate" type="date" name="birthdate" value="Date de naissance"/>
<span id="w-birthdate"></span>
</div>
<div>
<label for="mail">Email</label>
<input id="mail" type="email" name="mail" value="Email"/>
<span id="w-mail"></span>
</div>
<div>
<label for="postal_code">Code Postal</label>
<input id="postal_code" type="number" name="postal_code" value="Code Postal"/>
<span id="w-postal_code"></span>
</div>
<input id="#submitform" type="submit" name="submitform" value="Sauvegarder" class="btn btn-danger" /> </form>
</center>
</div>';
$objForm = new CustomForm;
if ( isset( $_POST['submitform'] ) ) {
if (isset($_POST['civility'])) {
$objForm->civility = $_POST['civility'];
}
$objForm->surname = $_POST['surname'];
$objForm->name = $_POST['name'];
$objForm->birthdate = $_POST['birthdate'];
$objForm->mail = $_POST['mail'];
$objForm->postal_code = $_POST['postal_code'];
}
$this->fillDB($objForm);
$this->context->smarty->assign(array(
'output' => $output
));
}
Javascript :
$("#nl_form").submit(function(e){
e.preventDefault();
var civility = $('#civility').val();
var surname = $('#surname').val();
var name = $('#name').val();
var birthdate = $('#birthdate').val();
var mail = $('#mail').val();
var postal_code = $('#postal_code').val();
window.open("http://mylink.com/register.php?inp_46="+civility+"&inp_1="+surname+"&inp_2="+name+"&inp_4="+birthdate+"&inp_3="+mail+"&inp_13="+postal_code+"");
return true;
});
Best.
When you open a link with window.open then you make a HTTP GET Request. So you have to use $_GET[...] to get the value of your parameters. E.g. for surname $_GET["inp_1"].
But don't use window.open for that instate make a Ajax request.
Here some usefull links
https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
http://jquery.com/ http://api.jquery.com/jQuery.post/
I have a view that is modeled to functions which pass data through to a database. This is all working and I see the data coming back when called, but it is not pre-populating the fields in my view when it comes back. I've been banging my head for a while on this. Everything is modeled (from what I can tell) properly.
I have stepped through the JS code below in Chrome and see the data being assigned to my $scope variables from the data.XXX return.
But, after load finishes, it's not preselecting my radio button or populating the fields with the data. Any help greatly appreciated.
Here is the View:
<div class="notification-container">
<form name="notificationForm" class="form-horizontal" ng-submit="saveQrNotifications()">
<div class="list-unstyled">
<input id="text" ng-model="NotificationMethods.NotificationMethodId" ng-change="notifyVisible()" name="text" type="radio" ng-value="1001"> Text Message<br>
<input id="email" ng-model="NotificationMethods.NotificationMethodId" ng-change="notifyVisible()" name="email" type="radio" ng-value="6"> Email<br>
<input id="voice" ng-model="NotificationMethods.NotificationMethodId" ng-change="notifyVisible()" name="voice" type="radio" ng-value="1003"> Voice<br>
<input id="nocontact" ng-model="NotificationMethods.NotificationMethodId" ng-change="notifyVisible()" name="nocontact" type="radio" ng-value="1000"> Do Not Contact<br>
</div>
<div class="col-md-12 notification-fields" ng-show="notifyFieldVisibility == true">
<div class="col-md-12" ng-if="NotificationMethods.NotificationMethodId == '1001'">
<label class="notication-input">Text Number</label>
<span class="clearfix"></span>
<input class="form-control area-code" type="text" ng-model="NotificationMethods.NotificationTextAreaCode" placeholder="(555)" required>
<input class="form-control phone-number" type="text" ng-model="NotificationMethods.NotificationTextPhoneNumber" placeholder="555-5555" required>
</div>
<div class="col-md-12" ng-if="NotificationMethods.NotificationMethodId == '6'">
<label class="notification-input" for="email">E-mail Address
<input class="form-control" id="email" name="email" type="text" ng-model="NotificationMethods.NotificationEmailAddress" placeholder="ex.me#example.com" required>
</label>
</div>
<div class="col-md-12" ng-if="NotificationMethods.NotificationMethodId == '1003'">
<label class="notication-input">Voice Number </label>
<span class="clearfix"></span>
<input class="form-control area-code" type="text" ng-model="NotificationMethods.NotificationVoiceAreaCode" placeholder="(555)" required>
<input class="form-control phone-number" type="text" ng-model="NotificationMethods.NotificationVoicePhoneNumber" placeholder="555.5555" required>
<label class="small">Ext.</label>
<input class="form-control extension" type="text" ng-model="NotificationMethods.NotificationVoiceExtension" placeholder="555">
</div>
<span class="clearfix"></span>
<div ng-show="notifyLoading" class="text-center" style="margin-top: 10px;">
<i class="fa fa-spinner fa-spin"></i> Saving...
</div>
<div class="col-md-12">
<button type="submit" class="btn btn-primary notification-btn">Save Notifications</button>
</div>
</div>
</form>
</div>
Here is my controller:
DATA COMING FROM DB:
if (data.StatusCode == "SUCCESS") {
$scope.refill = data;
//$scope.deliverTypes = data.DeliveryTypes;
$scope.showError = false;
$scope.submitRefill = true;
$scope.findRefillStatus = userMessageService.QuickRefillMessage(data.Prescriptions[0]);
$scope.isRefillable = data.Prescriptions[0].IsRefillable;
$scope.prescription.noPrescription.$valid = true;
$scope.loading = false;
$scope.NotificationMethods.NotificationEmailAddress = data.NotificationEmailAddress;
$scope.NotificationMethods.NotificationMethodId = data.NotificationMethodId;
$scope.NotificationMethods.NotificationTextAreaCode = data.NotificationTextAreaCode;
$scope.NotificationMethods.NotificationTextPhoneNumber = data.NotificationTextPhoneNumber;
$scope.NotificationMethods.NotificationVoiceAreaCode = data.NotificationVoiceAreaCode;
$scope.NotificationMethods.NotificationVoicePhoneNumber = data.NotificationVoicePhoneNumber;
$scope.NotificationMethods.NotificationVoiceExtension = data.NotificationVoiceExtension;
}
Figured it out. I was declaring the controller on the view used in ng-include. Removing that and letting the view inherit controller from surrounding view solved issue.