ParsleyJS custom validator not working - javascript

I am using the latest version of ParsleyJS and tried the example from doc, just copy pasted it into my code but it wont work. I actually made my own validator but its not working, so I tried to copy paste the exact example but it doesn't work as well.
I am working with Laravel and here's my form and js code.
<div class="form-group">
<label>Name of my school</label>
{{ Form::text('edu[institute]', null, ['class' => 'form-control', 'data-parsley-myValidator' => '']) }}
</div>
window.Parsley.addValidator('myValidator', {
validateString: function(value) {
return value.split('').reverse().join('') === value;
},
messages: {
en: 'This string is not the reverse of itself',
fr: "Cette valeur n'est pas l'inverse d'elle même."
}
})
I have just torn my hair, WHY WOULD THIS NOT WORK?
Laravel blade output of form field:
<input class="form-control" data-parsley-myvalidator="" name="edu[institute]" type="text">
EDIT:
This form field is inside a Bootstrap Modal.

Their example seems to work fine. I still can't reproduce your issue.
window.Parsley.addValidator('palindrome', {
validateString: function(value) {
return value.split('').reverse().join('') === value;
},
messages: {
en: 'This string is not the reverse of itself',
fr: "Cette valeur n'est pas l'inverse d'elle même."
}
});
<link href="//cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.7.2/parsley.min.js"></script>
<form data-parsley-validate="">
<label>Please enter a palindrome:</label>
<input type="text" data-parsley-palindrome="">
<input type="submit" class="btn">
</form>

Related

Nuxt / Netlify Form returning empty form data fields

I'm using Nuxt and Netlify Forms for a contact form, Everything is working as expected (validation, submit success) however I am getting empty form fields on submissions. I have tried matching the v-model and form names with no success. Do I have to change the body.encode to retrieve the v-model fields or somehow get the value of the name fields inputs?
Markup:
<form
name="contactForm"
method="post"
netlify-honeypot="bot-field"
data-netlify="true"
#submit.prevent="handleSubmit()"
>
<input type="hidden" name="form-name" value="contactForm" />
<div class="form-group">
<!--user name -->
<div class="floating-label">
<input
v-model="contact_name"
class="floating-input"
name="name"
type="text"
placeholder=" "
:class="{
'child-has-error': $v.contact_name.$error,
}"
/>
<label>Enter Your Name</label>
<p v-if="$v.contact_name.$dirty">
<span
v-if="!$v.contact_name.required"
class="form__alert"
>
Name is required
</span>
</p>
</div>
<!-- end user name -->
<!--user email -->
<div class="floating-label">
<input
v-model="contact_email"
class="floating-input"
type="text"
name="email"
placeholder=" "
:class="{
'child-has-error': $v.contact_email.$error,
}"
/>
<label>Enter Your Email</label>
<p v-if="$v.contact_email.$dirty">
<span
v-if="!$v.contact_email.required"
class="form__alert"
>
Email is required
</span>
<span v-if="!$v.contact_email.email" class="form__alert">
Please enter a valid email
</span>
</p>
</div>
<!-- end user email -->
<!--user message -->
<div class="floating-label">
<textarea
v-model="contact_message"
class="form-control form-control--textarea"
rows="5"
name="message"
placeholder="Enter Your Message"
:class="{ 'child-has-error': $v.contact_message.$error }"
/>
<p v-if="$v.contact_message.$dirty">
<span
v-if="!$v.contact_message.required"
class="form__alert"
>
Enter Your Message
</span>
<span
v-if="!$v.contact_message.minLength"
class="form__alert"
>
Message must be over 10 characters :)
</span>
</p>
</div>
<!-- end user message -->
</div>
<button type="submit" class="btn btn-primary">
Send Message
<font-awesome-icon far icon="arrow-right" />
</button>
</form>
Script:
<script>
import { required, email, minLength } from 'vuelidate/lib/validators'
export default {
data() {
return {
title: 'Contact Form',
show_contact: true,
contact_name: '',
contact_email: '',
contact_message: '',
form: {
name: '',
email: '',
message: '',
},
}
},
validations: {
contact_name: {
required,
},
contact_email: {
required,
email,
},
contact_message: {
required,
minLength: minLength(10),
},
},
methods: {
encode(data) {
return Object.keys(data)
.map(
(key) => `${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`
)
.join('&')
},
handleSubmit() {
this.$v.$touch()
if (this.$v.$invalid) {
return true
}
fetch('/', {
method: 'post',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: this.encode({
'form-name': 'contactForm',
...this.form,
}),
})
// eslint-disable-next-line no-console
.then(() => {
this.show_contact = false
// eslint-disable-next-line no-console
console.log('Message Success')
})
// eslint-disable-next-line no-console
.catch((e) => console.error(e))
},
},
}
</script>
You've been sending this.form as your data
body: this.encode({
'form-name': 'contactForm',
...this.form,
}),
but you never set values to it based on your inputs. I did not see any reference to it.
Either use those in your v-model bindings or convert this.form from data to a computed property like:
form() {
return {
name: this.contact_name,
email: this.contact_email,
message: this.contact_message
}
}
I'm working on a Nuxt/Netlify project too currently.
There are 3 scenarios
If you're using Nuxt as a static site
It looks like you're not binding your form values to the fields you're sending to Netlify
It's probably safe to replace
form: {
name: '',
email: '',
message: '',
},
with
form: {
contact_name: '',
contact_email: '',
contact_message: '',
}
Otherwise, assuming you're using Nuxt as an SPA and using a static stand-in form in this example here
Your stand-in form must contain fields with the same name as your actual form field. Otherwise, your form will be submitted but won't be seen on the NetlifyUI due to their build bots not expecting those form fields.

Parsley validation on button + custom validator not working

I have a form, styled with bootstrap, that contains multiple fields (tel number, date, start time, end time...), meant to book bicycles.
When those fields are changed, a script checks throught ajax if a bicycle is free and change the class of a button (act as submit by default) from .btn-danger (red - no bicycle available) to .btn-success (green - You got one !) accordingly :
<form id='resa_velo_form' name='resa_velo_form' method='POST' action='index.php?app=resa&ctrl=AccueilUserCtrl&action=enregistreResaVelo'>
<div class='form-group col-md-3'>
<label for="velo_date">Date d'emprunt : </label>
<div class='input-group date' id='datetimepicker_deb'>
<input type="text" id="velo_date" name="date_start" autocomplete="off" class="form-control" required>
<span class="input-group-addon">
<span class=" fa fa-calendar"></span>
</span>
</div>
</div>
<div class='form-group col-md-2'>
<label for="velo_time_start">Départ :</label>
<input id="velo_time_start" class="timepicker_input velo spinner" name="time_start" value="8:30" required>
</div>
<div class='form-group col-md-2'>
<label for="velo_time_end">Retour : </label>
<input id="velo_time_end" class="timepicker_input velo spinner" name="time_end" value="9:30" data-parsley-timeissup="#velo_time_start" required>
</div>
<div class='form-group col-md-5'>
<label> </label>
<button id="disponibilite_velo" class="error_resa btn btn-danger col-md-12" data-parsley-success='btn-success' required>Choisissez une date</button>
</div>
</form>
I managed to use Parsley to validate this form and even got to apply .has-error classes to form-group :
$('#resa_velo_form').parsley({
successClass: "has-success",
errorClass: "has-error",
classHandler: function(el) {
return el.$element.closest(".form-group");
}
})
I'm using successfully a custom validator on start and end time :
window.Parsley.setLocale('fr');
window.Parsley.addValidator('timeissup', {
requirementType: 'string',
validateString: function(value, requirement) {
time1 = $(requirement).val().split(/:/);
time1 = time1[0] * 3600 + time1[1] * 60;
time2 = value.split(/:/);
time2 = time2[0] * 3600 + time2[1] * 60;
return (time2 > time1);
},
messages: {
en: 'This value should be higher than start time.',
fr: "Cette valeur doit être supérieure à l'heure de départ."
}
});
BUT THEN...
I tried to make a custom validator to check the class of the button :
window.ParsleyConfig = {
excluded: 'input[type=hidden], :hidden, input[type=reset]',
inputs: 'input, textarea, select, input[type=button], button, input[type=submit]'
};
window.Parsley.addValidator('success', {
requirementType: 'string',
validateString: function(value, requirement) {
console.log('ok - Parlsey Valid Success');
return ($('#disponibilite_velo').hasClass(requirement));
},
messages: {
en: 'This button should be green !',
fr: "Ce bouton doit être vert !"
}
});
And it never works, Parlsey doesn't seems to use this validator, but still checks fields required and "timeissup" custom validator.
In fact, I managed to make it work by attaching it to an input field, but that's not the point.
Any help, please ?
Got it to work !
Contrary to this answer, you need to define excluded and inputs in the form validator itself :
$('#resa_velo_form').parsley({
successClass: "has-success",
errorClass: "has-error",
excluded: 'input[type=reset]',
inputs: 'input, textarea, select, button',
classHandler: function(el) {
return el.$element.closest(".form-group");
}
});
Other important thing : even if it's a button, you need the required attribute and a value different from '' (empty):
<button id="disponibilite_velo" class="error_resa btn btn-danger col-md-12" data-parsley-inputsuccess='btn-success' value='*' required>Choisissez une date</button>
Maybe not so clean, but... working !

Trouble with validate() on jquery

I have html like these
<form class="form-filter" id="form-filter-excel" role="form">
<div class="row">
<div class="col-md-4 col-sm-5">
<label>Date range</label>
<div class="input-group input-daterange datepicker">
<input id="fRange" name="fRange" class="form-control input-sm" type="text">
<span class="input-group-addon bg-primary">to</span>
<input id="sRange" name="sRange" class="form-control input-sm" type="text">
</div>
</div>
<div class="col-md-2 col-sm-1">
<label>
</label>
<a class="btn btn-wide btn-primary form-control" href="#" id="btnexport" ><i class="fa fa-file-excel-o"></i> Export To Excel</a>
</div>
</div>
</form>
end here my screen shoot
My question i wanna use validate() on jquery, but i'm kinda stuck i wanna use class= "input-daterange" as field, and the input fRange and sRange as required. How do i did that, if i using fRange and sRange as field, the error massage show up mess. Any idea??
UPDATE :
Sorry for not unclear my question
I'm using jquery validate like these
$('#form-filter-excel').validate({
highlight: function(element) {
$(element).closest('.form-group').prop('required',true);
},
unhighlight: function(element) {
$(element).closest('.form-group').prop('required',false);
},
errorElement: 'span',
errorClass: 'help-block',
errorPlacement: function(error, element) {
if(element.parent('.input-group').length) {
error.insertAfter(element.parent());
} else {
error.insertAfter(element);
}
},
rules: {
fRange: {
required: true,
date: true
},
sRange: {
required: true,
date: true
}
},
messages: {
fRange: "Please insert these input",
sRange: "Please insert these input"
},
});
$('#btnexport').click(function() {
$('#form-filter-excel').valid();
if($('#form-filter-excel').valid()==true)
{
var Fod = $('#fRange').val();
var Tod = $('#sRange').val();
window.open(host+"ajax/excelpoinfo?Fod=" + Fod +"&Tod=" + Fod, '_blank');
}
});
but the problem is the error massage not show under my input but show error like these on my screen
What i need is the error massage show on under each my input.
UPDATE:
I change my mind, i'm using sweet alert then, tq for helping. And for Mayank Pandeyz, u didnt see my question clearly, like i said, that not helping, even u said change replacement. Still not work.
On both the textbox provide the name attribute with its values like:
<form id="frmDetails" name="frmDetails">
<input type="textbox" name="fRange">
<input type="textbox" name="sRange">
</form>
And put the validation code on these like:
$('#frmDetails').validate({
rules:
{
fRange: {
required: true
},
sRange: {
required: true
}
},
messages:
{
fRange: {
required: "Please select fRange"
},
sRange: {
required: "Please select sRange"
}
}
});
Working Fiddle

jQuery validation: form always valid issue

i am trying to perfom form validation before submit to server. I am using jquery.validate plugin
(JQuery validation plugin page)
The problem i am facing is that does not matter what i type in the form fields, validation always succeded, i double checked everything against documentation and samples over the wire and cannot see why i am getting this behaviour.
This form is loaded via jquery ajax:
$.ajax({
url: "mypage.php",
type: "POST",
cache: false,
success: function(cont){
$("body").append(cont);
}
});
Here i show you mypage.php code
<script src="js/jquery.validate.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#frmParticipante").validate({
rules: {
nombre: { required: true } ,
email: { required: true, email: true },
ci: { required: true}
}
});
$("#frmParticipante").submit(function(e){
e.preventDefault();
if($(this).valid()){
loadpop("ganaste.php");
}
else
loadpop("perdiste.php");
});
});
</script>
<div id="pop_terminaste" class="pop_mensaje ingresardatos animated fadeInDown">
<div id="infopop">
<div id="lady"> <img src="images/terminaste1.jpg" width="453" height="626" /> </div>
<div id="dato">
<p class="txt1">¡Terminaste la trivia!</p>
<p class="txt2">Ahora solo te falta completar tus datos para conocer el resultado.</p>
<p class="txt3">Si ha cargado anteriormente sus datos, ingresar solo su cédula.</p>
<form action="" id="frmParticipante" class="form">
<fieldset>
<label for="nombre"><img src="images/ico_nombre.png" alt="ico_nombre" /></label>
<input type="text" placeholder="Nombre y Apellido" id="nombre">
</fieldset>
<fieldset>
<label for="email"><img src="images/ico_email.png" alt="ico_email" /></label>
<input type="text" placeholder="Email" id="email">
</fieldset>
<fieldset>
<label for="ci"><img src="images/ico_ci.png" alt="ico_ci" /></label>
<input type="text" placeholder="C.I" id="ci">
</fieldset>
<p class="msg error">Favor verificar los datos ingresados.</p>
<input type="submit" value="VER RESULTADOS" />
</form>
</div>
</div>
</div>
Thanks
I am pretty sure that the validation library requires name attributes and doesn't pay attention to id attributes. You should either change your id attr's to name, or just add name attributes with the same values...like :
<input type="text" placeholder="Nombre y Apellido" id="nombre" name="nombre">
Here is a fiddle to show that it works http://jsfiddle.net/7WTvL/1/
Along with the names, you will likely need to load your validate.js library in the head of the page you are loading the form into, and then run validate in .done() on your ajax request.
<script>
$.ajax({
url: "mypage.php",
type: "POST",
cache: false
}).done(function(cont) {
$("body").append(cont);
$("#frmParticipante").validate({
rules: {
nombre: { required: true } ,
email: { required: true, email: true },
ci: { required: true}
}
});
});
$("#frmParticipante").submit(function(e){
e.preventDefault();
if($(this).valid()){
loadpop("ganaste.php");
}
else
loadpop("perdiste.php");
});
</script>
Again...make SURE the validate library is loaded on the page you're ajax'ing content into...it needs to be on the page before your ajax'd content arrives.

Multiple inputs in a Bootbox

How can I have 2 inputs instead of just one in Bootstrap's Bootbox?
I need to receive 2 values in a modal dialog.
Actually, there is a simpler way which doesn't require you to modify bootbox code.
The string you pass at the bootbox creation doesn't have to be only text: it can also be html code. That means you can include pretty much everything in the box.
To put a custom form in a bootbox, you can then create it as follow :
bootbox.confirm("<form id='infos' action=''>\
First name:<input type='text' name='first_name' /><br/>\
Last name:<input type='text' name='last_name' />\
</form>", function(result) {
if(result)
$('#infos').submit();
});
I just made function for that, check it out - here
Usage example
bootbox.form({
title: 'User details',
fields: {
name: {
label: 'Name',
value: 'John Connor',
type: 'text'
},
email: {
label: 'E-mail',
type: 'email',
value: 'johnconnor#skynet.com'
},
type: {
label: 'Type',
type: 'select',
options: [
{value: 1, text: 'Human'},
{value: 2, text: 'Robot'}
]
},
alive: {
label: 'Is alive',
type: 'checkbox',
value: true
},
loves: {
label: 'Loves',
type: 'checkbox',
value: ['bike','mom','vg'],
options: [
{value: 'bike', text: 'Motorbike'},
{value: 'mom', text: 'His mom'},
{value: 'vg', text: 'Video games'},
{value: 'kill', text: 'Killing people'}
]
},
passwd: {
label: 'Password',
type: 'password'
},
desc: {
label: 'Description',
type: 'textarea'
}
},
callback: function (values) {
console.log(values)
}
})
For me, this is the cleanest way to do it :
var form = $('<form><input name="usernameInput"/></form>');
bootbox.alert(form,function(){
var username = form.find('input[name=usernameInput]').val();
console.log(username);
});
Create hidden div with form in HTML and inject this html to bootbox message. Snippet below.
var buttonClick = function() {
var bootboxHtml = $('#js-exampleDiv').html().replace('js-exampleForm', 'js-bootboxForm');
bootbox.confirm(bootboxHtml, function(result) {
console.log($('#ex1', '.js-bootboxForm').val());
console.log($('#ex2', '.js-bootboxForm').val());
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<div id="js-exampleDiv" hidden>
<form class="js-exampleForm">
<div class="col-sm-12">
<input placeholder="Example placeholder 1" id="ex1" />
</div>
<div class="col-sm-12">
<input placeholder="Example placeholder 2" id="ex2" />
</div>
</form>
</div>
<button onclick="buttonClick();">
Open bootbox confirm dialog.
</button>
You have to write your own function which will load dialog function from bootbox.
The easiest way is to copy prompt function from source: https://raw.github.com/makeusabrew/bootbox/v3.2.0/bootbox.js
and change this part for adding new input (or whatever you need)
// let's keep a reference to the form object for later
var form = $("<form></form>");
form.append("<input autocomplete=off type=text value='" + defaultVal + "' />");
and this part for getting result:
var confirmCallback = function() {
if (typeof cb === 'function') {
return cb(form.find("input[type=text]").val());
}
};
Here is a basic example for what you need (using knockout)
<button data-bind="click: select">Button</button>
<script type="text/html" id="add-template">
<div style="display:none">
<input data-bind='value: name' placeholder="Name">
</div>
</script>
var viewModel = function () {
var self = this;
self.name = ko.observable();
self.select = function () {
var messageTemplate = $($("#add-template").html());
ko.applyBindings(self, messageTemplate.get(0));
messageTemplate.show();
bootbox.confirm({
title: "Add new",
message: messageTemplate,
callback: function (value) {
// do something
}
});
}
}
ko.applyBindings(new viewModel());
Just add as many fields and bind them in the view model
http://jsfiddle.net/6vb7e224/2/
haradwaith Has the best solution for posting form data from a bootbox. Because it works, it's simple and because he demonstrates how to Actually Submit the Form. His solution:
bootbox.confirm("<form id='infos' action=''>\
First name:<input type='text' name='first_name' /><br/>\
Last name:<input type='text' name='last_name' />\
</form>", function(result) {
if(result)
$('#infos').submit();
});
Moving the <form> tag outside of the bootbox object allows the use of PHP when posting to self and to include hidden inputs without all the clutter.
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" id="infos">
<input type=hidden form="infos" name="created" value="<?php echo date("Y-m-d H:i:s"); ?>" />
</form>
Now you can check for $_POST['created']
<?php
if(isset($_POST['created'])){
echo "Timestamp: ".$_POST['created']; // great things happen here
}
?>
You can create the form anywhere in the body tag, it won't display because the inputs are hidden.
Hope that helps!
I know this question is pretty old now, but this is the way I've done it. I think this way is great for larger forms as putting all of the HTML in JavaScript can get ugly pretty quick.
This example uses Bootstrap but the idea is the same. Create a hidden form in HTML and then select it using JavaScript or JQuery.
HTML:
<div id="hiddenForm" class="hidden">
<form id="myForm" class="form-horizontal">
<div class="form-group">
<label class="control-label col-sm-2">First Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="FirstName" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">Last Name</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="LastName" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">City</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="City" />
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2">State</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="State" />
</div>
</div>
</form>
</div>
JavaScript Version:
var form = document.getElementById("hiddenForm").innerHTML;
bootbox.confirm({
message: form,
callback: function (result) {
// do something
}
});
JQuery Version:
var form = $("#hiddenForm").html();
bootbox.confirm({
message: form,
callback: function (result) {
// do something
}
});
Note:
When you try to serialize the form for posting, you'll have to make sure you are actually targeting the right form. $("#myForm").serialize() will most likely not work as it will grab the actual HTML form that you built earlier. So instead, you should do something like $(".bootbox-body #myForm").serialize() to get the current form's values.

Categories