Semantic UI onSuccess callback called even when form validation fails - javascript

When submitting a form, the onSuccess callback is still called even then the validation fails.
Why is it being called when the form is not valid?
Example here: https://jsfiddle.net/tL5xx6m9/7/
Snippet:
Verbose explanation to satisfy code/text ratio for submission:
In this snippet I have text that gets written when the onSuccess event is called. By clicking submit you will see that the form is not valid, and that the onSuccess text gets written. Under that text is the bool for whether the form is valid or not by calling $(".ui.form").form('is valid').
$(".ui.form").form({
onSuccess: function(event, fields) {
SubmitForm(fields);
event.preventDefault();
}
});
//Processes the forms data for a submission
function SubmitForm(fields) {
var valid = $(".ui.form").form('is valid');
$('#successText').html("On Success Called" + "<br> Is Valid: " + valid);
console.log("Submitting Form");
console.log(fields);
}
$('.ui.form').form({
fields: {
input1: {
identifier: 'input1',
rules: [{
type: "empty",
prompt: "input1 - This field is required"
}]
},
input2: {
identifier: 'input2',
rules: [{
type: "empty",
prompt: "input2 - This field is required"
}]
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.js"></script>
<form class="ui form attached fluid segment">
<div class="field">
<input name="input1" type="text" placeholder="input1" id="testRemoveField">
</div>
<div class="field">
<input name="input2" type="text" id="" placeholder="input2">
</div>
<button class="ui teal button" type="submit">Submit</button>
<div class="ui error message"></div>
<div id="successText">
</div>
</form>

It appears that by having two separate .form() method calls, it creates two validation checks that execute independently from each other. So the first call without rules will always be successful.
Move the onSuccess event to the same call as your validation rules and it starts to work as intended.
//Processes the forms data for a submission
function SubmitForm(fields) {
var valid = $(".ui.form").form('is valid');
$('#successText').html("On Success Called" + "<br> Is Valid: " + valid);
console.log("Submitting Form");
console.log(fields);
}
$('.ui.form').form({
fields: {
input1: {
identifier: 'input1',
rules: [{
type: "empty",
prompt: "input1 - This field is required"
}]
},
input2: {
identifier: 'input2',
rules: [{
type: "empty",
prompt: "input2 - This field is required"
}]
}
},
onSuccess: function(event, fields) {
SubmitForm(fields);
event.preventDefault();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.1.8/semantic.min.js"></script>
<form class="ui form attached fluid segment">
<div class="field">
<input name="input1" type="text" placeholder="input1" id="testRemoveField">
</div>
<div class="field">
<input name="input2" type="text" id="" placeholder="input2">
</div>
<button class="ui teal button" type="submit">Submit</button>
<div class="ui error message"></div>
<div id="successText">
</div>
</form>

Related

Submitting Braintree form after getting payment nonce using hosted fields

I am trying to customize the layout of my Braintree payment form using hosted fields.
I had been using the JS v2 SDK but was having other issues: Braintree - Hosted Fields - Uncaught TypeError: FormNapper requires an HTMLFormElement element or the id string of one
I've tried changing to the v3 SDK.
Here is the stripped down version of my payment form and the braintree.js file that I am using with it:
$.ajax({
url:'web/token.php',
type:'get',
dataType:'json',
success:function(token){
var payment_form = document.querySelector('#payment_form');
var submit_button = document.querySelector('#payment_button');
braintree.client.create({
authorization: token
}, function(err, clientInstance) {
if (err) {
console.error(err);
return;
}
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {'font-size': '14px'},
'input.invalid': {'color': 'red'},
'input.valid': {'color': 'green'}
},
fields: {
number: {selector: '#card-number',placeholder: '4111 1111 1111 1111'},
cvv: {selector: '#cvv',placeholder: '123'},
expirationDate: {selector: '#expiration-date',placeholder: 'MM/YY'}
}
}, function(err, hostedFieldsInstance) {
if (err) {
console.error(err);
return;
}
submit_button.removeAttribute('disabled');
payment_form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
console.log('Got a nonce: ' + payload.nonce);
$('#payment-method-nonce').val(payload.nonce);
// payment_form.submit();
// $('#payment_form').submit();
document.getElementById('payment_form').submit();
});
});
});
});
}
});
<form action="process_order.php" method="POST" class="form" id="payment_form">
<div id="payment_container">
<div class="form-group">
<label for="card-number">Card Number</label>
<div id="card-number" name="card-number"></div>
</div>
<div class="form-group">
<label for="cvv">CVV</label>
<div id="cvv" name="cvv"></div>
</div>
<div class="form-group">
<label for="expiration-date">Expiration Date</label>
<div id="expiration-date" name="expiration-date"></div>
</div>
<input type="hidden" id="payment-method-nonce" name="payment-method-nonce">
<input type="submit" class="btn btn-default mx-auto" value="Complete Order ยป" id="payment_button">
</div>
</form>
<script src="https://js.braintreegateway.com/web/3.50.0/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.50.0/js/hosted-fields.min.js"></script>
<script src="web/braintree.js"></script>
At this point I can get the nonce and it is added to the value of the hidden input but the form won't submit.
When I use the variable name or use document.getElementById() I get TypeError: document.getElementById(...).submit is not a function but when I do it the jQuery way ($) nothing happens.

How can I use field validation in my Vue wizard form?

In an example of a Vue wizard form I tried to add form validation with Joi. How do I set this up logically? The goal is to controll the fields before moving to the second and last page with the next() method. Because of the simplicity of this wizard form, I don't want to change to VueFormWizard. To increase the code I erased a lot of fields etc..
<template>
<div>
<div v-if="errorMessage" class="alert alert-danger" role="alert">
{{errorMessage}}
</div>
<form>
<div v-if="step ===1 ">
<div class="form-group">
<label for="title">Title</label>
<input v-model="example.title"
type="text"
class="form-control"
id="title" />
</div>
<button #click.prevent="next()">Next step</button>
</div>
<div v-if="step === 2">
<div class="form-group">
<label for="userName">Email.</label>
<input v-model="example.userName"
type="email"
class="form-control"
id="userName" />
</div>
<button #click.prevent="prev()">Go back</button>
<button #click.prevent="createExample" type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</template>
<script>
import Joi from 'joi'
const schema = Joi.object().keys({
title: Joi.string().alphanum().min(2).max(40).required(),
userName: Joi.string().email(),
})
export default {
data: () => ({
step: 1,
errorMessage: false,
example: {
title: '',
userName: ''
}
}),
watch: {
example: {
handler () {
this.errorMessage = ''
},
deep: true
}
},
methods: {
prev () {
this.step--
},
next () {
this.step++
if (this.validUser()) {
return false
}
},
createExample () {
// Post request
},
validUser () {
const result = Joi.validate(this.huismap, schema)
return true
if (result.error.message.includes('title')) {
this.errorMessage = 'Vul een titel in van min 2 karakters'
return false
}
}
}
</script>
You can make use of browser validation if you set it up like this:
<form #submit.prevent="submitMyForm">
<input v-model="form.title" required minlength="4" maxlength="20" />
<button type="submit">Submit</button>
</form>
Now your browser will prevent you from submitting the form if title is empty, if the length is less than 4 or greater than 20.
This solution can do a lot of stuff, even regex checking:
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation#Validating_against_a_regular_expression
However this is limited to a small set of checks and is not supported by older browsers. If you need very specific validation you'd have to use a custom solution, which is described here https://v2.vuejs.org/v2/cookbook/form-validation.html.

Semantic UI form validation doesn't update on real time

So I have this Semantic UI standard form:
<form id="signup-form" class="ui form" method="post">
<div class="field">
<label>name</label>
<input type="text" name="fullname" id="fullname">
</div>
<div class="field">
<label>username</label>
<input type="text" name="username" id="username">
</div>
<div class="field">
<label>email</label>
<input type="email" name="email" id="email">
</div>
<div class="two fields">
<div class="field">
<label>password</label>
<input type="password" name="password" id="password">
</div>
<div class="field">
<label>password repeat</label>
<input type="password" name="password-repeat" id="password-repeat">
</div>
</div>
<div class="field">
<div class="ui checkbox">
<input type="checkbox" name="terms" id="terms" tabindex="0" class="hidden">
<label>I accept the terms and conditions</label>
</div>
</div>
<button type="submit" value="signup" class="ui blue submit button pull-left">Sign Up</button>
<div class="ui error message"></div>
</form>
And this is the validation script I use:
<script>
$('#signup-form').form({
fields: {
fullname: {
identifier: 'fullname',
rules: [
{
type: 'empty',
prompt: 'can not be empty'
}
]
},
username: {
identifier: 'username',
rules: [
{
type: 'empty',
prompt: 'can not be empty'
}
]
},
email: {
identifier: 'email',
rules: [
{
type: 'email',
prompt: 'can not be empty'
}
]
},
password: {
identifier: 'password',
rules: [
{
type: 'empty',
prompt: 'can not be empty'
},
{
//type: 'regExp[/^[a-z0-9_-]{6,16}$/]',
type: 'regExp[/^[a-zA-Z0-9_]{6,16}$/]',
prompt: 'not valid'
}
]
},
password_repeat: {
identifier: 'password-repeat',
rules: [
{
type: 'match[password]',
prompt: 'must match the password'
}
]
},
terms: {
identifier: 'terms',
rules: [
{
type: 'checked',
prompt: 'must accept the rules'
}
]
}
}
});
</script>
Everything works as expected but one thing. After user hits the submit button semantic ui checks the form against the validation rules and if it succeeds it will allow the form to be submitted BUT if it doesn't, it shows the error messages and HIDES the submit button. After that even when user fixes the values of the form, it still shows the errors at the bottom of form and submit button is STILL hidden. Using enter key to submit the form works but that's not a very obvious way.
How do I make sure Semantic UI shows the submit button again after the form is fixed??
Turns out it doesn't actually hide it. It just overlaps it. A simple Bootstrap like clearfix div after the button fixes the problem.
<button type="submit" value="signup" class="ui blue submit button pull-left">Sign Up</button>
<div class="clearfix"></div>
Where clearfix is:
.clearfix,
.clearfix:before,
.clearfix:after,
.container:before,
.container:after,
.container-fluid:before,
.container-fluid:after,
.row:before,
.row:after {
content: " ";
display: table;
}
.clearfix:after,
.container:after,
.container-fluid:after,
.row:after {
clear: both;
}

how to validate a form for checkbox

I am trying to validate my checkboxes to ensure that a user clicks at least one checkbox. I am getting checkbox Names from the database. Can anyone solve this please.
$(function(){
$("#userFrm").validate({
rules: {
Item1: {
required: true,
},
},
messages: {
Item1: "Check atleast one box",
}
});
}
<form class="form-horizontal" action="" method="post" name="groupFrm" id="groupFrm">
<div class="control-group">
<label class="control-label">
Access Permission
<span class="error">*</span>
</label>
<div class="controls">
<div class="text-group">
{section name=source loop=$source}
<input type="checkbox" name="option1[]" id="Item1" class="first" {if in_array($source[source].id,$permission_user,true)} checked="checked"{/if} value="{$source[source].id}" />
{$source[source].mod_name}
{/section}
</div>
</div>
</div>
<div class="form-actions">
<input type="submit" name="edit_permission" id="edit_permission" value="Update" class="btn btn-success " onclick="validate()">
</div>
</form>
You have use custom validation code to validate check box.
Try this.
$.validator.addMethod('yourRuleName', function (val, elm, param) {
//Validation code Here
return valid;
}, 'Your error message here');
$('#userFrm').validate({
rules: {
item1: {
yourRuleName: true
}
}
});
This will return true if at least one was checked:
$("input[type=checkbox]:checked").length>0
Or, this will count only the checked checkboxes within that form of yours:
$("#groupFrm:checkbox:checked").length>0

Simple jquery validation - custom position error message placement

I am using jquery validate plugin to validate number in a form , how can i place the returned error message under the input button , i am unable to achieve,
Here is my image with the issue and what i need,pls check - http://i.imgur.com/Gt5aNxs.png
Please suggest me how to put the error message in a custom Div under the button instead of default underneath.
Here is my code:
<section id="contact" class="content">
<div class="container">
<h2>Contact Form Demo</h2>
<div class="row">
<div class="span12 contact-form">
<form action="mail.php" method="POST" class="form-horizontal contact-form" id="contact-form">
<!--<?php $formKey->outputKey(); ?> -->
<fieldset>
<div class="control-group">
<label class="control-label" for="inputPhone">Phone</label>
<div class="controls">
<input class="input-80" name="phone" type="text" id="inputPhone" placeholder="inc. country & area code">
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" value="Send" class="btn" id="btn-place">Send!</button>
</div>
<div >place here</div>
</div>
</fieldset>
</form>
</div>
</div>
</div>
</section>
<!-- javascript -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="js/jquery.validate.min.js"></script>
<script>
// contact form validation
$(document).ready(function(){
$('#contact-form').validate(
{
rules: {
name: {
minlength: 3,
required: true
},
email: {
required: true,
email: true
},
phone: {
minlength: 11,
required: false,
number: true
},
subject: {
minlength: 3,
required: true
},
message: {
minlength: 20,
required: true
}
},
highlight: function(label) {
$(label).closest('.control-group').addClass('error');
},
success: function(label) {
label
.text('OK!').addClass('valid')
.closest('.control-group').addClass('success');
}
});
// contact form submission, clear fields, return message,script no shown here
</script>
All you need to do is specify the errorLabelContainer in your options and specify the div you want the errors to go into:
$('#contact-form').validate({
//all your other options here
errorLabelContainer: '#errors'
});
Then just make sure you specify that your place here div has the id errors like this:
<div id="errors"></div>
See a working example here: http://jsfiddle.net/ryleyb/aaEFQ/ (note that I also specified the wrapper option, which you'll probably want if there are multiple errors).
errorPlacement: function(error, element) {
if((element.attr('name') === 'color[]')){
error.appendTo("div#errors");
}
else if(element.attr('name') === 'font[]' ){
error.appendTo("#font-error");
}
else{
element.before(error);
}
}

Categories

Resources