Bootstrap validation on dynamically adding multiple fields - javascript

I am using bootstrap v3.1.1 and I want to validate a form with bootstrap validation but who contains a button to clone 3 fields. With cloning everything works nice, but I can't validate the cloned fields. Here is my HTML Form:
<form id="myForm" action="myAction">
<div class="row" id="line_1">
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idFirstField_1" name="firstField[]">
</div>
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idSecondField_1" name="secondField[]">
</div>
<div class="col-md-2 form-group">
<input type="text" class="form-control input-sm" id="idThirdField_1" name="thirdField[]">
</div>
</div>
<a id="cloneButton">add line</a>
</form>
In JavaScript file I Have:
$(document).ready(function () {
var count = 2;
$('#cloneButton').click(function () {
var klon = $('#line_1');
klon.clone().attr('id', 'line_' + (++count)).insertAfter($('#line_1'));
$('#line_' + count).children('div').children('input').each(function () {
$(this).val('');
var oldId = $(this).attr('id').split('_');
$(this).attr('id', oldId[0] + '_' + count);
});
});
//For validating the fields:
$('#myForm').bootstrapValidator({
fields: {
'firstField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
},
'secondField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
},
'thirdField[]': {
validators: {
notEmpty: {
message: 'Enter a value'
}
}
}
}
});
});
I now that I must to use somethings like this
$('#myForm').bootstrapValidator('addField', klon.find('[name="firstField[]"]'));
for each field, but I don't now how correctly do it. Please help me. Thanks!!

if you insert the method addField in your input loop, it should work. I also suggest to save your first row as a template.
var template = $('#line_1').clone();
var options = {
fields: {
'firstField[]': {
validators: {
notEmpty: {
message: 'Enter a value 1'
}
}
},
'secondField[]': {
validators: {
notEmpty: {
message: 'Enter a value 2'
}
}
},
'thirdField[]': {
validators: {
notEmpty: {
message: 'Enter a value 3'
}
}
}
}
};
$('#myForm').bootstrapValidator(options);
$('#cloneButton').click(function () {
var rowId = $('.row').length + 1;
var validator = $('#myForm').data('bootstrapValidator');
var klon = template.clone();
klon.attr('id', 'line_' + rowId)
.insertAfter($('.row').last())
.find('input')
.each(function () {
$(this).attr('id', $(this).attr('id').replace(/_(\d*)$/, "_"+rowId));
validator.addField($(this));
})
});
FIDDLE

This Answer not exactly for this question but if someone want to add different field dynamically then they can use this.
$('#myForm').formValidation('addField', 'fourthField[]', {
validators: {
notEmpty: {
message: 'Enter a value 4'
}
},
});
Syntax : $("#form_name").formValidation("addField",'no of the field',{validation});

Related

Why do I get this error: Uncaught TypeError: Cannot read property 'classList' of null

I know there are few instances of this error being asked about, but none of the tips given seem to do anything for me. Any thoughts or tips would be appreciated.
I have a form that has fields validated via formvalidation.io, latest version 1.8.1
I thought my problem might have something to do with the "Confirm Password" and Password Strength steps but removing those fields has the same error appear.
Keep getting this error, although the form functions just fine and info gets written to the db correctly etc.:
FormValidation.min.js:formatted:2560 Uncaught TypeError: Cannot read property 'classList' of null
at FormValidation.min.js:formatted:2560
at Array.forEach (<anonymous>)
at s$4 (FormValidation.min.js:formatted:2559)
at FormValidation.min.js:formatted:2588
at Array.forEach (<anonymous>)
at c (FormValidation.min.js:formatted:2587)
at s.install (FormValidation.min.js:formatted:2845)
at l.registerPlugin (FormValidation.min.js:formatted:1407)
at FormValidation.min.js:formatted:1965
at Array.forEach (<anonymous>)
My Form:
<form id="signupForm" method="post" action="signup.html">
<div class="form-group">
<label><b>Work Name</b></label>
<input type="text" class="form-control" id="working_name" name="working_name" placeholder="Your Working Name">
</div>
<div class="form-group">
<label><b>Work Email</b></label>
<input type="text" class="form-control" id="email" name="email" placeholder="Your Work Email">
</div>
<div class="form-group">
<label><b>Choose a Password</b></label>
<input type="text" class="form-control" id="pwd" name="pwd" placeholder="Choose a Password">
<div class="progress mt-2" id="progressBar" style="opacity: 0; height: 10px;">
<div class="progress-bar progress-bar-striped progress-bar-animate" style="width: 100%; height: 5vh;"></div>
</div>
</div>
<div class="form-group">
<label><b>Retype Password</b></label>
<input type="text" class="form-control" id="confirmPWD" name="confirmPwd" placeholder="Enter your Password Again">
</div>
<div class="form-group">
<label><b>Website</b></label>
<input type="text" class="form-control" id="website_url" name="website_url" placeholder="Your Website (if you have one)">
</div>
<div class="form-group">
<label><b>Twitter Page</b></label>
<input type="text" class="form-control" id="twitter_url" name="twitter_url" placeholder="Twitter Page">
</div>
<div class="form-group">
<label><b>Link to Current Advertising</b></label>
<input type="text" class="form-control" id="advertising_link" name="advertising_link" placeholder="Link to Current Advertising">
</div>
<div class="form-group">
<label><b>Referred By</b></label>
<input type="text" class="form-control" id="referred_by" name="referred_by" placeholder="Who referred you to RS?">
</div>
<div class="form-group">
<label><b>Other Information</b></label>
<textarea id="other_info" name="other_info" cols="40" rows="3" class="form-control" placeholder="Other Information"></textarea>
</div>
<div class="form-group" align="center">
<!-- Do NOT use name="submit" or id="submit" for the Submit button -->
<br><button class="btn btn-signup" name="action" value="Sign up to use RS Services" type="submit">Sign up to use RS Services</button>
</div>
</form>
<script>
document.addEventListener('DOMContentLoaded', function(e) {
const strongPassword = function() {
return {
validate: function(input) {
// input.value is the field value
// input.options are the validator options
const value = input.value;
if (value === '') {
return {
valid: true,
};
}
const result = zxcvbn(value);
const score = result.score;
const message = result.feedback.warning || 'The password is weak';
const cmessage = 'Success Full';
// By default, the password is treat as invalid if the score is smaller than 3
// We allow user to change this number via options.minimalScore
const minimalScore = input.options && input.options.minimalScore ?
input.options.minimalScore :
5;
console.log(minimalScore, "dfd");
if (score >= minimalScore) {
console.log("condition true")
return {
valid: true,
message: cmessage,
meta: {
// This meta data will be used later
score: score,
},
}
} else if (score < minimalScore) {
console.log("condition false")
return {
valid: false,
// Yeah, this will be set as error message
message: message,
meta: {
// This meta data will be used later
score: score,
},
}
}
},
};
};
const form = document.getElementById('signupForm');
const fv = FormValidation.formValidation(
form, {
fields: {
working_name: {
validators: {
notEmpty: {
message: 'Your Agency or Working Name is required'
},
stringLength: {
min: 3,
max: 30,
message: 'The name must be more than 3 and less than 30 characters long'
},
// regexp: {
// regexp: /^[a-zA-Z0-9_]+$/,
// message: 'The name can only consist of letters, numbers or an underscore'
// }
}
},
email: {
validators: {
notEmpty: {
message: 'Your Email Address is required'
},
emailAddress: {
message: 'That is not a valid email address'
}
}
},
pwd: {
validators: {
notEmpty: {
message: 'The password is required and cannot be empty'
},
checkPassword: {
message: 'The password is too weak',
minimalScore: 4,
},
}
},
confirmPwd: {
validators: {
identical: {
compare: function() {
return form.querySelector('[name="pwd"]').value;
},
message: 'The Passwords do not match'
}
}
},
},
plugins: {
trigger: new FormValidation.plugins.Trigger(),
bootstrap: new FormValidation.plugins.Bootstrap(),
submitButton: new FormValidation.plugins.SubmitButton(),
defaultSubmit: new FormValidation.plugins.DefaultSubmit(),
icon: new FormValidation.plugins.Icon({
valid: 'fa fa-check',
invalid: 'fa fa-times',
validating: 'fa fa-refresh'
}),
},
}
)
.registerValidator('checkPassword', strongPassword)
.on('core.validator.validating', function(e) {
if (e.field === 'pwd' && e.validator === 'checkPassword') {
document.getElementById('progressBar').style.opacity = '1';
}
})
.on('core.validator.validated', function(e) {
if (e.field === 'pwd' && e.validator === 'checkPassword') {
const progressBar = document.getElementById('progressBar');
if (e.result.meta) {
// Get the score which is a number between 0 and 4
const score = e.result.meta.score;
console.log(score);
// Update the width of progress bar
const width = (score == 0) ? '1%' : score * 25 + '%';
console.log(width, "width");
progressBar.style.opacity = 1;
progressBar.style.width = width;
} else {
progressBar.style.opacity = 0;
progressBar.style.width = '0%';
}
}
});
});
</script>
Problem Solved.
Had to redo my html a little.
More of an issue with the way I had hideif/showif statements in place.

How to emit and event within a promise in Vuejs [duplicate]

I'm learning on how to render HTML contents in Vuejs I'm trying to build a small input component which gets generated from render function. It looks something like this:
export default {
name: "nits-input",
methods: {
},
props: {
label: String,
hint: String,
error: String,
placeholder: String
},
render (createElement) {
//Help action text
let helpText = this.hint ? createElement('span', { class: 'm-form__help' }, this.hint) : ''
//Error Text
let errorText = this.error ? createElement('span', { class: 'm--font-danger' }, this.error) : ''
return createElement('div', { class: ''}, [
createElement('label', this.label),
createElement('input', {
class: 'form-control m-input',
attrs: { type: this.type, placeholder: this.placeholder },
domProps: { value: self.value},
on: {
input: function (event) {
this.$emit('input', event.target.value)
}
}
}),
helpText, errorText
])
}
}
While calling this component I'm doing below:
<div class="form-group m-form__group">
<nits-input
label="Email Address"
type="email"
hint="We'll never share your email with anyone else."
placeholder="Enter email"
v-model="email"
>
</nits-input>
</div>
<div class="form-group m-form__group">
<nits-input
label="Password"
type="password"
placeholder="Enter password"
v-model="password"
>
</nits-input>
</div>
I want the value to be stored into v-model, to check the values are being set properly I'm using a watch function
watch: {
email () {
console.log('Email v-model defined as '+this.email)
},
password() {
console.log('Password v-model defined as '+this.password)
}
}
But this always gives me error:
Uncaught TypeError: Cannot read property '$emit' of null
I've taken the references from This VueJS Documentation Link. Help me out in this. Thanks.
you should use arrow function since you're loosing the scope inside that callback :
on: {
input:(event)=> {
this.$emit('input', event.target.value)
}
}

Vee Validate require either of two fields

I'm trying to use Vee Validate to require either of two input fields, name OR location, but they cannot both be empty. I am getting this error- 'Error in directive validate bind hook: "TypeError: Cannot read property 'expression' of undefined"' Here's what I have-
HTML
<div class="col-xs-12 col-sm-8">
<div class="same-height-parent">
<div class="same-height" :class="{'has-error': errors.has('searchLocation') }">
<input type="text" class="form-control" placeholder="Enter Zip or City, ST" v-model="searchLocation" v-validate ="{ rules: { required: this.locationInput} }" data-vv-name="searchLocation" >
</div>
<div class="form-element same-height">or</div>
<div class="same-height" :class="{'has-error': errors.has('searchName') }">
<input type="text" class="form-control" placeholder="Enter Name" v-model="searchName" v-validate ="{ rules: { required: nameInput} }" data-vv-name="searchName">
</div>
</div>
</div>
<div class="col-xs-12 col-sm-4">
<button class="btn btn-success btn-block btn-fz20"
#click="validateBeforeSubmit()">Search</button>
</div>
JS
export default {
name: 'startNewSearch',
data: function() {
return {
sectionTitle: 'Start a New Search',
sectionClass: 'search',
searchLocation: '',
searchName: '',
searchType: 'location'
}
},
methods: {
validateBeforeSubmit: function(e) {
this.$validator.validateAll();
if (!this.errors.any()) {
this.submit()
}
},
submit: function(e) {}
}
},
computed: {
locationInput() {
if(this.searchName === '') {
return true;
}
return false;
},
nameInput() {
if(this.searchLocation === '')
return true; // cellphone is required
return false;
}
}
}
This is an old question, but I came across it while looking for a similar problem.
Anyhow, I believe you have a syntax error.
v-validate ="{ rules: { required: nameInput} }"
...you're missing 'this'...
v-validate ="{ rules: { required: this.nameInput} }"
Regards,
Wayne
In vee-validate v3 my solution was to extend the require_if rule like this:
app.html:
...
<ValidationProvider name="lastName" immediate rules="required_if_not:company" v-slot="{ errors }">
...
app.js:
extend('required_if_not', {
...required_if,
// params: ['target']
validate: (value, args) => {
let target_value = args.target;
return Boolean(target_value || value);
},
message: 'Bitte dieses Feld ausfüllen.'
});
this also works with multiple fields.

How to validate same field second time in bootstrapvalidator

In this iam validating servicedescription after onchange and it is forworking fine but whenever my text changes to otherthan "OTHER" and need validate Remarks in that only StringLength
This is my div
<div class="form-group" id="serviceDescription">
<label class="control-label col-sm-3">Service Description:<span class="servicedescription hide" style="color:#FF0000;">*</span></label>
<div class="col-sm-6">
<textarea class="form-control" name="Remarks" id="Remarks" placeholder="Enter Service Description" rows="5"></textarea>
</div>
</div>
This is my onchange
.on('change', '[name="ServiceID"]', function () {
var Serviceid = parseInt($("#ServiceID").val());
var skillsSelect = document.getElementById("ServiceID");
var selectedText = skillsSelect.options[skillsSelect.selectedIndex].text;
if (selectedText == "OTHER") {
$(".servicedescription").removeClass("hide");
$('#AddServicesForm').bootstrapValidator('enableFieldValida‌​tors','Remarks');
$('#AddServicesForm').bootstrapValidator('validateField', 'Remarks');
}
else{
$('#AddServicesForm').bootstrapValidator('enableFieldValidators', 'Remarks', false)
$(".servicedescription").addClass("hide");
}
})
And this is my bootstrapvalidator
Remarks: {
validators: {
notEmpty: {
message: 'Remarks is required and cannot be empty'
},
stringLength: {
min: 1,
max: 200,
message: 'Service Description must be 1 to 200 characters long'
},
}
},

Jquery Validation on cloned elements

I am using the following JQuery validation:
http://bassistance.de/jquery-plugins/jquery-plugin-validation/
I have the following element:
<div class="form-item">
<label for="Reference_name" class="required">Name: <span class="required">*</span></label>
<input name="Reference[name][]" class="form-input validate {validate:{required:true,minLength:2,messages:{required:'Your name is required',minLength:'Your name is too short'}}}" id="Reference_name" type="text">
</div>
I have cloned the element but the validation is only appearing on the first element. I would like it to validate against the second too and show the error message label.
Can someone help with this please.
elements must be unique
<label for="Reference_name" class="required">Name:<span class="required">*</span></label>
<input type="text" id="Reference_name" name="Reference[Name]" id="Reference_name" required="required" maxlength="255" />
File Js
$(document).ready(function() {
validate_form();
});
function validate_form() {
$("#id_of_your_form").validate({
rules: {
'Reference_name': {
required:true,
minlength: 2,
}
},
},
messages: {
'Reference_name': {
required:"Your name is required",
minLength:'Your name is too short'
},
}
});
}
if you want to compare two fields
http://docs.jquery.com/Plugins/Validation/Methods/equalTo#other
Put your validation function in a global variable like this:
var validate_form_function = function(){
if($(".app-form").length > 0){
$('.app-form').validate({
rules: {
comment_message: {
required: true,
minlength: 2
}
},
messages: {
comment_message: {
required: "Your message",
minlength: "Your message"
}
}
});
}
};
Then revalidate your cloned form with the function like this :
validate_form_function();

Categories

Resources