AJAX Form Post PreventDefault Not Working - javascript

I have a simple HTML document with a form I would like to post to the server without leaving the page. I've Googled around the internet all day trying to figure out how to get this to work and I've come up with the following code:
<body>
<script>
$(document).ready(function() {
$('#newResource').submit(function (e) {
e.preventDefault();
$.ajax({
type: 'post',
url: 'scripts/script.php?new-resource=1',
data: $('#newResource').serialize(),
success: function () {
alert('form was submitted');
}
});
return false;
});
});
</script>
<form id="newResource" class="form-basic" enctype="multipart/form-data" method="post" action="scripts/script.php?new-resource=1">
<label><b>Resource Name:</b></label>
<input class="input-text" type="text" placeholder="Enter the resource name..." name="name" id="name" autocomplete="off" required="">
<br>
<label><b>Resource URL:</b></label>
<input class="input-text" type="text" placeholder="Enter the resource URL..." name="url" id="url" autocomplete="off" required="">
<br>
<label><b>Resource Department:</b></label>
<p>Select the department this resource should belong to.</p>
<select class="input-select" name="department" id="department">
<option value="5">Human Resources</option>
<option value="1">Information Technology</option>
<option value="3">Marketing</option>
<option value="0">No Department</option>
<option value="6">Purchasing</option>
<option value="4">Sales</option>
</select>
<br>
<label><b>Resource Icon:</b></label>
<p>Select the icon image to be displayed with this resource.</p>
<select class="input-select" name="icon" id="icon">
<option value="bell.png">Alarm Bell</option>
<option value="chat-bubbles.png">Chat Bubbles</option>
<option value="chronometer.png">Chronometer</option>
<option value="database.png">Database Icon</option>
<option value="envelope.png">Envelope</option>
<option value="folder.png">File Folder</option>
<option value="analytics.png">Monitor with Line Graph</option>
<option value="pie-chart.png">Monitor with Pie Chart</option>
<option value="networking.png">Networking Heirarchy</option>
<option value="orientation.png">Orientation Arrow</option>
<option value="server.png">Server Rack</option>
<option value="settings.png">Settings Gears</option>
<option value="speedometer.png">Speedomoeter</option>
<option value="worldwide.png">World Wide Web Globe</option>
</select>
<br>
<div style="float: right;">
<button type="button" onclick="loadPrefs('resources');" class="form-button cancel">Cancel</button>
<button class="form-button submit" type="submit">Submit</button>
</div>
</form>
</body>
The code is all within the body tag.
The problem is that when I click the submit button I am redirected to the PHP action script. Does the script I have need to be in the head tag instead?
If I remove the action from the form then the script redirects to the same page but no data is submitted.
Here is the PHP script if necessary:
if(isset($_GET['new-resource'])){
// escape the SQL input for security
$name = mysqli_real_escape_string($conn, $_POST['name']);
$url = mysqli_real_escape_string($conn, $_POST['url']);
$department = mysqli_real_escape_string($conn, $_POST['department']);
$icon = mysqli_real_escape_string($conn, $_POST['icon']);
// Run the SQL query to add the new resource item
$sql = "INSERT INTO Resources (ID, ResourceName, ResourceURL, IconImg, Department) VALUES (NULL, '$name', '$url', '$icon', '$department');";
$conn->query($sql);
// Close the SQL connection
$conn->close();
}
I can't seem to figure out why this is not working. Any thoughts and feedback are appreciated.

The important info in your case was "The HTML form elements are added with AJAX". At $(document).ready(), the #newResource form element did not yet exist, so the event was never bound. In your working example you used event delegation: $(document).on('click', '.submit', function(e) {...}, this is the correct way setup event listeners for non-existing elements.

Your event handler is bound to the submit event of the form. By the time the form has been submitted, it's too late to stop the default synchronous HTML form submission.
Bind your handler to the to click event on the submit button, use event.preventDefault() and submit the form via Ajax:
$(document).ready(function() {
$('.submit').click(function (e) {
e.preventDefault();
var form = $('#newResource');
var action = form.attr('action');
var data = form.serialize();
$.ajax({
type: 'POST',
url: action,
data: data,
success: function () {
alert('form was submitted');
}
});
});
});
Please note, the way this is written, it will fire for any click of an element with a class of submit. Since you may have more than one form on your web page and more than one button with a class of submit, it's not good to have the form variable use a hard-coded ID selector.
If the HTML of all your website forms are always coded this same way, with the submit button inside of a div which is nested in the form, you could replace:
var form = $('#newResource');
with:
var form = $(this).parent().closest('form');
Now you can wrap that code in a function called "bindForms()" or whatever, and you have a generic recipe for handling all forms, provided that the HTML structure is always the same (or at least, to the extent that the submit button always has a class of submit and is always wrapped in a parent container which is a child of the form.

Ok, I've managed to get this following code to work:
<script type="text/javascript">
$(document).on('click', '.submit', function(e) {
debugger;
e.preventDefault();
var form = $(this).parent().closest('form');
var action = form.attr('action');
var data = form.serialize();
$.ajax({
type: 'POST',
url: action,
data: data,
success: function () {
loadPrefs('resources');
}
});
});
</script>
The HTML form elements are added with AJAX but so was the script element. I moved the script element to the top of the page so that it is static and no longer loaded with the form.

Related

Submit a form via this object

I have a form that I want to submit, and I don't know the best way to call the form.
This is my HTML
<form id="form2" name="form2">
<select id="situation_matrimoniale" name="situation_matrimoniale">
<option value="Célibataire">Célibataire</option>
<option value="Marié(e)">Marié(e)</option>
<option value="Veuf(ve)">Veuf(ve)</option>
<option value="Divorcé(e)">Divorcé(e)</option>
</select><input type="text" name="nombre_enfant" id="nombre_enfant" value="" /><input type="button" value="Enregistrer" name="submit" onclick="submitFormInfoEtatCivil()" />
</form>
Now the Javascript, I included jQuery.
function submitFormInfoEtatCivil() {
var update = "index.php/rh/updateinfo";
var dataString = $( this ).serialize();
// dataString return <empty string>
jQuery.ajax({
});
}
I have many forms with ids : form1, form2, form3 ...
My problem is how to specify the fonction submitFormInfoEtatCivil() to get the form where button is submitted. I used $( this ).serialize() but I am wrong because the output is empty.
You can pass this inside function and then use .closest("form") to get input datas from form where button has been clicked.
Demo Code :
function submitFormInfoEtatCivil(el) {
var update = "index.php/rh/updateinfo";
//use closest to get form where button is clicked
var dataString = $(el).closest("form").serialize();
console.log(dataString)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="form2" name="form2">
<select id="situation_matrimoniale" name="situation_matrimoniale">
<option value="Célibataire">Célibataire</option>
<option value="Marié(e)">Marié(e)</option>
<option value="Veuf(ve)">Veuf(ve)</option>
<option value="Divorcé(e)">Divorcé(e)</option>
</select><input type="text" name="nombre_enfant" id="nombre_enfant" value="" />
<!--pass `this` inside function-->
<input type="button" value="Enregistrer" name="submit" onclick="submitFormInfoEtatCivil(this)" />
</form>
<form id="form" name="form">
<select id="situation_matrimoniale" name="situation_matrimoniale">
<option value="Célibataire">Célibataire</option>
<option value="Marié(e)">Marié(e)</option>
<option value="Veuf(ve)">Veuf(ve)</option>
<option value="Divorcé(e)">Divorcé(e)</option>
</select><input type="text" name="nombre_enfant" id="nombre_enfant" value="" />
<!--pass `this` inside function-->
<input type="button" value="Enregistrer" name="submit" onclick="submitFormInfoEtatCivil(this)" />
</form>
$(this) that you use refers to button and you are getting empty string when you are serialize() a button.
I strongly recommend an another solution for this problem; you can catch the form when it is submitted with the on() function;
$('form').on('submit',function(){
var thiz = $(this);
var update = thiz.attr("form-url"); //get update url from the form as an attiribute or define it staticly.
var dataString = thiz.serialize();
return false; //to prevent original form action.
});
When you use above code snippet you can remove onclick="submitFormInfoEtatCivil(this)" from your code and also if you want to deep dive with on() function, you can find here an documentation.

Submit AJAX form with multiple events

I have a form, and when the submit button is clicked, it sends an AJAX request. This works on the button click by:
$(#form).submit(function(event) {
event.preventDefault();
$.ajax({
// ...
})
});
The form data is passed to the URL in the ajax command using data.
Is there a way this form can be submitted and the same AJAX function can run on a dropdown change javascript/jQuery event? The dropdown menu is in the same form.
I have it so that when the AJAX returns successfully, it adds the HTML to populate a div with a table so this needs to be written once.
Short answer: "Yes". You can call the "submit" method of the form from anywhere you like. For example:
$("#someDropdown").change(function() { $("#form").submit(); });
Demo:
$(function() {
$("#someDropdown").change(function() {
$("#form").submit();
});
$("#form").submit(function(event) {
event.preventDefault();
console.log($(this).serialize());
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="someDropdown">
<option>Option 1</option>
<option>Option 2</option>
</select>
<hr>
<form id="form">
<input type="text" name="text1" />
<button type="submit">Submit</button>
</form>
Documentation: https://api.jquery.com/submit/

How to prevent page from reloading after form submit - JQuery

I am working on a website for my app development class and I have the weirdest issue.
I am using a bit of JQuery to send form data to a php page called 'process.php, and then upload it to my DB. The weird bug is that the page reloads upon submitting the form, and I cannot or the life of me figure out how to make the JQuery go on in just the background. That is sorta of the point of using JQuery in the first place haha. Anyways, I will submit all relevant code, let me know if you need anything else.
<script type="text/JavaScript">
$(document).ready(function () {
$('#button').click(function () {
var name = $("#name").val();
var email = $("#email").val();
$.post("process.php", {
name: name,
email: email
}).complete(function() {
console.log("Success");
});
});
});
</script>
<div class= "main col-xs-9 well">
<h2 style="color: black" class="featurette-heading">Join our mailing list!</h2>
<form id="main" method = "post" class="form-inline">
<label for="inlineFormInput">Name</label>
<input type="text" id="name" class="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
<label for="inlineFormInputGroup">Email</label>
<div class="input-group mb-2 mr-sm-2 mb-sm-0">
<input type="text" id="email" class="form-control" id="inlineFormInputGroup" placeholder="janedoe#email.com">
</div>
<!--Plan to write success message here -->
<label id="success_message"style="color: darkred"></label>
<button id ="button" type="submit" value="send" class="btn btn-primary">Submit</button>
</form>
This is my php if its relevant:
<?php
include 'connection.php';
$Name = $_POST['name'];
$Email = $_POST['email'];
//Send Scores from Player 1 to Database
$save1 = "INSERT INTO `contact_list` (`name`, `email`) VALUES ('$Name', '$Email')";
$success = $mysqli->query($save1);
if (!$success) {
die("Couldn't enter data: ".$mysqli->error);
echo "unsuccessfully";
}
echo "successfully";
?>
This is a screenshot of the log:
The <button> element, when placed in a form, will submit the form automatically unless otherwise specified. You can use the following 2 strategies:
Use <button type="button"> to override default submission behavior
Use event.preventDefault() in the onSubmit event to prevent form submission
Solution 1:
Advantage: simple change to markup
Disadvantage: subverts default form behavior, especially when JS is disabled. What if the user wants to hit "enter" to submit?
Insert extra type attribute to your button markup:
<button id="button" type="button" value="send" class="btn btn-primary">Submit</button>
Solution 2:
Advantage: form will work even when JS is disabled, and respects standard form UI/UX such that at least one button is used for submission
Prevent default form submission when button is clicked. Note that this is not the ideal solution because you should be in fact listening to the submit event, not the button click event:
$(document).ready(function () {
// Listen to click event on the submit button
$('#button').click(function (e) {
e.preventDefault();
var name = $("#name").val();
var email = $("#email").val();
$.post("process.php", {
name: name,
email: email
}).complete(function() {
console.log("Success");
});
});
});
Better variant:
In this improvement, we listen to the submit event emitted from the <form> element:
$(document).ready(function () {
// Listen to submit event on the <form> itself!
$('#main').submit(function (e) {
e.preventDefault();
var name = $("#name").val();
var email = $("#email").val();
$.post("process.php", {
name: name,
email: email
}).complete(function() {
console.log("Success");
});
});
});
Even better variant: use .serialize() to serialize your form, but remember to add name attributes to your input:
The name attribute is required for .serialize() to work, as per jQuery's documentation:
For a form element's value to be included in the serialized string, the element must have a name attribute.
<input type="text" id="name" name="name" class="form-control mb-2 mr-sm-2 mb-sm-0" id="inlineFormInput" placeholder="Jane Doe">
<input type="text" id="email" name="email" class="form-control" id="inlineFormInputGroup" placeholder="janedoe#email.com">
And then in your JS:
$(document).ready(function () {
// Listen to submit event on the <form> itself!
$('#main').submit(function (e) {
// Prevent form submission which refreshes page
e.preventDefault();
// Serialize data
var formData = $(this).serialize();
// Make AJAX request
$.post("process.php", formData).complete(function() {
console.log("Success");
});
});
});
clear the previous state when loading the page.... add this to document.ready function.
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}

Monitoring form fails with Ajax

I have a large form that I want to monitor for changes. I found example code for that in this post. When I run the code as posted, it works fine. But my form is using Ajax and it doesn't work for some reason. Here's my jsfiddle. I added a second monitor near the bottom but it isn't working either.
When the monitoring code is in the doc ready function, even the first "hello" update doesn't work. But this may be something to do with jsfiddle since I can get past that point locally. But even then, the origForm data is not seen more than once because, I think, the doc ready function is only called the one time when Ajax loads it.
Is there a way to monitor all of the fields when using Ajax?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="saved_form"></div>
<div id="changed"></div>
<div id="showform"></div>
<script>
$(document).ready(function() {
ShowForm();
$("#saved_form").text("hello");
var $form = $("form"),
origForm = $form.serialize();
$("#saved_form").text(origForm);
$("form :input").on("change input", function() {
$("#changed").text("A change was made");
});
});
function ShowForm () {
$.ajax({
url: 'ajax3.php',
success: function(data) {
$("#showform").html(`
<form>
<div>
<textarea name="description" cols="30" rows="3"></textarea>
</div>
<div>Username: <input type="text" name="username" /></div>
<div>
Type:
<select name="type">
<option value="1">Option 1</option>
<option value="2" selected>Option 2</option>
<option value="3">Option 3</option>
</select>
</div>
<div>
Status: <input type="checkbox" name="status" value="1" /> 1
<input type="checkbox" name="status" value="2" /> 2
</div>
</form>
`);
}
});
};
var $form2 = $("form"),
origForm2 = $form2.serialize();
$("#saved_form").text(origForm2);
$("form :input").on("change input", function() {
$("#changed").text("A change was made");
});
</script>
You are dynamically adding the form to your page. The selector will not pick up the change event. Also the event and selector in the on method are defined properly. more information about the on method can be found here http://api.jquery.com/on/
Try this:
$(document).on("change", "input, textarea", function() {
$("#changed").text("A change was made");
});
You can use .promise() after using .html() to render your form. This callback is launched right after form has been populated. Then you can use $("#showform form :input") to monitor events just on this eactly form. It costs less in performance than doing with $(document).on(...)
In your code:
function ShowForm () {
$.ajax({
url: 'test',
success: function(data) {
$("#showform").html(`
// <--- All your previous html -->
`).promise().done(function(){
// <--- Execute your monitor after rendering new form -->
$("#showform form :input").on("change input", function() { $("#changed").text("A change was made");
});
});
}
});
};
Look at the updated jsfiddle
To know more about .promise() here-jquery-promises

Add HTML form on button click

I have an HTML form in my website/application.
The form has lots of fields of input text, select, and PHP code, as well, to fill drop down values.
Is there any way I can clone/create the same form when the user clicks on the Add button? Let's say, if the user clicks 5 times, it would have five forms on the UI.
HTML
<form id = "buyerForm" role="form" method="POST" enctype="multipart/form-data" style="margin-top:30px;">
<span class="customerno" style="font-size: 22px;">Buyer 1 (Form 2)</span>
<div class="form-group">
<label>APPLICANT DETAILS</label>
</div>
<div class="form-group">
<label>Mr. / Mrs</label>
<select class="form-control" name="jnameTitle" id="jnameTitle">
<option>Please Select One</option>
<option value="Mr">Mr</option>
<option value="Mrs">Mrs</option>
<option value="MS">MS</option>
</select>
</div>
// similar fields are omitted to reduce the complexity
<div class="form-group">
<label>Address</label>
<textarea name="jaddress" id="jaddress" class="form-control" cols="80" rows="5" ></textarea>
</div>
<button type="submit" name="jointCustomers" id="jointCustomers" class="btn btn-success btn-lg btn-flat">Save</button>
<button type="reset" class="btn btn-default btn-lg">Reset</button>
</form>
if you're using jQuery (or dont mind using it) you could just use clone to add the form again to the parent container
$("#youButton").click(function(){
$("#buyerForm").clone().appendTo("#yourParentWrapper");
});
see this fiddle
Yes, there is a way.
Lets say you have the main page -> mainPage.php, where you can have a list and the button (addForm).
Then you will have your myform.php page that will generate a form it self.
The process is very simple.
You press the btn AddForm
You make a request using AJAX against your function that generate the form in the myform.php page.
Inside your AJAX code, you will add your form inside the list object.
Note: This is only a basic idea. You must adapt the code to your needs.
//Your main page, will contain a list.mainPage.php
<ul id="myFORMS">
<li><button id="idBtnElement" type="button">AddForm</button></li>
</ul>
//Your php code to create the form. You can create a function if you want
$arrToJSON = array(
"myFormHtml"=>"You will put your HTML form code here"
);
return json_encode(array($arrToJSON));
//Your javaScript code
$(document).on("event", "#idBtnElement", function(){
//Data you want to send to php evaluate
var dt={
ObjEvn:"btn_ADDFORM"
};
//Ajax
var request =$.ajax({//http://api.jquery.com/jQuery.ajax/
url: "myFormGenerator.php",
type: "POST",
data: dt,
dataType: "json"
});
//Ajax Done catch JSON from PHP
request.done(function(dataset){
for (var index in dataset){
formStrHtml=dataset[index].myFormHtml;
}
//JavaScript
//Here you can grab formStrHtml in apped at the end of the list in your main page.
$("#myFORMS ul").append('<li>'+formStrHtml+'</li>');
});
//Ajax Fail
request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);
});
}

Categories

Resources