Reputation: 919
I am having a page with a form on it that should use AJAX to save and load data to a file.
This is the java script I am using:
$(document).ready(function(){
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
$(".configFile").click(function() {
if (this.text == '' && this.text == 'undefined')
{
return;
}
$.get( "showForm.php", { loadConfig: this.text} )
.done(function( data ) {
$('#configFormContainer').html(data);
});
});
The class .configFile in the second function refers to a list of a-Tags. When I click on of of those, the script successfully loads the content from a file and displays it. This is the html for the mentioned a-Tags:
<div class="list-group">
<a href="#" class="configFile>config.json</a>
<a href="#" class="configFile>config_1504987517.json</a>
</div>
This part is working fine: The javascript-function is triggered. In showForm.php the config file is loaded. It is re-building the complete form with the content from the file.
Whats not really working is the trigger on the submit-function. This is the form-html
<form id="saveConfigForm" method="POST">
<a bunch of form elements />
<button name="submit" class="btn btn-success" type="submit" id="saveConfig">Speichern</button>
</form>
So, whats happening now:
When I load the page initially, I click the submit-Button and get the alert. This trigger .submit() is working.
When I click one of the a-tags to load a config-file, the file is being loaded without refreshing the page. This trigger .click() is working, too.
After that: When I click the submit-button, the page is being reloaded. The trigger .submit() is not working.
And after this "unwanted" reload of the page, the .submit()-trigger is working, again.
I have no clue what it is wrong here. Hope someone can help
cheers
Upvotes: 0
Views: 1604
Reputation: 919
I kind of found out whats causing the problem: The ajax-call returns the html-form and put it to the form-container.
After this, the trigger to that form is gone, because the trigger was connected to the form, that I am overwriting with the ajax-data.
It will work, when I reset the trigger like that. But this looks more like quick'n'dirty
$(document).ready(function(){
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
$(".configFile").click(function() {
if (this.text == '' && this.text == 'undefined')
{
return;
}
$.get( "showForm.php", { loadConfig: this.text} )
.done(function(data) {
$('#configFormContainer').html(data);
// re-init the trigger on "submit" here
// ------------------------------------
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
});
});
});
I needed to adjust the the showForm.php. If it's being called from the ajax-method, it will only return the form elements, not the form itself. If it is being called from the scratch, it returns the complete form.
Furthermore, the java script now replaces the content of the form-element, not it's container. This way the trigger does not get lost.
$(document).ready(function(){
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
$(".configFile").click(function() {
if (this.text == '' && this.text == 'undefined')
{
return;
}
$.get( "showForm.php", { loadConfig: this.text} )
.done(function(data) {
$('#saveConfigForm').html(data);
});
});
});
Just for the sake of completeness, this is the main part of the showForm.php now:
<?php
if (!isset($_GET['loadConfig']))
{
// do not return the complete form to prevent losing the trigger on it
echo '<form id="saveConfigForm" method="POST">';
}
echo '<a bunch of form elements />';
if (!isset($_GET['loadConfig']))
{
echo '</form>';
}
Upvotes: 1
Reputation: 313
Though this isn't your whole code set, I took what you posted and made a page. I could click either of the .configFile
links, then click the submit button and I get the alert.
However I did close both class
attributes of the .configFile
elements with a "
. I don't know if that's the difference. But, if it isn't then it's something that's occurring after the ajax request which of course I can't simulate with this code.
<html>
<body>
<div class="list-group">
<a href="#" class="configFile">config.json</a> <!-- //added " to end of class attribute -->
<a href="#" class="configFile">config_1504987517.json</a> <!--//added " to end of class attribute -->
</div>
<form id="saveConfigForm" method="POST">
<a bunch of form elements />
<button name="submit" class="btn btn-success" type="submit" id="saveConfig">Speichern</button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" type="text/javascript"></script>
<script>
$(document).ready(function(){
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
$(".configFile").click(function() {
if (this.text == '' && this.text == 'undefined')
{
return;
}
if (window.XMLHttpRequest)
{
// AJAX for IE7+, Chrome, Firefox, Safari, Opera
xmlhttp = new XMLHttpRequest();
} else {
// AJAX for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
$('#configFormContainer').html(xmlhttp.responseText);
}
}
xmlhttp.open("GET","showForm.php?loadConfig=" + this.text, true);
xmlhttp.send();
});
});
</script>
</body>
</html>
The other thing that would be curious to me: Open the browser's developer console and paste in your submit binder again:
$("#saveConfigForm").submit(function (e)
{
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
If your submit works after that, I'd suggest either binding the click event again after the new html is rendered. Or, binding the event to $(document) like:
$(document).on('submit', '#saveConfigForm', (e) => {
e.preventDefault();
var formData = $(this).serialize();
alert(formData);
});
As a final note, I'm not trying to augment your code any more than necessary to help with the specific issue you're having. As another user commented, it would be cleaner to use the jQuery functions since you're using jQuery. But I don't take that as part of your question.
Upvotes: 1