I'm working on a website.
I have index.html page with div container and I load all the other pages into this div.
I have window.onhashchange function that refreshes the page on url change and loads corresponding html file into that div
I have javascript/ajax contact form.
Problem:
When I click "submit" I expect success or error message to change class and appear under my form. However, "submit" button adds "?" to my URL and, consequently, my page refreshes and all the elements load with default classes.
Question: How can I prevent my "submit" button from adding "?" to my URL? Or am I doing it all wrong?
Codes are shown below:
submit function in my .js file:
$(".form-horizontal").submit(function (e) {
e.preventDefault();
var fname = $("#first-name").val();
var lname = $("#last-name").val();
var email = $("#email").val();
var subject = $("#subject").val();
var message = $("#message").val();
var dataString = 'fname=' + fname + 'lname=' + lname + '&email=' + email + '&subject=' + subject + '&message=' + message;
function isValidEmail(emailAddress) {
var pattern = new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);
return pattern.test(emailAddress);
};
if (isValidEmail(email) && (message.length > 1) && (fname.length > 1)) {
$.ajax({
type: "POST",
url: "sendmail.php",
data: dataString,
success: function () {
$('.contact-success').fadeIn(1000);
$('.contact-error').fadeOut(500);
}
});
} else {
$('.contact-error').fadeIn(1000);
$('.contact-success').fadeOut(500);
}
return false;
});
php file:
<?php
// Email Submit
// Note: filter_var() requires PHP >= 5.2.0
if ( isset($_POST['email']) && isset($_POST['fname']) && isset($_POST['lname']) && isset($_POST['subject']) && isset($_POST['message']) && filter_var($_POST['email'], FILTER_VALIDATE_EMAIL) ) {
// detect & prevent header injections
$test = "/(content-type|bcc:|cc:|to:)/i";
foreach ( $_POST as $key => $val ) {
if ( preg_match( $test, $val ) ) {
exit;
}
}
//
mail( "email#domain.com", $_POST['subject'], $_POST['message'], "From:" . $_POST['email'] );
}
?>
Update:
Thank you very much for suggestions in the comments!
Errors that I get on submit. I also get them on some of my pages.
I checked, it is wrapped in $(document).ready(function().
Form does have class <form class="form-horizontal" role="form">.
In case I won't be able to figure it out, I guess I'll just create separate "Thank you for submitting your message" page. Kind of workaround ))
does element exist when code is run? - need to think more about it! I'll check!
Related
I have a form that submits data to a Google script. Currently my users are sent to Google's page when submitting a form. I tried adding an ajax script to keep them on the page after submitting but when I do that my validation script doesn't work. When I try to combine them neither script works. One of the issues is that the "post" url is decided using a php script (due to Google,s limitations) Below is my code, any help would be appreciated. Thank you!
Submit information to Google and keep user on my page:
$('#agentForm').submit(function(e){
e.preventDefault();
$.ajax({
url:'<?php echo $actionURLs[$counter]; ?>',
type:'post',
data:$('#agentForm').serialize(),
complete:function(){
//whatever you wanna do after the form is successfully submitted
window.location = "agents.php?agentID=<?php echo $_GET['agentID']; ?>&email=<?php echo $_GET['email']; ?>&action=submitted";
}
});
});
Validation:
// Wait for the DOM to be ready
function validateForm()
{
var pax = jQuery('input[name="passengers"]:checked').length > 0;
var rph = jQuery('input[name="reservation"]:checked').length > 0;
var validationPassed = true;
var msg = '';
//console.log(pax);
//console.log(rph);
//console.log(jQuery('#mco').val());
//console.log(jQuery("input:radio[name='flights']").is(":checked"));
//console.log(jQuery("input:radio[name='iscorrect']").is(":checked"));
if(!pax){
validationPassed = false;
msg +='Please select at least one passenger.</br>';
}
if(!rph){
validationPassed = false;
msg +='Please select at least one segment.</br>';
}
if(jQuery('#mco').val() != '' && !jQuery.isNumeric(jQuery('#mco').val())){
validationPassed = false;
msg +='MCO Amount must be a numeric value.</br>';
}
if (!jQuery("input:radio[name='flights']").is(":checked")){
validationPassed = false;
msg +='Are all flights being flown?</br>';
}
if (!jQuery("input:radio[name='iscorrect']").is(":checked")){
validationPassed = false;
msg +='Is the total correct?</br>';
}
else if(jQuery('input[name=iscorrect]:checked').val() == 'INCORRECT' && jQuery('#correct_amount').val() == ''){
validationPassed = false;
msg +='Please specifiy the correct amount.</br>';
}
else if(jQuery('input[name=iscorrect]:checked').val() == 'INCORRECT' && jQuery('#correct_amount').val() != '' && !jQuery.isNumeric(jQuery('#correct_amount').val())){
msg +='Correct amount must be a numeric value.</br>';
}
if(!validationPassed){
jQuery('.errors').show();
jQuery(window).scrollTop(jQuery('.errors').offset().top);
}
jQuery('.errors').html(msg);
return validationPassed;
}
jQuery( document ).ready(function() {
jQuery("input[name='iscorrect']").click(function(){
jQuery('#correct_amount').val('');
/*if(jQuery('input[name=iscorrect]:checked').val() == 'INCORRECT'){
jQuery("#correct_amount").prop("readonly", false);
}
else{
jQuery('#correct_amount').val('');
jQuery("#correct_amount").prop("readonly", true);
}*/
});
jQuery("input[name='correct_amount']").click(function(){
jQuery('#INCORRECT').prop('checked', true);
});
});
I think your validation is not working because you have stopped propagation of the event in your JavaScript first code with e.preventDefault().
Try to call validateForm() directly inside your first submit event listener, like that:
$('#agentForm').submit(function(e){
validateForm();
e.preventDefault();
$.ajax({
url:'<?php echo $actionURLs[$counter]; ?>',
type:'post',
data:$('#agentForm').serialize(),
complete:function(){
//whatever you wanna do after the form is successfully submitted
window.location = "agents.php?agentID=<?php echo $_GET['agentID']; ?>&email=<?php echo $_GET['email']; ?>&action=submitted";
}
});
});
hello i have a login validation form which uses a mix of jquery and ajax to do validations... if the values are ok the form should submit, if the values are not ok then the form should not submit... however in my case the form is submitting even when the values are incorrect ( i am using the mousedown function ) please see below my code..
<form method="post" name="loginform" action="models/login.php">
<input type="email" class="homepage" name="user_email2" id="user_email2" placeholder="Email" maxlength="50" />
<div class="errormsg" id="errormsg6"></div>
<input type="password" class="homepage" name="user_password2" id="user_password2" placeholder="Password" maxlength="20" />
<div class="errormsg" id="errormsg7"></div>
<input type="submit" name="login" id="login" value="Submit">
<div class="errormsglast" id="errormsg8"></div>
</form>
jquery and ajax
$(document).ready(function()
{
/* ----------------- Login Validations Global Variables ----------------- */
var user_email2 = "";
var user_emailajax2 = "";
var user_password2 = "";
var user_passwordajax2 = "";
var emailformat = new RegExp(/^[+a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i);
/* ----------------- Define Validate Email */
var validate_email_login = function()
{
var item5 = $("#user_email2").val().toLowerCase();
if (item5.length < 6 || item5.length > 50)
{
$("#errormsg6").html("Email : 6 - 50 Characters");
user_email2 = "";
}
else
{
$("#errormsg6").html("");
user_email2 = item5;
if (!emailformat.test(item5))
{
$("#errormsg6").html("Wrong Email Format");
user_email2 = "";
}
else
{
$("#errormsg6").html("");
user_email2 = item5;
$.ajax(
{
type: 'POST',
url: 'classes/validatelogin.php?f=1',
data: "user_email2=" + item5,
success: function(msg)
{
if (msg == "ok")
{
user_emailajax2 = "";
$("#errormsg6").html("Email Does Not Exist");
}
else if (msg == "exists")
{
user_emailajax2 = item5;
$("#errormsg6").html("");
}
}
});
}
}
}
/* ----------------- Define Validate Password */
var validate_password_login = function()
{
var item5 = $("#user_email2").val().toLowerCase();
var item6 = $("#user_password2").val();
if (item6.length < 8 || item6.length > 20)
{
$("#errormsg7").html("Password : 8-20 Characters");
user_password2 = "";
}
else
{
$("#errormsg7").html("");
user_password2 = item6;
if (user_email2 != "" && user_emailajax2 != "")
{
$.ajax(
{
method: "POST",
url: "classes/validatelogin.php?f=2",
data: "user_email2=" + item5 + "&user_password2=" + item6,
success: function(msg)
{
if (msg == "WrongPw")
{
user_passwordajax2 = "";
$("#errormsg7").html("Wrong Password - See Forgot Password");
}
else if (msg == "CorrectPw")
{
user_passwordajax2 = item6;
$("#errormsg7").html("");
/* window.location.href="manage-properties"; */
}
}
});
}
}
}
/* ----------------- Run Functions */
$("#user_email2").on('focusout', validate_email_login);
$("#user_password2").on('focusout', validate_password_login);
/* ----------------- Stop on Submit */
$( "#login" ).mousedown(function()
{
validate_email_login();
validate_password_login();
if (user_email2 == "" || user_emailajax2 == "" || user_password2 == "" || user_passwordajax2 == "")
{
$("#errormsg8").html("Please Fill All Fields (Correctly)");
console.log("submit false");
return false;
}
else
{
$("#errormsg8").html("");
console.log("submit true");
return true;
}
});
});
Solution Tried - problem is that when user puts the wrong event that is fine, but if user then puts the correct values, the submit returns false on first time, then second time it returns true... it should return true in first go
<input type="button" name="login" id="login" value="Submit">
$( "#login" ).mousedown(function()
{
validate_email_login();
validate_password_login();
if (user_email2 == "" || user_emailajax2 == "" || user_password2 == "" || user_passwordajax2 == "")
{
$("#errormsg8").html("Please Fill All Fields (Correctly)");
console.log("submit false");
return false;
}
else
{
$("#errormsg8").html("");
console.log("submit true");
$('[name=loginform]').submit();
}
});
});
Instead of having a type="submit" button just have a normal button e.g<input type="button" name="login" id="login" value="Submit">. Then when you finished checking the values and happy that it should send then just call:
$('[name=loginform]').submit();
Because what is happening currently is that the form submits when you click on the button, because you are not stopping that event from happening.
If you want to prevent the form from submitting I would suggest either not using that button and initiating the submit yourself like I mentioned above, or alternatively you can use the onsubmit="someFunction()" on the form element way and just return false if it should not submit and return true if it should.
I would say your code suffers from a few issues and some bad practices.
I see you are trying to learn JS so forgive me for not directly solving your issue but to give you some pointers and point you to some best practices.
Logic -
It seems like you are doing a login form. I would say most of this checks should not happen in the client but on the server.
When user signups it might be wise to check user name length on the client as well and prompt the user that he can't use the user name he wants to register with, but during login all the client care is can I login or not.
Security -
You seem to have two serious security issues with your code
You allow to test if an e-mail/user exist or not using 'classes/validatelogin.php?f=1'. in general you should always test the user and password together if they exist and match the user should be able to login, if not the login should fail. you shouldn't notify the user why it fails (if the user name does not exist or if it exist but the password is wrong).
You don't seem to hash passwords in the database. I assume it by limiting the password max length. let the user choose as long password as he wants and hash it using a secure hashing algorithm (I'd suggest bcrypt but google around and find a suitable one). I know you are only learning but this is highly important I think hashing is the first thing you need to learn when handling user logins
Working with the DOM.
You should cache your DOM elements
so instead of calling $('#id') all the time in the main function scope set
var emailInput = $("#user_email2");
function submitForm() {
var email = emailInput.val().toLowerCase();
...
}
You should also probably set the text value of the element and not the html doesn't matter much now but since you are setting text value its good practice and will help you avoid unexpected injections and errors.
Since your using ajax you should not let the form to submit itself even when validation is successful.
Common logic should be packed into functions and reused.
There are many places where your original code can be split into shorter and reusable functions
handle async code better
jQuery supports the Promise API when using ajax requests, I would rather use it. Your original code had a few async calls if you needed to sync between them it would have been painful using plain callbacks (and it is probably what caused you issues in the first place)
Here is a simplified solution using my suggestions -
$(document).ready(function() {
"use strict";
var emailInput = $("#user_email2"),
emailError = $("#errormsg6"),
passwordInput = $("#user_password2"),
passwordError = $("#errormsg7");
function required (value) {
if (value) {
return true;
} else {
return false;
}
//this is just to make the code clear you could use
//`return value ? true : false` or `return !!value`
}
$('form:eq(0)').on('submit', function (e) {
var valid = true,
email = emailInput.val(),
password = passwordInput.val();
e.preventDefault();
if ( !required(email) ) {
emailError.text('Email is required');
valid = false;
}
if ( !required(password) ) {
passwordError.text('Password is required');
valid = false;
}
if ( valid ) {
$.ajax({
method: "POST",
url: "login.php",
data: {
email: email,
password: password
}
}).done(function (data, textStatus, jqXHR) {
//redirect user to main page
}).fail(function (jqXHR, textStatus, errorThrown) {
//show the user the error
})
}
});
});
I've created action onClick in GridView and it redirects me to an action in controller.
Code in Index.php:
},
'rowOptions' => function ($model, $key, $index, $grid) {
return ['id' => $model['id'], 'onclick' => 'var myid=this.id; var enteredValue = prompt("Please enter a number");
window.location.href = "index.php?r=patientservices%2Fpassing" + "&id=myid, " + enteredValue; '];
},
In my Controller code:
public function actionPassing($id,$price)
{
$ser= $this->findModel($id);
$model = new Receipts();
$countclinic=Receipts::find()
->where(['patient_services_id'=>$id])
->count();
if ($countclinic== 0) {
$model->patient_id=$ser->patient_id;
$model->price=$price; // the price that i need to pass
$model->doctor_id=$ser->doctor_id;
$model->patient_services_id=$ser->id;
$model->reg_date=DATE('y-m-d h:m:s');
$model->description='دفعة تحت الحساب';
$model->userin = \Yii::$app->user->identity->id ;
$model->save();
$models = $this->findModel($id);
$models->state=2;
$models->save();
JS Code :
$this->registerJs("
$('.custom_button').on('click', function() {
alert(id);
var enteredValue = prompt('Please enter a number');
if (enteredValue != null) {
window.location.href = 'index.php?r=patientservices%2Fpassing' + '&id=, ' + enteredValue;
}
});
");
What I need is:
When the user clicks on the Row in GridView a prompt text appears for the user and the number inserted in the prompt text is passed with the ID to controller to use it there but the js code pass the id as a character not like number
$model->price=$ser->price;
Here's how you can do it:
Instead of using link, use # as a link since you don't want to redirect user just yet.
After user clicks on button, you want to "summon" a prompt. This can be achieved by JavaScript/jQuery only.
Inside the JavaScript/jQuery code you can insert PHP code, too, and form an URL.
For example (in GridView):
'buttons' => [
'passing' => function () {
return Html::a('Content', '#', [
'class' => 'btn btn-primary custom_button',
'title' => 'تسجيل القيمة كـ إيصال',
]);
},
],
Then at the end of file:
$this->registerJs("
$('.custom_button').on('click', function() {
var enteredValue = prompt('Please enter a number');
if (enteredValue != null) {
window.location.href = '".$url."' + '&id= ' + enteredValue;
}
});
");
Worth to note I have included a class custom_button since we want to know if the button user clicked is the correct one, not any.
I have absolutely no idea how to add a 'thank you page' submission to my clients website. I am not experienced in coding, only UI etc.
Here is a [link][1] to site in question.
(EDIT) Let me elaborate. I am using Blocs (bootstrap wysiwyg app) and there is a form submit. I now need to add a 'thank-you' page redirect for google analytics purposes. The code below is what I believe will be able to help:
$(function()
{
var successMsg = "Your message has been sent."; // Message shown on success.
var failMsg = "Sorry it seems that our mail server is not responding, Sorry for the inconvenience!"; // Message shown on fail.
$("input,textarea").jqBootstrapValidation(
{
preventSubmit: true,
submitSuccess: function($form, event)
{
if(!$form.attr('action')) // Check form doesnt have action attribute
{
event.preventDefault(); // prevent default submit behaviour
var processorFile = "./includes/"+$form.attr('id')+".php";
var formData = {};
$form.find("input, textarea, option:selected").each(function(e) // Loop over form objects build data object
{
var fieldData = $(this).val();
var fieldID = $(this).attr('id');
if($(this).is(':checkbox')) // Handle Checkboxes
{
fieldData = $(this).is(":checked");
}
else if($(this).is(':radio')) // Handle Radios
{
fieldData = $(this).val()+' = '+$(this).is(":checked");
}
else if($(this).is('option:selected')) // Handle Option Selects
{
fieldID = $(this).parent().attr('id');
}
formData[fieldID] = fieldData;
});
First, submit the form and then catch the post. Handle the form and redirect.
<?php
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Handle your form
// redirect
header("Location: thank-you.php");
exit;
}
?>
<form metod="POST" action="<?= $_SERVER['REQUEST_URI']; ?>">
<button type="submit">Send</button>
</form>
So i am creating a simple form that checks whether or not the value that the user is inputting exists or not in my DB using jQuery. Everything up until now is working so far however i find myself stuck at this next part.
To easily explain i will just show an example of what i am trying to achieve.
For this example i will be "weeden"
weeden has an ID of 255 in the company table of my database.
If the user types in "weeden" into the client field
To the right of the client field (on the web form), the text "weeden is unavailable" will appear
what i would like to have happen instead is this: "ID 255 is unavailable"
Here is the relevant code.
HTML FORM
<form action="addrecord.php" method="post" autocomplete="off"/>
<div class="form-field">
<label for="client">Client: </label>
<input type="text" name="client" id="client" class="check-exists" data-type="client" placeholder="#">
<span class="check-exists-feedback" data-type="client"></span>
</div>
jQuery Function
$.fn.existsChecker = function(){
return this.each(function(){
var interval;
$(this).on('keyup', function(){
var self = $(this),
selfType = self.data('type'),
selfValue,
feedback = $('.check-exists-feedback[data-type=' + selfType + ']');
if(interval === undefined){
interval = setInterval(function(){
if(selfValue !== self.val()){
selfValue = self.val();
if(selfValue.length >= 1){
$.ajax({
url: 'check.php',
type: 'get',
dataType: 'json',
data: {
type: selfType,
value: selfValue
},
success: function(data){
if(data.exists !== undefined){
if (data.exists === true){
feedback.text(selfValue + ' is already taken.');
}else {
feedback.text(selfValue + ' is available');
}
}
},
error: function(){
}
});
}
}
}, 1000);
}
});
});
};
Check.php
$db= new PDO('mysql:host=host;dbname=mydb', 'user', 'pass');
if(isset($_GET['type'], $_GET['value'])){
$type = strtolower(trim($_GET['type']));
$value= trim($_GET['value']);
$output = array('exists' => false);
if(in_array($type,
array('client')
)
){
switch($type){
case 'client':
$check = $db->prepare("
SELECT COUNT(*) AS count
FROM company
WHERE name = :value
");
break;
$check->execute(array('value'=> $value));
$output['exists'] = $check->fetchObject()->count ? true: false;
echo json_encode($output);
Any help/suggestions would be greatly appreciated. I consider myself a beginner, this is my first time working on a web project.
Just to clarify ahead of time, there are many other input fields on the same webform such as: email, date, first, last, etc.
I hope my question was clear enough. Thank you
You have to change your Query to something like this:
$check = $db->prepare("
SELECT id, COUNT(*) AS count
FROM company
WHERE name = :value
");
I assume that your primary key field on the company-table is named id.
And finally store the id in the output-Array
$result = $check->fetchObject();
$output['exists'] = $result->count ? true: false;
$output['id'] = $result->id;
Then you can output the id like so:
if (data.exists === true){
feedback.text('ID ' + data.id + ' is unavailable');
}
You can handle everything in query
$db= new PDO('mysql:host=host;dbname=mydb', 'user', 'pass');
if(isset($_GET['type'], $_GET['value'])){
$type = strtolower(trim($_GET['type']));
$value= trim($_GET['value']);
$output = array('exists' => false);
if(in_array($type,array('client'))){
switch($type){
case 'client':
$check = $db->prepare("
SELECT (CASE WHEN(COUNT(id)>0) THEN id ELSE FALSE END) AS count
FROM company WHERE name = :value ");
break;
}
$check->execute(array('value'=> $value));
$output['exists'] = $check->fetchObject()->count ? true: false;
echo json_encode($output);
}
In Ajax success
if(data.exists !== undefined){
if (!data.exists){
feedback.text(selfValue + ' is already taken.');
}else {
feedback.text(selfValue + ' is already taken.');
}
}