First of all, thanks for your time reviewing my question and trying to help me. I have been working on an App where I use Materialize CSS form to gather user's inputs. However, I have been having a hard time to validate empty fields when the user press the submit button.
Below is my code, so you can have a better idea of what I have. I need to come up with some javascript to validate empty fields when the user press the submit button on the form. I am having a hard time to create this, since I have nested object to fetch to my API. I tried creating a for in loop to iterate on the object but had no success on it.
Any insights on this would be highly appreciated!
Thanks Again
let btnSave = document.getElementById("btnSaveGift");
btnSave.addEventListener("click", APP.addGift);
addGift() {
//user clicked the save gift button in the modal
let gift = {
name: document.getElementById("name").value,
price: document.getElementById("price").value,
store: {
name: document.getElementById("storeName").value,
productURL: document.getElementById("storeProductURL").value
}
}
//validating the inputs - still working on it.
}
<div class="modal modal-fixed-footer center" id="modalAddGift">
<div class="modal-content">
<h4>New Gift idea</h4>
<p>Why not add another idea?</p>
<form class="col s12">
<div class="row">
<div class="input-field col s12 black-text">
<input id="name" type="text" class="validate black-text" class="validate" required=""
aria-required="true"/>
<label for="name" class="black-text">Idea</label>
<span class="helper-text" data-error="please try again"></span>
</div>
</div>
<div class="row">
<div class="input-field col s12 black-text">
<input id="price" type="number" inputmode="numeric" class="validate black-text" class="validate" required=""
aria-required="true"/>
<label for="price" class="black-text">Price</label>
<span class="helper-text" data-error="invalid price"></span>
</div>
</div>
<div class="row">
<div class="input-field col s12 black-text">
<input id="storeName" type="text" class="validate black-text" class="validate" required=""
aria-required="true"/>
<label for="storeName" class="black-text">Store Name</label>
<span class="helper-text" data-error="please try again"></span>
</div>
</div>
<div class="row">
<div class="input-field col s12 black-text">
<input id="storeProductURL" type="url" class="validate black-text" class="validate" required=""
aria-required="true"/>
<label for="storeProductURL" class="black-text">Website</label>
<span class="helper-text" data-error="invalid URL"></span>
</div>
</div>
</form>
</div>
<div class="modal-footer light-blue">
<a
href="#!"
id="btnSaveGift"
class="modal-close waves-effect waves-green btn-flat white-text"
>Save Gift Idea</a
>
</div>
</div>
Validating your inputs values shouldn't be that difficult, since the addGift() function gets called when the submit button is clicked and the gift objct is generated within it. then your validation can take effect using a simple if statement:
// validating
if(!gift.name || !gift.price
|| !gift.store.name || !gift.store.productURL ){ // This checks for any false value
// What action you want to take goes here
} else{
// What to do when all fields are true goes here!
}
Related
I have a form1 and a add button. The thing I want is to add same form as form2 below form1 on clinking add button. As I am new to Angular Js it will be very helpful if someone can help me out.
HTML
<div class="row">
<header class="panel-heading">
<h5 class="panel-title" style="padding-left: 1.5rem;">
<b>APPLICANTS</b>
<input class="btn btn-primary" style="float:right " type="button" value="Add" />
</h5>
<hr>
</header>
<div class="panel-body">
<div class="container">
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Name</label>
<div>
<input type="text" class="form-control" id="inputDefault" ng-model="txtFullName">
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label class="control-label">Nationality</label>
<div>
<input type="text" class="form-control" id="inputDefault" ng-model="txtNationality">
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="form-group">
<label class="control-label">Pin Code</label>
<div>
<input type="text" class="form-control" id="inputDefault" ng-model="txtPincode">
</div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label class="control-label">House No.</label>
<div>
<input type="text" class="form-control" id="inputDefault" ng-model="txtHouseNo">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You need to create an array of applicants model objects, let's call it applicantsArray, where every object will represent a single applicant form.
You need to initialize this array with one model empty on page load.
Then you need to wrap your form with ng-for and iterate over every applicant model. So the n-th form will be binded with the n-th model in the applicantsArray.
Last step will be to push an empty applicant model to applicantsArray when 'Add' is clicked. Then a new model is added and the DOM will render additional form for the new model.
I have the following HTML code:
<form class="row g-3 needs-validation" novalidate>
<div class="col-md-4">
<label for="validationCustom01" class="form-label">First name</label>
<input type="text" class="form-control" id="validationCustom01" value="Mark" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustom02" class="form-label">Last name</label>
<input type="text" class="form-control" id="validationCustom02" value="Otto" required>
<div class="valid-feedback">
Looks good!
</div>
</div>
<div class="col-md-4">
<label for="validationCustomUsername" class="form-label">Username</label>
<div class="input-group has-validation">
<span class="input-group-text" id="inputGroupPrepend">#</span>
<input type="text" class="form-control" id="validationCustomUsername" aria-describedby="inputGroupPrepend" required>
<div class="invalid-feedback">
Please choose a username.
</div>
</div>
</div>
<div class="col-md-6">
<label for="validationCustom03" class="form-label">City</label>
<input type="text" class="form-control" id="validationCustom03" required>
<div class="invalid-feedback">
Please provide a valid city.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom04" class="form-label">State</label>
<select class="form-select" id="validationCustom04" required>
<option selected disabled value="">Choose...</option>
<option>...</option>
</select>
<div class="invalid-feedback">
Please select a valid state.
</div>
</div>
<div class="col-md-3">
<label for="validationCustom05" class="form-label">Zip</label>
<input type="text" class="form-control" id="validationCustom05" required>
<div class="invalid-feedback">
Please provide a valid zip.
</div>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="" id="invalidCheck" required>
<label class="form-check-label" for="invalidCheck">
Agree to terms and conditions
</label>
<div class="invalid-feedback">
You must agree before submitting.
</div>
</div>
</div>
<div class="col-12">
<button class="btn btn-primary" type="submit">Submit form</button>
</div>
</form>
With the following JavaScript code, to validate the user input. If there are any invalid fields, it should the user stop submitting his request:
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
// putting alert here does not work..?
// something like alert('successfully validated your request!')
}, false)
})
})()
The problem is: I want to alert the user, if the submission was successfully, with the alert() function. But I can't figure out where to put the alert function. I marked the code where I tried putting the alert function into, but it's always triggering even when it's not even validated. Does somebody know what am I doing wrong here? Thank you very much.
I need to disable the textbox inside my angularJS dynamic form after I clicked the button. my code seems to be working fine if I am going to disable textbox outside the dynamic form but when I get the ID of the textbox inside the dynamic form it is not working. What could be the problem.
$scope.copyText = function () {
document.getElementById('copyText').disabled=true;
document.getElementById('bName').disabled=true;
document.getElementById('pName').disabled=true;
// $('#bName').attr('disabled', true);
//alert('#bName');
$scope.LanguageFormData.language = [
{ bName: document.getElementById('brandName').value, pName: document.getElementById('prodName').value, pNameSub: document.getElementById('prodNameSub').value, lFeature: document.getElementById('pfeatureNew').value, lIngredient: document.getElementById('pingredientNew').value, lInstruction: document.getElementById('pinstructionNew').value, languageCat: null }
];
My View looks like this
<div class="col-md-12" class="pull-right" >
<button class="btn btn-primary pull-right" type="button" ng-click="copyText()" id="copyText" value="">COPY</button>
</div>
</div>
<div id="web" ng-repeat="languageItem in LanguageFormData.language">
<div class="row col-xs-12">
<div class="col-xs-6">
<br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Brand Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" ng-required="true" name="bName" id="bName" class="form-control" ng-model="languageItem.bName" required/>
</div>
</div><br/><br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Product Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" name="pName" ng-required="true" id="pName" ng-model="languageItem.pName" required/>
</div>
</div><br/><br/><br/>
Why not use ng-disabled. You need to change $scope.disableThis=false; back to false to re-enable the text somewhere else inside the controller code.
$scope.copyText = function () {
$scope.disableThis=true;
$scope.LanguageFormData.language = [
{ bName: document.getElementById('brandName').value, pName: document.getElementById('prodName').value, pNameSub: document.getElementById('prodNameSub').value, lFeature: document.getElementById('pfeatureNew').value, lIngredient: document.getElementById('pingredientNew').value, lInstruction: document.getElementById('pinstructionNew').value, languageCat: null }
];
Suggestions:
I have some doubts on the above code, you can just use the $scope.LanguageFormData.language as is, since you are using ng-model in the input fields, the data of the variable is updated dynamically, you can check this by {{LanguageFormData.language}} printing the output in the HTML
HTML:
<div class="col-md-12" class="pull-right" >
<button class="btn btn-primary pull-right" type="button" ng-click="copyText()" id="copyText" ng-disabled="disableThis" value="">COPY</button>
</div>
</div>
<div id="web" ng-repeat="languageItem in LanguageFormData.language">
<div class="row col-xs-12">
<div class="col-xs-6">
<br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Brand Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" ng-required="true" name="bName" id="bName" ng-disabled="disableThis" class="form-control" ng-model="languageItem.bName" required/>
</div>
</div><br/><br/><br/>
<div class="form-group">
<label class="col-md-6 control-label">Product Name: </label>
<div class="col-md-6">
<input type="text" class="form-control" name="pName" ng-required="true" id="pName" ng-model="languageItem.pName" ng-disabled="disableThis" required/>
</div>
</div><br/><br/><br/>
Suggestions:
It would be good if you restrict the ID for one particular element alone, its a good practice to follow in general!
I am new in angular 2, i am making a "User Register" form but it shows error in "Property does not exist on type" in Phone number Validation.
I am compiling in JIT and AOT.
In JIT compiler shows error message and run my user register form it is working properly. but when i compile with AOT shows compilation error.
I am reading the angular 2 form validation official doc here is the link Angular 2 form validation
Below is my Html Form and compiler Output
Html Form
<form class="ui large form" method="post" (ngSubmit)="onSubmit(registerForm.form.valid)" #registerForm="ngForm" novalidate>
<sm-loader [complete]="!formSubmited" class="inverted" text="Loading..."></sm-loader>
<div class="form-group">
<div class="col-md-12 img-bottom">
<div class="col-md-offset-4">
<img (click)="profileImage.click()" class="img img-responsive img-circle ui middle aligned tiny circular image profileImage"
[src]="profileImageSrc" />
<input class="form-control user-reg-img" (change)="fileChangeEvent($event)" type="file" accept="image/*" #profileImage [hidden]="true"
/>
</div>
<div class="col-md-12 image-padding">
<span class="user-reg-img-name" (click)="profileImage.click()">{{profileImageName}}</span>
</div>
</div>
</div>
<div class="form-group">
<label><strong>Signup with Email Address:</strong></label>
</div>
<div class="form-group">
<p class="success text-center">{{successMessage}}</p>
<p class="error text-center">{{errorMessage}}</p>
<div class="field">
<input type="text" name="name" placeholder="Name" [(ngModel)]="register.name" #name="ngModel" required class="form-control input-reg"
/>
<div [hidden]="name.valid || name.pristine" class="error text-left">
Name is required
</div>
</div>
</div>
<div class="form-group">
<div class="field">
<input class="form-control input-reg" type="email" name="email" placeholder="Email" [(ngModel)]="register.email" #email="ngModel"
required />
<div [hidden]="email.valid || email.pristine" class="error text-left">
Email is required
</div>
</div>
</div>
<div class="form-group">
<input type="text" id="mobile" class="form-control input-reg" required minlength="10" maxlength="10" name="mobile" [(ngModel)]="register.mobile"
placeholder="Phone Number" #mobile="ngModel" pattern="[0-9]+">
<div *ngIf="mobile.errors && (mobile.dirty || mobile.touched)">
<div class="error text-left" [hidden]="!mobile.errors.required">
Mobile Number is required
</div>
<div class="error text-left" [hidden]="!mobile.errors.minlength">
Mobile Number must be at least 10 characters long.
</div>
<div class="error text-left" [hidden]="!mobile.errors.maxlength">
Monile Number cannot be more than 10 characters long.
</div>
</div>
</div>
<div class="form-group">
<div class="field">
<input class="form-control input-reg" type="password" name="password" placeholder="Password" [(ngModel)]="register.password"
#password="ngModel" required />
<div [hidden]="password.valid || password.pristine" class="error text-left">
Password is required
</div>
</div>
</div>
<div class="form-group">
<input type="checkbox" name="isAgree" [(ngModel)]="register.isAgree" #isAgree="ngModel" required />
<label id="label-terms-cond">I Agree to Post Bucks Terms & Conditions</label>
<div [hidden]="!showTermsAgreeErrorMsg" class="error text-left">
Please agree the terms and conditions to continue
</div>
</div>
<div class="form-group">
<textarea rows="4" class="form-control font-small terms-cond-textarea" rows="7">You must follow any policies made available to you within the Services.</textarea>
</div>
<div class="form-group">
<button class="fluid yellow large ui button btn btn-block btn-warning reg-btn-submit" type="submit">Signup</button>
</div>
</form>
AOT Output
Thanks in advance
Vikram
It looks the JIT compiler will never check the type of mobile.errors, but AOT check it at compilation by looking this line :
<div *ngIf="mobile.errors && (mobile.dirty || mobile.touched)">
According that in this line mobile.errors is a boolean, you'll obtain your traces...
I can't reproduce this bug (version problem ?), but maybe the following code will fix it :
<div *ngIf="(mobile.errors != null) && (mobile.dirty || mobile.touched)">
There is an opened issue here : https://github.com/angular/angular/issues/11425
Here is my answer, there is actual problem of required which is not found under mobile.errors object. below is my single line code.
!mobile.errors['required']
If object field not found then we use as array in template.
I'm using Stripe's jQuery plugin to validate credit card entry fields before details are being sent off for server side validation, but using Stripe's example my form will not submit, even when credit card data is valid.
The server side validation catches any issues, but I'd like to give users isntant feedback if there's an error in their data before it goes off to the server.
Stripe's jQuery plugin: https://stripe.com/blog/jquery-payment.
Their example: http://stripe.github.io/jquery.payment/example/
I'm using Bootstrap 3.3.4 and jQuery 1.11.2
My Form:
<form novalidate autocomplete="on" name="securepay" id="securepay" method="post" action="?func=validate" data-toggle="validator">
<div class="form-group col-sm-6">
<label for="cc-number" class="control-label">Card Number:</label>
<input id="cc-number" name="cc-number" type="tel" class="form-control cc-number paymentInput" autocomplete="cc-number" placeholder="•••• •••• •••• ••••" data-error="Please enter the long card number" value="" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group col-sm-6">
<label for="cc-exp" class="control-label">Expiry Date:</label>
<input id="cc-exp" name="cc-exp" type="tel" class="form-control cc-exp paymentInput" autocomplete="cc-exp" placeholder="MM / YY" data-error="Please enter the expiry date shown on the card" value="" required>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="row">
<div class="form-group col-sm-6">
<label for="cc-cvc" class="control-label">CVC Number:</label>
<input id="cc-cvc" name="cc-cvc" type="tel" class="form-control cc-cvc paymentInput" autocomplete="off" placeholder="•••" data-toggle="popover" data-trigger="focus" data-placement="right" title="CVC Security Number" data-content="On most cards, the 3-digit security code is on the back, to the right of the signature. On American Express cards, the 4-digit security code is on the front, to the top-right of the card number." data-error="Please enter the CVC number" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group col-sm-6">
<label for="cc-name" class="control-label">Name on Card:</label>
<input id="cc-name" name="cc-name" type="text" class="form-control cc-name paymentInput" autocomplete="cc-name" data-error="Please enter your name as specified on the card" value="" required>
<div class="help-block with-errors"></div>
</div>
</div>
<div class="checkbox">
<label>
<input type="checkbox" id="cc-terms" required><span class="text-info small">Please confirm that you agree to our Terms and Conditions</span>
</label>
</div>
</div>
<div class="form-group col-sm-12">
<button type="submit" id="secure-submit" class="btn btn-primary margin-10">Make Payment</button>
</div>
</form>
My Javascript:
$(function () {
$('[data-toggle="popover"]').popover({container: 'body'})
//Form Validation
$('#securepay').validator()
//$('[data-text]').payment('restrictText');
$('.cc-number').payment('formatCardNumber');
$('.cc-exp').payment('formatCardExpiry');
$('.cc-cvc').payment('formatCardCVC');
$.fn.toggleInputError = function(erred) {
this.parent('.form-group').toggleClass('has-error', erred);
this.parent('button').toggleClass('disabled', erred);
return this;
};
$('form').submit(function(e) {
e.preventDefault();
var cardType = $.payment.cardType($('.cc-number').val());
$('.cc-number').toggleInputError(!$.payment.validateCardNumber($('.cc-number').val()));
$('.cc-exp').toggleInputError(!$.payment.validateCardExpiry($('.cc-exp').payment('cardExpiryVal')));
$('.cc-cvc').toggleInputError(!$.payment.validateCardCVC($('.cc-cvc').val(), cardType));
$('.cc-brand').val(cardType);
});
});
The problem is it uses e.preventDefault(); which causes the form to not submit, even if the validation passes.
I'd like to use preventDefault(); to stop the form from being submitted if there's an error, but what would be the best way implament it so that the form will submit when the validation passes? I'd tried a few different options, but I just don't seem to be able to get it to work the way I want it to.
at the end of your function you can add
$(this).unbind('submit').submit()
if the validation passed.
maybe I am a little late, but perhaps it can be useful to someone..
$('form').submit(function(e) {
e.preventDefault();
var cardType = $.payment.cardType($('.cc-number').val());
$('.cc-number').toggleInputError(!$.payment.validateCardNumber($('.cc-number').val()));
$('.cc-exp').toggleInputError(!$.payment.validateCardExpiry($('.cc-exp').payment('cardExpiryVal')));
$('.cc-cvc').toggleInputError(!$.payment.validateCardCVC($('.cc-cvc').val(), cardType));
$('.cc-brand').val(cardType);
//check if there are errors
if(!$('.has-error').length) {
// The answare of #loli
$(this).unbind('submit').submit();
}
});