Getting the field of form angular - javascript

I have a form with some fields.
I'm validating the fields with css classes:(if the field is invalid and the user touched it, then input's border-color = red.)
select.ng-invalid.ng-touched,
input.ng-invalid.ng-touched,textarea.ng-invalid.ng-touched {
border-color: red;
}
If the user submits the form without filling one or more field, there would be a danger alert.
HTML:
<div ng-show="formInvalid>
error!
</div>
JS:
if ($scope.pniyaForm.$valid) {
$scope.formInvalid = false;
.....
} else {
$scope.formInvalid = true;
}
But, If the user submits the form and has not touched any of the field, the css classes don't influence.(because user didn't touch...)
I want to add the class in the code.
Does anyone have an idea for an elegant way to do this without writing it on each field separately?

A possible solution:
when you are executing your form function, add the following line into it.
$scope.$apply(function () {});
this line will cause the ng $scope.$watch() run and apply changes if they exist.
may work, may not work, read the following link for deeper understanding of the issue.
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html

Using ng-class validation in angularjs
<div class="form-group">
<label>Name</label>
<input type="text" required ng-model="name" name="name" ng-class="{'has-error': myForm.name.$invalid}" />
</div>
<div class="form-group">
<label>Age</label>
<input type="text" required ng-model="age" name="age" ng-class="{'has-error': myForm.age.$invalid}" />
</div>

If the user submits the form and has not touched any of the field, the css classes don't influence
You need to provide an initial defined value to an ngModel and at least provide the required attribute to an input.
Use ngClass to conditionally apply css classes in case some form parts are invalid
<form name="myform">
<div class="form-group" ng-class="{'has-error': myform.myinput.$invalid}">
<input name="myinput" ng-model="myName" class="...." required>
</div>
....
</form>
....
// in controller
$scope.myName = "cats"; // form is valid
$scope.myName = ""; // form is invalid, and the css class 'has-error' will be applied
Then use ngDisables in your submit button to prevent submission in case the form is invalid
<button type="submit" ng-disabled="myform.$invalid">submit</button>

Related

How do I get the input value from a angular form using javascript

I'm a client from a SaaS in which I can custom code with JS.
With this custom JS feature, I'm trying to extend this form page by validating the typed in data.
I found out that jQuery is available and it looks like they use Angular, which is why I'm struggling cuz I only and barely know JS.
Can I get the input value, in the case Andrew, from the form field 'First Name'?
This is the HTML snippet
<div class="form-group ng-scope" id="" ng-if="[true, undefined].includes(entitiesDataVisibility["c1b99979-6b13-51a3-9c0e-ccb878e76655"])">
<label for="field_56657680-c963-45b1-838c-9894dcdb09d0">First Name<span class="required">*</span>
</label>
<input id="field_56657680-c963-45b1-838c-9894dcdb09d0" ng-model="entitiesData["c1b99979-6b13-51a3-9c0e-ccb878e76655"]" class="form-control ng-valid ng-not-empty ng-dirty ng-valid-parse ng-touched" type="text" name="6da5a22b-8d81-4f76-9e9b-0441e5d48a39">
</div>
If I try to Query Select the input by name (the id is dynamical for some reason) with
console.log($("[name='6da5a22b-8d81-4f76-9e9b-0441e5d48a39']"));
I then get:
I apologize if it's too basic :(
assuming the id doesn't change then
console.log($("#field_56657680-c963-45b1-838c-9894dcdb09d0").val())
that should get the value for you
but if you afer validation angular has build in validaton that would better suited than jquery, look at using somthing like so
import { FormControl, FormGroup, Validators } from '#angular/forms';
...
searchform = new FormGroup({
search: new FormControl('', [Validators.required, Validators.minLength(3)]),
});
get searchControls() {
return this.searchform.controls;
}
....
<form class="form-inline" [formGroup]="searchform">
<input
type="search"
class="form-control"
placeholder="Enter some data"
name="search"
id="search"
formControlName="search"
required
#search />
<div
*ngIf="searchControls['search'].touched
&& searchControls['search'].invalid"
class="alert alert-danger">
<div
*ngIf="searchControls['search'].errors
&& searchControls['search'].errors['required']">
Name is required.
</div>
<div
*ngIf="searchControls['search'].errors
&& searchControls['search'].errors['minlength']">
Name should be 3 character.
</div>
</div>
I hope this helps
Assuming following:
name and id attribute are dynamic
label text has always exact value. i.e. First Name
Input element is always below label field.
You can get the value by $('.form-group label:contains(First Name)').next().val()
So above code will find the label element containing First Name label element and selects the sibling element below it i.e. Input Element
JSfiddle Link
Hope that helps!

Why does myForm.$submitted not work with ng-messages but with ng-if?

I am trying to validate my Form when there is a keypress and also when it its submitted.For that purpose i am writing this code :-
<form name="myForm" ng-submit="submit()" novalidate>
<input type="email" name="email" ng-model="email" required/>
<div ng-messages="myForm.$submitted">
<span ng-message="required">Please enter details in these field</span>
<span ng-message="email">Please enter email</span>
</div>
<button type="submit">Save</button>
</form>
There is a success message in submit function :-
$scope.submit = function(){
console.log("Update Successful");
}
Even if i haven't fill the required field and press Save i still get the "Update Successful" message.So,why doesn't the validation work and why is the submit function even if the validation fails.
Also i found these solution of doing it these way :-
<form name="myForm" ng-submit="myForm.$valid && submit()" novalidate>
<input type="email" name="email" ng-model="email" required/>
<div ng-messages="myForm.email.$error" ng-if="myForm.$submitted">
<span ng-message="required">Please enter details in these field</span>
<span ng-message="email">Please enter email</span>
</div>
<button type="submit">Save</button>
</form>
This works fine but problem is,it should also validated on keypress.However,it only validates on keypress after i have sumbitted the form atleast once before that keypress validation doesn't work.
How should i solve these?
I was also trying myForm.$touched but even that doesn't work when i use it as :-
<div ng-messages="myForm.$touched">
...
</div>
There is a little something that you've missed in implementing AngularJS's form validation.
From the code you've provided, your form, as it seems, is using the default HTML5 form validation and NOT AngularJS form validation.
How?
In order to be able to wire up with AngularJS form validation (technically adding it as a property to the form directive), in addition to the name attribute of the form control, ng-model attribute is also required.
Meanwhile, to disable HTML5 default validation behavior, novalidate attribute must be added to the form tag.
To be able to achieve your expected behavior from the form (i.e. validation on key press as well as on submission, if I'm right) you can implement a combination of yourForm.$dirty and yourForm.$submitted properties:
<div ng-messages="myForm.email.$error" ng-if="myForm.$dirty || myForm.$submitted">
<p ng-message="required">Please enter details in these field</p>
<p ng-message="email">Please enter email</p>
</div>
Demo
Try this:
In html:
<form name="myForm" novalidate>
<input type="email" name="email" required/>
<div ng-messages="myForm.email.$error" ng-if="myForm.email.$touched || valid">
...
</div>
<button ng-click="submit(myForm.$valid)">Save</button>
</form>
In controller:
$scope.submit(valid)
{
valid ? $scope.validCheck = false : $scope.validCheck = true;
}

Manually highlight all invalid inputs of Angular Form

The task is kinda primitive.
I got a simple Angular form with various inputs and I'd like to highlight invalid inputs manually (e.g. on submit action).
I tried to loop over invalid inputs, assuming that they must have some method to highlight an error, but unfortunately they don't.
Same with form. $setDirty() didn't work as well.
I'm using ng-form directive to get access to both form and input.
AngularJS version is 1.2.x.
You form markup should look like, so that when you click on submit ng-class will add submitted class on form that will give you idea that whenever you have submitted class on form and field has ng-invalid class, you can highlight those element
Markup
<ng-form name="form" ng-class="{submitted: submitted}" ng-submit="submitted=true; submit();">
<input type="text" name="firstname" ng-model="formData.firstname">
<input type="text" name="lastname" ng-model="formData.lastname">
<input type="submit" value="submit">
</ng-form>
CSS
.submitted input.ng-invalid {
border: solid 1px red;
}
Use ng-pattern and required it will check you validation. and onSubmiy you can customized your validation also
Example: http://jsfiddle.net/kevalbhatt18/dmo1jg02/
<div ng-app ng-controller="formCtrl">
<form name="myForm" ng-submit="onSubmit()">
<input type="number" ng-model="price" name="price_field" ng-pattern="/^[0-9]{1,7}$/" required>
<span ng-show="myForm.price_field.$error.pattern">Not a valid number!</span>
<input type="submit" value="submit"/>
</form>
</div>
Js
function formCtrl($scope){
$scope.onSubmit = function(){
alert("form submitted");
}
}

Angular is automatically adding 'ng-invalid' class on 'required' fields

I am building an angular app for which I have some forms set up.
I have some fields that are required to be filled before submission. Therefore I have added 'required' on them:
<input type="text" class="form-control" placeholder="Test" ng-model="data.test" required>
However when I launch my app, the fields are displayed as 'invalid' and the classes 'ng-invalid' and 'ng-invalid-required' even before the submit button has been click or before the user has typed anything in the fields.
How can I make sure that thoses 2 classes are not added immediately but either once the user has submitted the form or when he has typed something wrong in the corresponding field?
Since the inputs are empty and therefore invalid when instantiated, Angular correctly adds the ng-invalid class.
A CSS rule you might try:
input.ng-dirty.ng-invalid {
color: red
}
Which basically states when the field has had something entered into it at some point since the page loaded and wasn't reset to pristine by $scope.formName.setPristine(true) and something wasn't yet entered and it's invalid then the text turns red.
Other useful classes for Angular forms (see input for future reference )
ng-valid-maxlength - when ng-maxlength passes
ng-valid-minlength - when ng-minlength passes
ng-valid-pattern - when ng-pattern passes
ng-dirty - when the form has had something entered since the form loaded
ng-pristine - when the form input has had nothing inserted since loaded (or it was reset via setPristine(true) on the form)
ng-invalid - when any validation fails (required, minlength, custom ones, etc)
Likewise there is also ng-invalid-<name> for all these patterns and any custom ones created.
Thanks to this post, I use this style to remove the red border that appears automatically with bootstrap when a required field is displayed, but user didn't have a chance to input anything already:
input.ng-pristine.ng-invalid {
-webkit-box-shadow: none;
-ms-box-shadow: none;
box-shadow:none;
}
Since the fields are empty they are not valid, so the ng-invalid and ng-invalid-required classes are added properly.
You can use the class ng-pristine to check out whether the fields have already been used or not.
Try to add the class for validation dynamically, when the form has been submitted or the field is invalid. Use the form name and add the 'name' attribute to the input. Example with Bootstrap:
<div class="form-group" ng-class="{'has-error': myForm.$submitted && (myForm.username.$invalid && !myForm.username.$pristine)}">
<label class="col-sm-2 control-label" for="username">Username*</label>
<div class="col-sm-10 col-md-9">
<input ng-model="data.username" id="username" name="username" type="text" class="form-control input-md" required>
</div>
</div>
It is also important, that your form has the ng-submit="" attribute:
<form name="myForm" ng-submit="checkSubmit()" novalidate>
<!-- input fields here -->
....
<button type="submit">Submit</button>
</form>
You can also add an optional function for validation to the form:
//within your controller (some extras...)
$scope.checkSubmit = function () {
if ($scope.myForm.$valid) {
alert('All good...'); //next step!
}
else {
alert('Not all fields valid! Do something...');
}
}
Now, when you load your app the class 'has-error' will only be added when the form is submitted or the field has been touched.
Instead of:
!myForm.username.$pristine
You could also use:
myForm.username.$dirty
the accepted answer is correct.. for mobile you can also use this (ng-touched rather ng-dirty)
input.ng-invalid.ng-touched{
border-bottom: 1px solid #e74c3c !important;
}

How to get the values from a form and prevent submission?

I have this simple form:
HTML
<form>
<label for="eName">Name</label>
<input id="eName" type="text" name="eName">
<label for="Email">Email</label>
<input id="Email" type="text" name="Email">
<button id="create" class="boton"
onclick="doSomething();" type="submit">Create!</button>
</form>
JS
function doSomething() {
var name, email;
name = document.getElementById("eName").value;
email = document.getElementById("Email").value;
putElementsIntoTheDOM(name, email);
}
When the user inputs some information I want to populate the DOM with the user input.
The example above works. But I think it can be done better. I just don't know how.
How can I wire the <button> so that when the user clicks it the form values are passed
to the function doSomething()?
Also, since I'm not sending the form values anywhere except populating the DOM, how can I
prevent the submission?
I've seen something like this but I can't get it too work.
<button id="create" class="boton" onclick="doSomething(this.form);"
type="submit">Create!</button>
If you don't want to send the form values anywhere, then you just need to remove type="submit" from your button.
Your example code works fine. I'm not sure what you mean by a 'better' way. More modern/idiomatic javascript would not be using the onclick attribute, but instead binding doSomething to the button. Using jQuery, that would look like:
$("#create").click(doSomething);
First of all you have to update your function declaration to be able to receive the variables you want to send
function doSomething(name,email) {
}
Secondly, if you have to send values of some fields to that function, you can do so on button click like this.
<button id="create" class="boton" onclick="doSomething(document.getElementById('eName').value,document.getElementById('Email').value);" type="submit">Create!</button>
However, using unobtrusive javascript is recommended, and for that jQuery is one of the options you can use for passing variables to your function neatly.
There is a difference between the type="submit" and type="button" that I didn't realize.
Also, the button and submit types react differently with onclick and onsubmit events.
For example
<form onclick="doSomething()">
<label for="eName">Name</label>
<input id="eName" type="text" name="eName">
<label for="Email">Email</label>
<input id="Email" type="text" name="Email">
<button id="create" class="boton" type="button">Create!</button>
</form>
Notice that at the top of the form there is onclick.
The onclick is fired whenever you focus on an input element, and of course if you click the button.
Changing the form to <form onsubmit="doSomething(); but not changing the type="button" doesn't do anything. Clicking the button doesn't trigger the function.
By changing the type="submit"and keeping the head <form onsubmit="doSomething(); triggers the function when the button is clicked. A nice added functionality to this is that if you have any <input ... required="required"> the submit will only work if those fields are filled in (and your form will let you know about the required fields).
To prevent the submission/refreshing (since I'm only populating the DOM with user input) adding return false at the form head prevents submission
<form onsubmit="doSomething(); return false">.
Finally, to get the form values adding this:
<form onsubmit="doSomething(this); return false> and then
function doSommething(formInfo) {
var name = formInfo.eName.value;
var email = formInfo.Email.value;
...
}

Categories