jQuery Ajax Submit issues - forms

the Form
<article id="signup-form">
<form id="signupform" method="post" action="signup.php" accept-charset="utf-8">
<label for="email">Email Address</label>
<input type="text" id="email" name="email"/>
<input type="image" src="images/btn_signup.png" value="Sign up" alt="Sign up"/>
</form>
<br />
</article>
the Javascript
$(document).ready(function () {
$('#signupform').submit(function () {
var email = $('#email').val();
if (email != 0) {
if (isValidEmailAddress(email)) {
$(this).ajaxSubmit(options);
} else {
alert("Please Enter a Valid Email Address");
}
} else {
alert("Please Enter a an Email Address");
}
return false;
});
var options = {
success: showResponse,
dataType: 'json',
resetForm: true
};
function showResponse(responseText, statusText, xhr, $form) {
if (responseText == 'false') {
alert("Please try again. We could not sign you up.");
}
if (responseText == 'true') {
alert("Success");
}
}
});
function isValidEmailAddress(emailAddress) {
var pattern = new RegExp(/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(#((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(#\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i);
return pattern.test(emailAddress);
}
i get the folowing error and the form submits and goes to the signup.php

You can prevent the forms default event by altering your call
$('#signupform').submit(function (event) and the entering event.preventDefault

Related

Vue3: How to get error messages with Bootstrap and VeeValidate 4?

I want to use vue3 together with bootstrap 4/5 with veevalidate 4.
<template>
<Form as="form" #submit.prevent="onFormSubmit" class="needs-validation" :class="{ 'was-validated': wasValidated }">
<div class="form-group">
<label for="firstNameId">First Name *</label>
<Field name="firstname" as="input" id="firstNameId" type="text" rules="required|firstname" class="form-control" placeholder="First Name" v-model="firstName" aria-describedby="input-true input-false input-help" aria-invalid="true" />
<ErrorMessage as="div" name="firstname" v-slot="{ message }">
{{ message }}
<div class="invalid-feedback">
{{ message }}
</div>
</ErrorMessage>
<div class="valid-feedback">Good!</div>
</div>
<Form>
</template>
<script>
import { Field, Form, ErrorMessage, defineRule } from 'vee-validate';
defineRule('required', value => {
if (!value || !value.length) {
return 'This field is required.';
}
return true;
});
defineRule("firstname", (value) => {
if (!/^[a-zA-Z0-9( ),'.:/-]+$/i.test(value)) {
return "Please use only letters, numbers and the following special characters: ( ),'.:/-";
}
return true;
});
export default {
components: {
Form,
Field,
ErrorMessage
},
data () {
return {
firstName: "",
wasValidated: false,
},
methods: {
onFormSubmit(values) {
alert(JSON.stringify(values, null, 2));
console.log("Submitted");
console.log(values);
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
this.wasValidated = true;
}, false);
});
},
},
};
</script>
The problem is that I can't activate the div with the class invalid-feedback or valid-feedback.
I could add the class was-validated to the <form>-tag, but I get feedback first after the second click on the submit button.
<template>
<Form as="form"
#submit="onFormSubmit"
class="needs-validation"
:validation-schema="schema"
v-slot="{ errors }"
>
<div class="form-group">
<label for="firstNameId">First Name *</label>
<Field
name="firstName"
type="text"
placeholder="First Name"
v-model="firstName"
aria-describedby="input-true input-false input-help"
aria-invalid="true"
v-slot="{ meta, field }"
>
<input
v-bind="field"
name="firstName"
type="text"
class="form-control"
:class="{
'is-valid': meta.valid && meta.touched,
'is-invalid': !meta.valid && meta.touched,
}"
/>
</Field>
<ErrorMessage as="div" name="firstname" v-slot="{ message }" class="invalid-feedback">
{{ message }}
</ErrorMessage>
<Form>
</template>
<script setup>
import { markRaw } from 'vue';
import { Field, Form, ErrorMessage} from 'vee-validate';
import * as yup from 'yup';
</script>
<script>
export default {
components: {
Form,
Field,
ErrorMessage
},
data () {
return {
schema: markRaw(yup.object().shape({
firstName: yup.string().min(0).max(20).label('First Name'),
})),
};
},
methods: {
onFormSubmit(values) {
console.log(JSON.stringify(values, null, 2));
},
},
};
</script>

I dont see the issue with the setInterval

In this code, I would like to clear the message after I successfully sent a message via the form I set up a setInterval but it does not work on the specified code but work when I try it in the console. log.
here is the code the component success-message have the message saying that the message has been sent successfully but won't update with the setInterval.
<template>
<success-message v-if="!successMessage" ></success-message>
<!-- <div v-show="successMessage"> -->
<form #submit.prevent="submitForm" >
<div class="form-control">
<label for='name'>Your Name</label>
<input type="name" id="name" v-model.trim="name"/>
</div>
<div class="form-control">
<label for='email'>Your email</label>
<input type="email" id="email" v-model.trim="email"/>
</div>
<div>
<label for='message'>Your message</label>
<textarea row="5" id="message" v-model.trim="message"></textarea>
</div>
<p class="errors" v-if="!formIsValid">Please you enter all requested informations.</p>
<div class="actions">
<button>Send Message</button>
</div>
</form>
<!-- </div> -->
</template>
<script>
export default {
data(){
return {
name: '',
email: '',
message: '',
successMessage: true,
formIsValid: true,
}
},
methods: {
submitForm(){
this.formIsValid = true;
if (this.name === '' || this.email === '' || !this.email.includes('#') || this.message === '') {
this.formIsValid = false;
return;
} else {
fetch("https://vue-http-demo-8aa03.firebaseio.com/stone.json", {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify({name: this.name,
email: this.email,
message: this.message}),
}).then((data)=>{
if (data.status === 200) {
this.successMessage = false;
this.name ='';
this.email ='';
this.message ='';
setInterval(function(){ this.successMessage=true;}, 3000);
setInterval(function(){ console.log(this.successMessage=true);}, 3000);
}
});
}
},
},
}
</script>
If you want to access valid scope for this, you need to use arrow function for setInterval:
setInterval(() => {
this.successMessage = true;
}, 3000);

Is my HTML form sending to a Netlify lambda function correctly?

With a site running on Netlify, I'm trying to send an automatic reply using Mailgun to a site visitor who submits a form.
I'm trying to follow this example to do it:
https://gist.github.com/flatlinediver/0bdca4c2ae09d34d351d45230d3b2489
However, when I try to run this locally and submit the form (using netlify dev), I keep running into this error:
Request from ::1: POST /.netlify/functions/submission-created
Response with status 500 in 1 ms.
SyntaxError: Unexpected token a in JSON at position 1
at JSON.parse (<anonymous>)
at Object.exports.handler (/Users/sam/Projects/wycd/functions/submission-created.js:15:23)
at /usr/local/lib/node_modules/netlify-cli/src/utils/serve-functions.js:117:29
at Layer.handle [as handle_request] (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/layer.js:95:5)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:137:13)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:131:14)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:131:14)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:131:14)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:131:14)
at next (/usr/local/lib/node_modules/netlify-cli/node_modules/express/lib/router/route.js:131:14)
Here is my file for the function submission-created
require('dotenv').config()
const apiKey = process.env.MAILGUN_API_KEY
const domain = process.env.DOMAIN
// const receiver_mail = process.env.RECEIVER_MAIL
const mailgun = require('mailgun-js')({ apiKey, domain })
exports.handler = function(event, context, callback) {
if(event.httpMethod!='POST' || !event.body){
return callback(new Error('An error occurred!'))
}
const data = JSON.parse(event.body);
if(data.antibot.length>0){
return callback(new Error('Forbidden access'))
}
let messageData = {
from: data.email,
to: data.email,
subject: `Message received from ${data.name}`,
text: `${data.message}`
}
mailgun.messages().send(messageData, function (error) {
if (error) {
return callback(error);
} else {
return callback(null, {
statusCode: 200,
body: 'success'
});
}
})
}
And here is my code for the HTML form on index.html
<form class="contact" id="contactForm" action="/.netlify/functions/submission-created" name="contactForm" method="POST" data-netlify="true">
<input type="text" class="large" id="name" name="name" placeholder="Your Name *" required>
<input type="text" class="large" id="email" name="email" placeholder="example#email.com *" required>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="tel" class="large" id="phone" name="phone">
<script src="build/js/utils.js"></script>
<script>
var input = document.querySelector("#phone"),
output = document.querySelector("#output");
var iti = window.intlTelInput(input, {
nationalMode: true,
utilsScript: "../../build/js/utils.js?1562189064761" // just for formatting/placeholders etc
});
var handleChange = function() {
var text = (iti.isValidNumber()) ? "International: " + iti.getNumber() : "Please enter a number below";
var textNode = document.createTextNode(text);
output.innerHTML = "";
output.appendChild(textNode);
};
// listen to "keyup", but also "change" to update when the user selects a country
input.addEventListener('change', handleChange);
input.addEventListener('keyup', handleChange);
</script>
<input type="text" id="role" name="role" style="display: none;">
<button type="submit" style="background: black; cursor: pointer;">Submit</button>
<p class="text-sm"><em>When you click Submit, we'll send your details to a top climate organization who will guide you on further action.</em></p>
</form>
Can anybody share advice to get this function working as expected?

Reactjs submit form and setState not working first time

I have a submit action for my form which basically validates on submit.
It is working as i expect because when i submit the form it renders the errors. But the issue occurs when i do the submit i do not want to do the ajax request as the form is invalid. I notice that on the first submit the emailError is not set (default) but the second submit the state contains the correct emailError set to true.
I understand from the react docs that setState is not available immeditely as it is pending.
How can i get around this issue?
My code is below
import React, { Component } from 'react';
import isEmail from 'validator/lib/isEmail';
class formExample extends Component
{
constructor(props) {
super(props);
this.state = {
email: '',
emailError: false
};
this.register = this.register.bind(this);
this.updateState = this.updateState.bind(this);
}
updateState(e) {
this.setState({ email: e.target.value });
}
validateEmail() {
if (!isEmail(this.state.email)) {
console.log("setting state");
this.setState({ emailError: true });
return;
}
console.log(this.state);
this.setState({ emailError: false });
}
register(event) {
event.preventDefault();
this.validateEmail();
//only if valid email then submit further
}
render() {
return (
<div className="row">
<div className="col-md-2 col-md-offset-4"></div>
<div className="col-lg-6 col-lg-offset-3">
<form role="form" id="subscribe" onSubmit={this.register}>
<div className="form-group">
<input type="text" className="form-control" placeholder="Email..." name="email" value={this.state.email} onChange={this.updateState} />
<div className="errorMessage">
{this.state.emailError ? 'Email address is invalid' : ''}
</div>
</div>
<div className="input-group input-group-md inputPadding">
<span className="input-group-btn">
<button className="btn btn-success btn-lg" type="submit">
Submit
</button>
</span>
</div>
</form>
</div>
</div>
);
}
}
export default formExample;
in register you call validateEmail, but not return anything, so the rest of the function get's called.
setState is async! so you cannot count on it in the rest of register.
Try this:
validateEmail() {
const isEmailError = !isEmail(this.state.email)
this.setState({ emailError: isEmailError });
return isEmailError;
}
register(event) {
if(this.validateEmail()){
//ajax
};
}
other approach will be:
validateEmail(ajaxCb) {
const isEmailError = !isEmail(this.state.email)
this.setState({ emailError: isEmailError }, ajaxCb);
}
register(event) {
function ajaxCb(){...}
this.validateEmail(ajaxCb)
}

In meteor js ,In edit form i'm unable to display the dropdown box values which i stored during adding a form

I have a form that uses drop-down boxes to save information in mongo
Db. That works fine, but the problem comes when I am trying to edit
the information in the database.I used the same form (add form) to
edit the information. it pulls the values from the database and
displays the fields in the fields accordingly. However, I am having a
hard time figuring out how to populate the drop-down boxes with the
value from the database. Basically, I want the "option selected" tag
to be the database and be able to still have the rest of the options
to select from.in text box I am getting the text values from database
but in drop down I wont be able to get the value.
addmenu.html
<template name="addMenu">
<form class="addingMenus">
<p><input type="text" name="menuName" id="menuName" placeholder="Choose Label" value = {{menuName}}></p>
<p><input type="text" name="associatedPages" id="associatedPages" placeholder="Enter Associated Pages" value= {{associatedPages}}></p>
<p><input type="text" name="menuUrl" id="menuUrl" placeholder="Enter Page URl" value={{menuUrl}}></p>
<p>
<select id="level" >
<option name="parent" value="0" selected = {{rejected}}>parent level</option>
<option name="child" value="1" selected = {{accepted}}>child level</option>
</select>
<select id="childLevel" style="visibility:hidden">
{{#each parent}}
<option value = "{{this._id}}" selected = {{subMenu}} >{{this.menuName}}</option>
{{/each}}
</select>
</p>
<p>
<select id="publishStatus">
<option name="publish" value="true" selected="{{published}}">publish</option>
<option name="unpublish" value="false" selected="{{unpublished}}">unpublish</option>
</select>
</p>
<p><button type="button" class="save-button" id="{{task}}-save-button">SAVE</button></p>
</form>
</template>
addmenu.js:
Template.addMenu.events({
'click #add-menu-save-button': function (event,template) {
//event.preventDefault();
console.log(event);
var levelId = document.getElementById('level').value;
if (levelId == 1) {
parentId = document.getElementById('childLevel').value;
} else {
parentId = "null";
}
var publishStatus = document.getElementById('publishStatus').value;
//console.log(publishStatus);
let menuInsert = {
menuName: document.getElementById('menuName').value,
associatedPages: document.getElementById('associatedPages').value,
menuUrl: document.getElementById('menuUrl').value,
level: document.getElementById('level').value,
createdAt: new Date(),
publishStatus: publishStatus,
parentId: parentId
};
Meteor.call("addMenu", menuInsert, function (error, result) {
if(error) {
console.log("error in adding a menu");
} else {
alert("successfully entered in database");
Router.go('/administrator/admin');
}
});
},
'click #level': function (event, template) {
event.preventDefault();
console.log(document.getElementById('level').value);
if(document.getElementById('level').value == '1') {
document.getElementById("childLevel").style.visibility = "visible";
console.log("iam in session in level");
} else {
document.getElementById("childLevel").style.visibility = "hidden";
}
}
});
Template.addMenu.helpers({
parent: function () {
return menuDetails.find({level: "0"});
},
accepted: function (event) {
console.log(this.level);
if(this.level == "1") {
Session.set('submenu',this.parentId);
console.log(Session.get('submenu'));
return "selected";
}
},
rejected: function (event) {
if(this.level == "0") {
return "selected";
}
},
subMenu: function (event) {
var id = Session.get('submenu');
console.log(this._id);
if(id == this._id) {
return "selected";
}
},
published: function (event) {
if(this.publishStatus == true)
return "selected";
},
unpublished: function (event) {
if(this.publishStatus == false)
return "selected";
}
});
you need to modify your template like this.
<select id="childLevel" style="visibility:hidden">
{{#each parent}}
<option {{isSelected this.menuName}} value = "{{this._id}}">{{this.menuName}}</option>
{{/each}}
</select>
then in the helper you need to write this custom helper.
Template.addMenu.helpers({
isSelected: function(menuName){
return (menuName == 'your conditional value here') ? 'selected': '';
}
});