$scope and setPristine() not working inside factory - javascript

I am trying to write convert my current api call into a factory which is reusable inside ApiService factory. However, I can't seem to clear the form.
So, what i can i do to make the clearForm function work as it is.
<form name="formName">
<input type="name" ng-model="form.username"></input>
<input type="password" ng=model="form.password"></input>
<button type="submit" ng-click="submitForm()">Submit</button>
<form>

form is in $scope. You can't access it without using $scope and factory don't have $scope.
try like this
$scope.formName.$setPristine();
All you can do is to pass that form to service and clear it
'clearForm': function(formName) {
formName.$setPristine();
formName.$setUntouched();
}
from controller
FormFactory.clearForm($scope.formName);

Related

How to make the function called by #submit work?

<!--html-->
<div id="vvv">
<form action="#">
<input required type="text">
<input type="submit" #submit="func">
</form>
</div>
// js
vvv = new Vue({
el: '#vvv',
methods: {
func(){
console.log(11111111111111)
}
}
})
How to make the function called by #submit work?
I need use the default submit action to inspect if all required fields have been filled. And after that, i wanna call my own submit function which set by #submit to post form data.
But, i find the function set by #submit is not be allowed to call.
What's wrong with my code? Or, if this action really not be allowed? And how can i realize my requirement?
Try calling the function from form tag
<!--html-->
<div id="vvv">
<form action="#" #submit.prevent="func" >
<input required type="text">
<button type="submit" >Submit</button>
</form>
</div>
If you're trying to do some custom validations, Vue makes it easy to track the state in real time. In the example I threw together below, you can see how a few different fields are simply validated to not be empty.
This is something you would build on, of course, to make more advanced validations, but hopefully it illustrates the concept. Then, you can use whatever method on whatever element you want to submit your form data!
https://codepen.io/barneychampaign/pen/JjKxymg

Displaying value from local storage in Angular Page

This should be something trivial but I can't figure it out for the life of me.
What I need is an input field that is by default filled out for a user from a value from local Storage.
The problem I've run into is that none of the ways I'd normally do this (jQuery onload, JS onload or a (onload) in the HTML tag) seem to be run when a user switches to a different page without reloading. I've also tried ngOnInit() but that seems to be running before the page's DOM Content is ready to be edited and isn't working here.
Here is my code:
<form (submit)="editName($event)">
<div class="form-group">
<label for="nameInput">Name</label>
<!-- I want to insert the localStorage Value user_name into this input -->
<input type="name" class="form-control" id="nameInput" (onload)="initName()">
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
A sad attempt at acheiving this is also in my component.ts:
initName() {
document.getElementById("nameInput").textContent = localStorage.getItem('user_name');
}
The error message in my console is:
ERROR TypeError: Cannot read property 'user_name' of undefined
I would recommend using an Angular ReactiveForm in this case instead of manually retrieving and binding the value.
In your component, create an instance of a FormGroup and bind the value from localStorage to the form control:
#Component({
template: `
<form *ngIf="form" [formGroup]="form" (submit)="editName($event)">
<div class="form-group">
<label for="nameInput">Name</label>
<input formControlName="name" type="name" class="form-control" id="nameInput">
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
`
})
export class YourComponent implements OnInit {
form: FormGroup;
ngOnInit(): void {
this.form = new FormGroup({
name: new FormControl(localStorage.getItem('user_name')),
});
}
}
For more on Reactive forms in Angular, see: https://angular.io/guide/reactive-forms
I'd recommend using Angular Reactive Forms over Template-driven Forms regarding the purpose here. With a Template-driven approach you'll end up setting the localStorage bindings explicitly for every value inside your form. A better alternative is using Reactive Forms. (see Brandon's answer)
Assuming you use a FormGroup for your whole form you can retrieve and save the whole form using the FormGroup.value method that will give you all the values of your form in one step without disabled controls or FormGroup.getRawValue() to also include disabled controls. You can then just use this to store your attributes in the localStorage on form submit:
this.form = new FormGroup({
surName: new FormControl('user_surname'),
name: new FormControl('user_name'),
age: new FormControl('user_age'),
...
});
localStorage.setItem('userFormValues',JSON.stringify(this.form.value));
See how this example looks in your local storage:
This way your local storage will not be messed up with many keys. To read your values back to your form just use JSON.parse in combination with FormGroup.setValue():
this.form.setValue(JSON.parse(localStorage.getItem('userFormValues')));
TS page
init variable
username:string;
create function for fill variable from localstorage
getName(){
this.username = localStorage.getItem("user_name";
}
call variable on page load
onInit(){
this.getName();
}
html page
<input type="name" class="form-control" id="nameInput" value="{{username}}">
In the end I've gone with creating a method called getUsername() in component.ts:
getUsername() {
return localStorage.getItem('user_name');
}
then I bound it to the input using this:
<input type="name" class="form-control" id="nameInput" value="{{getUsername()}}">

Programmatically submit a form from an Angular directive

In my Angular 1.5.X app I have a directive with the following template
<form id="pdfDownloadForm"
name='pdfDownloadForm'
method="POST"
action="{{ downloadUrl }}">
<input type="hidden" name="data" value="" />
<button type="button" ng-click="submit()">Submit</button>
</form>
When the form is submitted, I would like to do the following
Set the value of the hidden parameter data to a value retrieved from a remote service
Submit the form
Attempted Solution
Presumably the easiest way to set the hidden parameter is with
<input type="hidden" name="data" ng-model="dataValue" />
and then before submitting the form, assign to scope.dataValue the value retrieved from the remote service?
I tried to submit the form programmatically with
scope.submit = function () {
$('#pdfDownloadForm').submit();
}
But this causes the following error:
Error: [$rootScope:inprog] $apply already in progress
Since you're using Angular 1.5+, there's no reason to use scope - either use controllerAs syntax or, preferably, components.
I'd implement your task by interrupting first submit call and populating hidden field instead. Any subsequent submits are allowed to happen.
// inside contorller
onSubmit(event) {
if (!this.dataValue) {
event.preventDefault();
this.initializeData();
}
}
initializeData() {
$http.get('/my-data-source').then((response) => {
this.dataValue = response.data.value;
this.pdfDownloadForm.submit(); // requires <form name="$ctrl.pdfDownloadForm">
});
}
See https://docs.angularjs.org/api/ng/directive/ngSubmit
It's better to avoid using ngClick here since form can be submitted by Enter instead of button click.
<button type="button" ng-click="submit">Submit</button>
should be
<button type="button" ng-click="submit()">Submit</button>
so after your edit to your post, this wasn't the solution? have your tried it?

In Angular, how to get a form in $scope in controller?

Having these two files:
HTML:
<form name="registrationForm" ng-submit="registerUser()">
...
</form>
JS (inside the Angular controller):
$scope.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);
I get the error that Cannot read property 'confirmPassword' of undefined
This leads me to believe that I have no access to the form registrationForm in the controller. Based on this (https://docs.angularjs.org/api/ng/type/ngModel.NgModelController) I imagined that I should.
Other solutions that I've seen include passing the form to the controller when the form is submitted, but what I need to do (set custom validation) needs to happen way before that.
Other solution mentioned adding the controller to the form via ng-controller but that changed nothing.
EDIT:
From the website above, is there a reason why in here (https://plnkr.co/edit/ZT0G6ajdbescT72qLKSU?p=preview) $scope.myForm can be accessed, but only inside of the $scope.setEmpty function?
I recommend using the controller itself instead of the $scope provider for this. This was one of the first issues I came across when working with angularjs
In your controller:
function MyController($scope) {
var vm = this;
vm.registrationForm.confirmPassword.$setValidity("PasswordsMatch", $scope.validation.doPasswordsMatch);
}
In your form:
<form name="vm.registrationForm" ng-submit="registerUser()">
...
</form>
The only gotcha is that you need to specify the controllerAs property in your route or ngInclude:
ng-include="templates/my-template.html" ng-controller="MyController as vm"
or
when('/my-route', {
templateUrl: 'templates/my-template.html',
controller: 'MyController as vm'
})
You need to add a name attribute to form element.
<form name="registrationForm" ng-submit="registerUser()">
...
</form>
this form must rely on a controller indeed. please take a look at the example:
angular.module("fooApp",[]);
angular.module("fooApp")
.controller("formctl",function(){
this.user={};
this.dosave=function(){
if(this.user.pwd == this.user.confpwd)
alert(this.user.username+" logged");
else
alert("pwd does not match");
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app="fooApp">
<h1>sample</h1>
<div ng-controller="formctl as ctl">
<form ng-submit="ctl.dosave()">
<label>username</label><br/>
<input ng-model="ctl.user.username" required/><br/>
<label>password</label><br/>
<input ng-model="ctl.user.pwd" type="password" required/><br/>
<label>confirm password</label><br/>
<input ng-model="ctl.user.confpwd" type="password"/><br/>
<input type="submit"/>
</form>
</div>
</div>
You'll want to pass the form into the submit function to pass the entire form into the controller. Use the form name.
<form name="registrationForm" ng-submit="registerUser(registrationForm)">
...
</form>
The other option would be to pass the inputs directly in as params
<form name="myForm" novalidate >
some input: <input type="text" name="sometext" ng-model="myInput">
<input type="submit" ng-click="doAction(myInput)">
</form>
Quick Plunk
https://plnkr.co/edit/s0Al2LTHkvUPoLYNzTpm?p=info
If you're just after the value of the inputs, it's easier to test if you have explicit parameters that you expect on the method instead of dumping in the entire form.

AngularJS validation of asynchronously loaded form

I am building an AngularJS application that includes modal windows which contain forms and are loaded into the DOM asynchronously (when the appropriate button is clicked). The forms work fine, but I cannot properly check if they are valid. Here's an example:
HTML
<div ng-app="myapp" ng-controller="MyCtrl">
<form novalidate name="myform" ng-submit="submitForm(myform)">
<input type="text" required ng-model="myname" />
</form>
</div>
JavaScript
var app = angular.module('myapp', []);
app.controller("MyCtrl", function($scope) {
$scope.submitForm(form) {
if(form.$valid) {
// Do http stuff here
}
};
});
If this form is loaded asynchronously, the form variable has value NaN and form.$valid is undefined. However, if I load it with the rest of the page, it works fine. Does anyone know how to force AngularJS to populate the scope variable for the form? Thanks!
When you include a form using ng-include a childScope is created. The parent and the childScope cant access eachothers scopes. Therefore the .$valid comes up empty.
I had a similiar issue the other day and got a working solution that suited me in this thread:
AngularJS $setValidity on childScope form

Categories

Resources