Angular JS: Validate form fields before submit - javascript

I'm building an Angular JS app with a 2-step form. It's really just one form, but uses JavaScript to hide the first panel and show the second when the user clicks the 'next' button and moves on to step 2. I have set 'required' validations on some of the fields in step 1, but obviously, they do not get validated when the user clicks the 'next' button...they get validated when the 'submit' button is clicked at the end of step 2.
Is there any way I can tell angular to validate those fields in the form when the 'next' button is clicked?

I suggest to use sub-forms. AngularJS supports putting one form inside another, and validity is propagated form lower form to upper;
Here is example: http://plnkr.co/edit/SruBmlGZZtbwiU8cktAp?p=preview
Here is some code so you can grasp the idea:
<form name='myform' ng-init="step = 1">
<div ng-show="step==1">
<h3>Step 1: Enter some general info</h3>
<div ng-form='step1form'>
Name: <input ng-model="name" required>
</div>
<button ng-disabled="!step1form.$valid" ng-click="step = 2">Next</button>
</div>
<div ng-show="step==2">
<h3>Step 2: Final info</h3>
<div ng-form="step2form">
Phone: <input ng-model="phone" required>
</div>
<button ng-click="step = 1">Prev</button>
<button ng-disabled="!myform.$valid" ng-click="submit()">Submit</button>
</div>
<div>
Validation status:
<div> Whole form valid? {{myform.$valid}} </div>
<div> Step1 valid? {{step1form.$valid}} </div>
<div> Step2 valid? {{step2form.$valid}} </div>
</div>
</form>

Related

Dynamically enable/disable SUBMIT button in twig

Facing an issue that I could easily solve with the help of JS, but failing to do it in twig. I have a couple of fields in twig, and a submit button. I would want to validate these fields' data in frontend before actually submitting them, and have the "Submit" button disabled as long as the condition is unsatisfacatory. The problem in case:
<div class="col-lg-12">
<div class="form-group field">
<label>Description:</label>
<textarea model="description" name="description"></textarea>
</div>
</div>
<div class="col-lg-6">
// checking if user has forgotten to add description, to prevent data submitting
<button type="submit" class="btn btn-default blue" {% if description == "" } % disabled="disabled" {% endif %}>
Submit
</button>
</div>
In JS or AngularJSi could easily solve this problem, but is there any means of achieving the same result in Twig? I need it to check the status of description dynamically and react accordingly.
Already tried:
min-length - does not prevent submitting, only colors the field after it is activated, does not work
Is there any means to do it? Thank you in advance!

Preventing form submission on Enter key press in Angular

There are so many answers for this on stackoverflow. But unfortunately none of them is working for me. I will tell you what I have tried one by one.
<form (keydown.enter)="$event.preventDefault()" ...>
<button (keyup.enter)="skillsHandleEnter($event, skillString)"></button>
#Component(...)
class MyComponent {
skillsHandleEnter(event, skillString) {
event.preventDefault();
// ... your logic
}
}
But none of the approach is working. I am using ngx-tags-input which allows me to apply some tags separated by enter key. This creates a problem. The moment I press Enter key, my form gets submitted with just one tag that i was able to enter. Trust me I've tried almost everything to prevent this and also I dont want to over complicate the things. Please ignore naming conventions. I will fix them later.
Here's my blog.component.html before implementing any solution.
<form [formGroup]="editorForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="exampleInputEmail1">
<h3>Title</h3>
</label>
<input type="text" class="form-control" id="inputTitle" aria-describedby="emailHelp" placeholder="Enter a question that explains your problem exactly">
<br>
<label for="editor">
<h3>Editor</h3>
</label>
<quill-editor [styles]="editorStyle" [modules]="config" formControlName="editor"></quill-editor>
</div>
<ngx-tags-input class="form-control input-lg" name="tags"></ngx-tags-input>
<button class="btn btn-primary mt-3 mb-3">Submit</button>
</form>
Please correct me.
I followed these two simple steps:
1) I added an attribute in my form tag.
(keydown.enter)="$event.preventDefault()"
2) Added (click) listener on the submit button
So the entire HTML code looks like:
<div class="container">
<div class="row pt-5">
<div class="col-md-12 col-lg-12 col-sm-12 bg-light">
<form [formGroup]="editorForm" (keydown.enter)="$event.preventDefault()">
<div class="form-group">
...
</div>
<button class="btn btn-primary (click)="onSubmit()">Submit</button>
</form>
</div>
</div>
</div>
The problem was that I was using click listener with the form tag itself along with keydown.enter.
the html button element has a three valid type
submit : the button submits the form data to the server. This is the default 🔥🔥 if the attribute is not specified, or if the attribut is dynamically changed to an empty or invalid value.
reset: The button resets all the controls to their initial values,
like . button: The button has no default
behavior and does nothing when pressed. It can have client-side
scripts associated with the element's events, which are triggered
when the events occur.
button: the button has no default behavior and does nothing when
pressed. It can have client-side scripts associated with the
element's events, which are triggered when the events occur.
so to solve the probleb just set the button type to button like this
<button type="button" (click)="onSubmit()" class="btn btn-primary mt-3 mb-3">Submit</button>
The only reason to use ngSubmit is to submit the form on "enter".
So you can remove the ngSubmit event listening and replace it by the click event of the button. I also removed the submit emitting from the button by adding type="button".
<form [formGroup]="editorForm">
<div class="form-group">
<label for="exampleInputEmail1">
<h3>Title</h3>
</label>
<input type="text" class="form-control" id="inputTitle" aria-describedby="emailHelp" placeholder="Enter a question that explains your problem exactly">
<br>
<label for="editor">
<h3>Editor</h3>
</label>
<quill-editor [styles]="editorStyle" [modules]="config" formControlName="editor"></quill-editor>
</div>
<ngx-tags-input class="form-control input-lg" name="tags"></ngx-tags-input>
<button type="button" (click)="onSubmit()" class="btn btn-primary mt-3 mb-3">Submit</button>
</form>

How to Enable and Disable Submit Button Using Jquery/Javascript

this is my code i want to have disable submit button after page load and enabled button when im typing in the textbox. pls help thanks
<div class="container" id="frmtoken">
<form method=POST action="authorize.php">
<div class="featured-desc-left">
<p>Enter token and wait to be connected.</p>
<p><strong>note: Only one device per token is allowed</strong></p>
</div>
<div class="two columns featured-desc-left">
<p><input type="text" name="token"></p>
</div>
<div class="featured-desc-left">
<p>
<input name="tconnect" type="submit" value="Connect"
onClick="this.form.submit(); this.disabled=true; this.value='Sending...';"/>
</p>
</div>
</form>
</div>
jQuery
$(document).ready(function(){
$("input[type=submit]").attr("disabled","disabled");
});
$("input[type=text]").on("keydown",function(){
$("input[type=submit]").removeAttr("disabled");
});
Bearing in mind this will apply to all submit inputs on the page when any text inputs on the page are typed in so you probably should assign classes/ids.

AngularJS form validation failing when input populated dynamic

I have the following form:
If I click on a star, the input will be automatically populated with the number of the clicked star. (clicking on the 3rd star the input will be populated with number '3' like in the image bellow)
The input bellow the stars is ng-required="true".
<form name="completeSurveyForm" role="form" novalidate ng-submit="vm.save()">
<ul class="question-list">
<li data-ng-repeat="question in vm.survey.questions | orderBy:'conditionalOrderId' track by question.id ">
<small class="label label-primary pull-right">{{question.questionTypeName}}</small>
<h3>
<b>{{$index +1 }}.</b> {{question.questionBody}}
</h3>
<hr> <!-- Replace here with directives -->
<div data-ng-switch="question.questionType">
<numericrange question="question" data-ng-switch-when="NUMERIC_CHOICE" />
</div>
</li>
</ul>
<button type="submit" ng-disabled="completeSurveyForm.$invalid " class="btn btn-primary">
<span data-translate="fqApp.business.form.submit">Submit</span>
</button>
</form>
And the numericrange directive looks like this:
<div class="row">
<div class="col-md-2" ng-if="!completed">
<div>
<span ng-mouseover="showHovered($event)" ng-mouseleave="clearStars($event)" ng-click="selectStar($event)"
data-ng-repeat="sym in range(startNonActive(question), question.maxValue, 1)" class="{{question.symbol}} starred-element" value="{{$index}}">
</span>
<input type="number" name="{{question.id}}"
data-ng-model="question.numericValue"
data-ng-value="numberOfSelectedStars" ng-required="true" />
</div>
</div>
</div>
Getting into the problem:
If I click on a star and the input populates dynamically with a number the form fails to validate like in the image bellow:
I manually write a number in the input the form is valid and I can click the submit button.
But why If I write manually a number in the input, the form gets valid and I can click the 'submit' button and if the input is populated automatically by selecting a star, the form does not validate and I cannot click on the 'submit' button?
While you clicking on star, manually make dirty when value assigned.
angular.forEach($scope.form.$error.required, function(field) {
field.$setDirty();
})
or
You can use $setViewValue(value, trigger) method. This method will be called when a control wants to change the view value.
Refer here

Dynamic form validation using angular 2

I am working on angular 2 application and creating the form fields dynamically(using json) in a subsection template. I wanted to disable submit button when the form is invalid.
<h1>Form Validation</h1>
<div >
<form #loginForm="ngForm">
<subsection [question]="fieldsData"></subsection>
<button type="submit" [disabled]="!loginForm.form.valid">Submit</button>
</form>
</div>
Sub section as it follows
<div *ngFor="let data of question">
<label> {{data.displayName}}</label>
<input type="data.dataType" name="data.fieldId" [(ngModel)]="data.fieldValue" required name="data.fieldId" #name="ngModel">
<div *ngIf="name.errors && (name.dirty || name.touched)" class="alert alert-danger">
<div [hidden]="!name.errors.required">
Name is required
</div>
</div>
<br><br>
I have a requirement where submit button should be enabled after all the required fields are filled
Created plunker link Here
Based on your plunkr I think you'd be better served using a reactive form rather than the template driven form approach you have described, as you are defining your form fields in a model anyway (the fieldsData array defined in AppComponent).
The current template approach isn't giving you the validation behaviour you want as the input fields in the sub-component are not participating in the wider form - if you debug loginForm.value you will see that the name fields are not part of the form - meaning that if you submit the form, the form will not contain the data entered in those fields.
An alternative is to make the sub-component participate in the form by implementing ControlValueAccessor as described here but this adds complexity you may not need.
A simpler way would be (1) use reactive forms or (2) don't use a nested subsection component at all.
<form #loginForm="ngForm">
<div *ngFor="let data of fieldsData">
<label> {{data.displayName}}</label>
<input type="data.dataType" [(ngModel)]="data.fieldValue" required [name]="data.fieldId" #name="ngModel">
<div *ngIf="name.errors && (name.dirty || name.touched)" class="alert alert-danger">
<div [hidden]="!name.errors.required">
{{data.displayName}} is required
</div>
</div>
</div>
<button type="submit" [disabled]="!loginForm.form.valid">Submit</button>
Form contains: {{loginForm.value | json }}
</form>
question.component.html
<form #loginForm="ngForm">
<div *ngFor="let data of question">
<label> {{data.displayName}}</label>
<input type="data.dataType" [(ngModel)]="data.fieldValue" required name="data.fieldId" #name="ngModel">
<div *ngIf="name.errors && (name.dirty || name.touched)" class="alert alert-danger">
<div [hidden]="!name.errors.required">
{{data.displayName}} is required
</div>
</div>
<br><br>
</div>
<button type="submit" [disabled]="loginForm.invalid">Submit</button>
</form>
The above disables the submit button you can use the above to activate using *ngIf. You can also use the above as !loginForm.valid.
app.component.html
<h1>Form Validation</h1>
<subsection [question]="fieldsData"></subsection>

Categories