I am using ajax to validate user credentials after i have validated the user has input data into the required fields but afterwords the form is not being submitted. I have created a variable submit_form which is supposed to determine if the default form action is performed or not but when set it to true and console log it, it still seems to continue it's default value of false, why is it like that and how can change it so my form can submit after the username and password are correct.
Here is my screenshot of the console in the browser
Here is a my code:
/*global $*/
/*global _*/
$(document).ready(function() {
'use strict';
$('#login-form').on('submit', function(event) {
var form_items = {
username: { required: true, name: 'Username' },
password: { required: true, name: 'Password' },
token: {}
};
var $login_form = $(this);
var submit_form = false;
var errors;
var display = '';
var data;
var validation = new Validation( form_items );
validation = validation.check( $login_form['context'] );
// If any element has the class for errors, remove the class
$('.has-error').removeClass('has-error');
if ( validation.passed() ) {
data = JSON.stringify( validation.getData() );
$.ajax({
method: "POST",
url: "ajax/login.ajax.php",
data: { info: data }
}).done(function( response ) {
response = JSON.parse(response);
// if the error list display is there, remove it
$('.bg-danger').parent().remove();
if ( _.has(response, 'errors') ) {
errors = response['errors'];
display = '<div class="form-group"><ul class="bg-danger">';
if ( _.isArray(errors) || _.isObject(errors) ) {
_.each( errors, function(elem, index, list) {
display += '<li>' + elem + '</li>';
});
} else {
display += '<li>' + errors + '</li>';
}
display += '</ul></div>';
$login_form.prepend( display );
} else {
submit_form = true;
}
});
console.log( submit_form );
} else {
// if the error list display is there, remove it
$('.bg-danger').parent().remove();
errors = validation.getErrors();
display = '<div class="form-group"><ul class="bg-danger">';
_.each( errors, function(elem, index, list) {
var $form_element = $('#'+index); // get form element
$form_element.parent().parent().addClass('has-error');
display += '<li>' + elem + '</li>';
});
display += '</ul></div>';
$login_form.prepend( display );
}
if ( !submit_form ) {
event.preventDefault();
}
});
});
Related
I am trying to use Ajax that will keep
the inputs that the user has entered but for some reason, it isn't working.
In case of an error, my controller redirects the view with the data of errors,
however, after the page is uploading the form is empty.
I am using the MVC model of Codeigniter.
$("#save").click(function () {
var tnum1 = $("#tnum1").val();
var tnum2 = $("#tnum2").val();
var tnum3 = $("#tnum3").val();
var loc = $("#loc").val();
var dine = $("#dine").val();
var date = $("#date").val();
var time = $("#time").val();
var phone = $("#phone").val();
var fullname = $("#fullname").val();
$.ajax({
type: 'POST',
url: "<?php echo site_url(); ?>" + "/hosting/create",
data: {tnum1:tnum1, tnum2:tnum2, tnum3:tnum3, loc:loc, dine:dine,
date:date, time:time, phone:phone, fullname: fullname},
error: function () {
alert( "Load was performed.");
},
success: function (data) {
if (data === "") {
window.location.href = "<?php echo site_url('hosting/tableMap'); ?>";
}
else {
$("#error").html(data);
}
}
});
});
Controller
public function create() {
$newDate = date("Y-m-d",strtotime($this->input->post('re_date')));
$newTime = date("H:i", strtotime($this->input->post('re_time')));
$data = array(
'num' => $this->input->post('num'),
'location' => $this->input->post('location'),
'diners' => $this->input->post('diners'),
're_date' => $newDate,
're_time' => $newTime,
'phonenumber' => $this->input->post('phonenumber'),
);
$dataclient = array(
'fullname' => $this->input->post('fullname'),
'phonenumber' => $this->input->post('phonenumber'),
);
$error = $this->validation($data,$dataclient);
if ($error) {
$data['error'] = $this->session->set_flashdata('error','<b><u>Failed! </u></b>'.$error.'');
redirect(base_url("/hosting/tableMap"));
} else {
$this->Hosting_model->form_insert($data, $dataclient);
}
}
If you redirect the controller then it will not retain the previous values. Instead save the error in a variable and return it to ajax function.
That is the whole point of ajax - to not redirect or reload a page ie do the task asynchronously.
remove this line-
redirect(base_url("/hosting/tableMap")); // redirecting on error
then in your controller
if ($error) {
// data['error'] = $this->session->set_flashdata('error','<b><u>Failed! </u></b>'.$error.''); // remove this as page will not reload, flashdata wouldn't work
// redirect(base_url("/hosting/tableMap"));
$ajax_data['error'] = 1; // if error exists then value
$ajax_data['validation_error'] = $error;
} else {
$this->Hosting_model->form_insert($data, $dataclient);
$ajax_data['error'] = 0; // if error doesn't exist then value
}
return json_encode($ajax_data); // or echo json_encode($ajax_data);
Now, to prevent default action of form submission that is to redirect page use
$("#save").click(function (e) {
e.preventDefault();
// rest of your code
then in your ajax success:
if (data.error == 0) { // no error
window.location.href = "<?php echo site_url('hosting/tableMap'); ?>";
}
else { // error
$("#error").html(data); // do whatever you want to do with error
// errors can be retrieved from "data.validation_error" -- it will be an array probably sp you'll have to loop through each element
}
I have a couple of jQuery functions that pass PHP data to the JS function using the wordpress wp_localize_scripts function:
function mb_scripts_settings() {
// blanks
$mb_ajax_form_type = $mb_get_page_slug = $mb_redirect = $mb_redirect_time = $mb_form_disable = $mb_array = '';
// get the form type
$mb_ajax_form_type = ( is_front_page() ? 'change' : 'submit' );
// get the page slug from ID
$mb_get_page_slug = get_post_field( 'post_name', get_the_ID() );
// if the page is admin or password
if( is_page( array('admin', 'pw') ) ) {
$mb_redirect = true;
$mb_redirect_time = 3000;
$mb_form_disable = true;
if( is_page('admin') ) {
// generate the url for redirection
$mb_form_area = ( ( is_page('admin') && isset($_GET['mbtab']) ) ? $_GET['mbtab'] : null );
$mb_form_area_url = ( empty($mb_form_area) ? '/' : '/admin/?mbtab=' . $mb_form_area . '&mbform=1' );
$mb_form_area_url = get_home_url( $mb_form_area_url );
}
}
// if the page is front
if( is_front_page() ) {
$mb_redirect = false;
$mb_redirect_time = 0;
$mb_form_disable = false;
$mb_get_page_slug = 'front_page';
$mb_form_area = $mb_form_area_url = null;
}
// build the array
$mb_array = array(
$mb_ajax_form_type,
$mb_get_page_slug,
$mb_redirect,
$mb_redirect_time,
$mb_form_disable
);
return $mb_array;
}
Which would output an array with all the needed data for the JS function:
// create the script
$(function() {
// var
var mb_form_type = mb_mbtheme_js[0],
mb_form_type = '.' + mb_form_type,
mb_get_page_slug = mb_mbtheme_js[1],
mb_redirect = mb_mbtheme_js[2],
mb_redirect_time = mb_mbtheme_js[3],
mb_form_disable = mb_mbtheme_js[4];
// trigger the ajax on form type
// $("#mb_ajax_form") + mb_form_type + ( function( mb_ajax_form ) {
$("#mb_ajax_form").change( function( mb_ajax_form ) {
// stop the default function of buttons
mb_ajax_form.preventDefault();
// do the ajax
mb_ajax_form_js();
});
});
// accept the form ID
function mb_ajax_form_js() {
// get the vriables
var mb_ajax_form_data = new FormData( $("#mb_ajax_form")[0] ),
mb_ajax_form_time = 60,
mb_ajax_form_links = "#mb_ajax_form input, #mb_ajax_form submit, #mb_ajax_form button";
// do the ajax
$.ajax({
method: "POST",
data: mb_ajax_form_data,
contentType: false,
processData: false,
// the before send function
beforeSend: function( before ) {
// lock the form input and select
$( mb_ajax_form_links ).prop( "disabled", true );
},
// the success function
success: function( success ) {
// show the response
$( "#response" ).show().html( success );
// scroll to the top of the container - response divHeight
$( "section.mbcontainer" ).animate({
scrollTop: $( "#response" ).offset().top
}, "slow" );
// re-enable the submit button
// $( mb_ajax_form_links ).prop( "disabled", false );
},
// the complete function
complete: function( complete ) {
// if we are seeing the success message
if( $( "#response div" ).hasClass( "mbsuccessmessage" ) ) {
// the admin or password page conditions
if( mb_get_page_slug == 'admin' || mb_get_page_slug == 'pw' ) {
// set the redirection
setTimeout( function() { window.location.replace( mb_redirect ); }, mb_redirect_time );
// what to do with the form
$( mb_ajax_form_links ).prop( "disabled", mb_form_disable );
}
// the front page conditions
if( mb_get_page_slug == 'front_page' ) {
// set the redirection
setTimeout( function() { $(".mbsuccessmessage").slideUp(); }, mb_redirect_time );
}
}
},
// the error function
error: function( error ) {
// log the error
console.error( error );
}
});
}
However, it doesn't seem to be working as I thought it would when it wasn't being passed via the array and was all hard coded in. Things like the mb_form_type weren't working until I created a new variable with the '.' + mb_form_type.
Now it is spitting an error on the complete: function but I have also tried setting the if statement to compare as String() == String(mb_get_page_slug) == String('admin') but that didn't work either.
Is there something I am missing in the comparisons?
Your issue is one of scope. $(function() {}); creates a closure and you define your vars in that closure. Code outside the closure cant see those variables. To fix this, you have several options, here are 2 that would work:
1) move the variables to outside the closure like this:
// var
var mb_form_type = mb_mbtheme_js[0],
mb_form_type = '.' + mb_form_type,
mb_get_page_slug = mb_mbtheme_js[1],
mb_redirect = mb_mbtheme_js[2],
mb_redirect_time = mb_mbtheme_js[3],
mb_form_disable = mb_mbtheme_js[4];
// create the script
$(function() {
// trigger the ajax on form type
// $("#mb_ajax_form") + mb_form_type + ( function( mb_ajax_form ) {
$("#mb_ajax_form").change( function( mb_ajax_form ) {
// stop the default function of buttons
mb_ajax_form.preventDefault();
// do the ajax
mb_ajax_form_js();
});
});
// accept the form ID
function mb_ajax_form_js() {
// your code here...omitted for brevity
}
2) move your function inside the closure like this (note, anything calling mb_ajax_form_js will also need to be inside the closure):
// create the script
$(function() {
// var
var mb_form_type = mb_mbtheme_js[0],
mb_form_type = '.' + mb_form_type,
mb_get_page_slug = mb_mbtheme_js[1],
mb_redirect = mb_mbtheme_js[2],
mb_redirect_time = mb_mbtheme_js[3],
mb_form_disable = mb_mbtheme_js[4];
// trigger the ajax on form type
// $("#mb_ajax_form") + mb_form_type + ( function( mb_ajax_form ) {
$("#mb_ajax_form").change( function( mb_ajax_form ) {
// stop the default function of buttons
mb_ajax_form.preventDefault();
// do the ajax
mb_ajax_form_js();
});
// accept the form ID
function mb_ajax_form_js() {
// your code here...omitted for brevity
}
});
Update:
For accessing the submit and change functions using a string variable (mb_form_type), you'll need to use the "array access syntax" rather than the dot notation you have tried.
As a simple example, this would work (note that mb_form_type doesnt contain the .):
var mb_form_type = 'change';
$("#mb_ajax_form")[mb_form_type]( function( mb_ajax_form ) {
alert('This will work using array access syntax');
});
here's a working example
In laravel 5.7 / jquery 3 app looking at the snippet https://bootsnipp.com/snippets/ykXa
I made similar, but having several input/select elements.
I add new row with input/select elements code :
$(document).on('click', '.todo-btn-add', function(e)
{
e.preventDefault();
var todos_count= parseInt($("#todos_count").val())+1
var controlForm = $('.controls form:first'),
currentEntry = $(this).parents('.entry:first'),
newEntry = $(currentEntry.clone()).appendTo(controlForm);
var modifiedHidden= newEntry.find('input');
modifiedHidden.val('1');
modifiedHidden.attr('id','todo_modified_'+todos_count);
modifiedHidden.attr('name','todo_modified_'+todos_count);
var todo_text_input= modifiedHidden.next( "input" )
todo_text_input.val('');
todo_text_input.attr('id','todo_text_'+todos_count);
todo_text_input.attr('name','todo_text_'+todos_count);
var todo_select_priority= newEntry.find( "select" )
todo_select_priority.val('');
todo_select_priority.attr('id','todo_priority_'+todos_count);
todo_select_priority.attr('name','todo_priority_'+todos_count);
var todo_select_completed= todo_select_priority.find( "select" )
todo_select_completed.val('');
todo_select_completed.attr('id','todo_completed_'+todos_count);
todo_select_completed.attr('name','todo_completed_'+todos_count);
controlForm.find('.entry:not(:last) .todo-btn-add')
.removeClass('todo-btn-add').addClass('btn-remove')
.removeClass('btn-success').addClass('btn-danger')
.html('<span class="fa fa-minus"></span>');
$("#todos_count").val( todos_count )
}).on('click', '.btn-remove', function(e)
{
$(this).parents('.entry:first').remove();
$("#todos_count").val( parseInt($("#todos_count").val())-1 )
e.preventDefault();
return false;
});
But problem that saving the form I collect all data in 1 array to save it on server with:
function saveTodoDialog( csrf_token ) {
let todos_count= $("#todos_count").val()
let todosList= [];
for(let i= 0; i< todos_count; i++) {
let todoItem = {
todo_id: $("#todo_id_" + i).val(),
todo_modified: $("#todo_modified_" + i).val(),
todo_text: $("#todo_text_" + i).val(),
todo_priority: $("#todo_priority_" + i).val(),
todo_completed: $("#todo_completed_" + i).val()
}; //Object initialiser
alert("todos_count::"+todos_count+ " i::"+i+"todoItem::"+var_dump(todoItem) )
todosList.push(todoItem);
}
console.log("todosList::")
console.log( todosList )
let href = "/admin/save-todo-page";
$.ajax({
type: "POST",
dataType: "json",
url: href,
data: { "_token": csrf_token, "todosList" : todosList },
success: function (response) {
popupAlert("Todo items were saved successfully !", 'success')
},
error: function (error) {
popupErrorMessage(error.responseJSON.message)
}
});
But checking data for any row I see that all data for newly added rows has undefined value.
How to fix it ?
Thanks!
If the error is happening because you are getting undefined from your inputs, I suggest adjusting your saveTodoDialog() method.
function saveTodoDialog( csrf_token ) {
let todoList = Array.prototype.slice
.call( document.querySelectorAll('input.form-control') )
.map( (todo, index) => {
// Create Individual TODO object
});
// Make server request
}
I am getting data from a form and on submit button if data ios not valid it returns false and if data is valid am sending an email through ajax in its success method am showing a modal for sent or not I want window.location.href to be change after modal is hidden as form submits before even modal is displayed so I used event.preventdefault to stop it from submit but now have two issues
browser gets stuch until modal is open
after modal window.location is not being changed.
here is my code for submit button
<input type="submit" class="button btn btn-primary" onclick ="return SendEmail();" />
here is SendEmail()
function SendEmail()
{
if (!CheckContactUsFormValidation()) {
return false;
}
else{
var l_strEmail = document.getElementById('txtEmail').value;
var l_strComents = document.getElementById('txtComments').value;
var l_strEventLocation = document.getElementById('txtEventLocation').value;
var l_strStartDate = document.getElementById('txtStartDate').value;
var l_strOrganization = document.getElementById('txtOrganization').value;
var l_strPhone = document.getElementById('txtPhone').value;
var l_strLastName = document.getElementById('txtLastName').value;
var l_strFirstName = document.getElementById('txtFirstName').value;
var rent = document.getElementById("inlineRadio1").value;
var lease = document.getElementById("inlineRadio2").value;
if (rent.checked == true) {
var l_strCheck = 'rent';
}
else {
if (lease.checked == true) {
var l_strCheck = 'lease';
}
}
var l_strTitle = "Contact Us";
var l_strContents = 'Hi, ' + l_strFirstName + ' ' + l_strLastName + '\n';
l_strContents += 'he is mail for requesting product on ' + l_strCheck + ' and start date is ' + l_strStartDate + ' for organization ' + l_strOrganization + '\n';
l_strContents += 'his cell #' + l_strPhone + ' and his coments are as follows \n';
l_strContents += l_strComents + '\n' + 'You can contact him on email: ' + l_strEmail;
l_strContents += 'End here!';
var l_strtoEmail = 'abc#yahoo.com';
SendEmailWithCustomTitle(l_strtoEmail, l_strContents, l_strTitle);
}
return true;
}
function CheckContactUsFormValidation() {
var m_boolValidator = true;
if (!CheckRequiredFieldValidation('FirstName', 'Enter first name')) {
m_boolValidator = false;
}
if (!CheckRequiredFieldValidation('LastName', 'Enter last name')) {
m_boolValidator = false;
}
if (!CheckRequiredFieldValidation('Organization', 'Enter Organization')) {
m_boolValidator = false;
}
if (!CheckRequiredFieldValidation('Email', 'Enter Email')) {
m_boolValidator = false;
}
else
{
if (!CheckEmailValidation('Email', 'Enter valid email address')) {
m_boolValidator = false;
}
}
if (!CheckRequiredFieldValidation('Phone', 'Enter phone#')) {
m_boolValidator = false;
}
if (!CheckRequiredFieldValidation('StartDate', 'Enter start date')) {
m_boolValidator = false;
}
return m_boolValidator;
}
and here is ajax function being called inside SendEmail()
function SendEmailWithCustomTitle(txtEmail, txtContents, l_strTitle) {
event.preventDefault();
$.ajax({
async:false,
type: "POST",
url: "PTServiceRoutines.aspx/AjaxSendEmail",
data: "{'p_strEmail':'" + txtEmail + "','p_strTitle':'" + l_strTitle + "','p_strContents':'" + txtContents + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: successAjaxSendEmailWithCustomTitleHandler,
failure: failureAjaxSendEmailWithCustomTitleHandler,
error: errorAjaxSendEmailWithCustomTitleHandler
});
return false;
}
function successAjaxSendEmailWithCustomTitleHandler(data) {
ShowAlert(data.d);
//ShowAlert is method used to open modal showing data.a
};
function failureAjaxSendEmailWithCustomTitleHandler(data) {
};
function errorAjaxSendEmailWithCustomTitleHandler(data, status) {
};
I have already tried event.preventdefault,event.soppropogation but I could not find any easy way to return true from ajax success function SendEmail call.
Remove async:false, from you ajax to stop the browser from waiting for the ajax to complete
Use the following event to redirect when the modal is closed
$('#myModal').on('hidden.bs.modal', function () {
window.location.href = "desired-page.php"
})
You can create a button in modal and in that button click event, at first hide the modal and the call the ajax call. And window.location.href will not work inside a html form. To make window.location.href work you can move your submit button out of the form.
To open modal in success follow one of following two methods.
.done(function() {
$("#yourmodal").modal();
});
Or
success: function(data) {
$("#yourmodal").modal();
}
To stop ajax call until modal hide use following. Place your ajax call inside a function for an example "submitForm()". call this in following.
$('#yourmodal').on('hidden.bs.modal', function (e) {
// do something...
})
I have a JavaScript file which has a function that I reference. When I call the function from one part of the code, it works, and from another, it doesn't. Placing the function code above or below the call seems not to make any difference.
The error happens when I call the voteUp function.
Below is the entire JS file. Any idea why the two different calls to that function would have such different results? The call from the code above gives error: undefined function.
$(function()
{
$("#login_div input[type=submit]").click(function()
{
var email = $("#email").val();
var password = $("#user_pass").val();
//alert("Email: " + email);
//alert("password: " + password);
var dataString = 'email='+ email + '&password=' + password;
if( !email )
{
alert ("1");
$('.login_success_email_empty').fadeOut(200).hide();
$('.login_error_email_empty').fadeOut(200).show();
}
else
if( !password || password.length < 5)
{alert ("2");
$('.password_success').fadeOut(200).hide();
$('.password_error').fadeOut(200).show();
}
else
{
$.ajax({
type: "POST",
url: "../auth/login_ajax.php",
dataType: "json",
data: dataString,
success: function(json)
{
$('.password_error').fadeOut(200).hide();
$('.no_such_user').fadeOut(200).hide();
$('.login_success_email_empty').fadeOut(200).hide();
$('.login_success').fadeIn(200).show();
// Closing the dialog bosx
$('#loginpopup').dialog('close');
// Swapping out the header div
$('#header_logged_out').hide();
$('#header_logged_in').show();
queue.login = true;
if (queue.voteUp)
{
alert("in vote up queue: " + queue.voteUp + " and login: " + queue.login );
voteUp(queue.voteUp);
}
// Now also need to retrieve the problem_id
//problem_id = $("#problem_id").val();
//$problemId = $('#theProblemId', '#loginpopup').val();
// var $problemId = $('#theProblemId', '#loginpopup');
// alert ("After login, problem_id: " + problem_id + " and problemId was: " + $problemId);
},
error : function(json)
{
queue.login = false;
alert ("error");
// Output the result.
errorMessage = json.responseText;
alert ("ErrorMessage: " + errorMessage );
if ( errorMessage == 'no_such_user' )
{
$('.no_such_user').fadeOut(200).hide();
$('.no_such_user').fadeOut(200).show();
}
}
});
}
return false;
});
});
$(document).ready(function()
{
queue = new Object;
// queue.login = false;
var $dialog = $('#loginpopup')
.dialog({
autoOpen: false,
title: 'Login Dialog'
});
var $problemId = $('#theProblemId', '#loginpopup');
$("#newprofile").click(function ()
{
$("#login_div").hide();
$("#newprofileform").show();
});
// Called right away after someone clicks on the vote up link
$('.vote_up').click(function()
{
var problem_id = $(this).attr("data-problem_id");
queue.voteUp = $(this).attr('problem_id');
voteUp(problem_id);
//Return false to prevent page navigation
return false;
});
var voteUp = function(problem_id)
{
alert ("In vote up function, problem_id: " + problem_id );
queue.voteUp = problem_id;
var dataString = 'problem_id=' + problem_id + '&vote=+';
alert ("login status: " + queue.login );
if ( queue.login == false )
{
// Call the ajax to try to log in...or the dialog box to log in. requireLogin()
$dialog.dialog('open');
alert ("after dialog was open - in false case of being logged in.");
// prevent the default action, e.g., following a link
return false;
}
else
{
// The person is actually logged in so lets have him vote
$.ajax({
type: "POST",
url: "/problems/vote.php",
dataType: "json",
data: dataString,
success: function(data)
{
alert ("vote success, data: " + data);
// Try to update the vote count on the page
//$('p').each(function()
//{
//on each paragraph in the page:
// $(this).find('span').each()
// {
//find each span within the paragraph being iterated over
// }
//}
},
error : function(data)
{
alert ("vote error");
errorMessage = data.responseText;
if ( errorMessage == "not_logged_in" )
{
queue.login = false;
//set the current problem id to the one within the dialog
$problemId.val(problem_id);
// Try to create the popup that asks user to log in.
$dialog.dialog('open');
// prevent the default action, e.g., following a link
return false;
}
else
{
alert ("not");
}
} // End of error case
}); // Closing AJAX call.
} // Closing the else call
};
//$('.vote_down').click(function()
//{
// alert("down");
// problem_id = $(this).attr("data-problem_id");
//
// var dataString = 'problem_id='+ problem_id + '&vote=-';
//Return false to prevent page navigation
// return false;
// });
// $('#loginButton', '#loginpopup').click(function()
// {
/// alert("in login button fnction");
// $.ajax({
// url:'url to do the login',
// success:function()
// {
//now call cote up
// voteUp($problemId.val());
// }
// }); // Closing AJAX call.
//});
}); // End of document.ready() check
The function is declared as a local variable inside your second "ready" handler. Nothing outside that context will be able to call it.
You could make it a global function, maybe, but it depends on whether "queue" is really supposed to be global or not. If it is, it really should be explicitly declared as global (that is, with a var declaration outside the initialization code) because what you've got now is not valid with "strict" mode anyway.