Background: I am working on a small web application. AJAX will successfully POST the data to the action(create.php) and create.php will execute the necessary mysql query. Once AJAX is done, I append a message to the div id="container"></div> informing the user of a successful execution then clear the content "container" for future use; however, here in lies the problem.
Problem: After AJAX executes, I can not click on any HTML links already loaded onto the page(page.php). I have to refresh the page in order to click on any links and follow them to their destination. What is causing this to happen and how can I fix it?
AJAX does not need to return a result. It only needs to execute the specified jQuery code once the request is done. On a hunch, I altered create.php to echo the $_POST array and have AJAX return that as a result. Once AJAX loads the result into the "container" I still can not click on any links loaded on page.php
Answer: The DOM was not being reloaded after AJAX calls causing bootstrap dropdown menus to not function properly. The bootstrap dropdown class had to be manually reinitialized after each call. This has already been answered in detail here
create.php
<?php
if($_POST){
//run mysql query
}else{
//do nothing
}
?>
form.php
<form id="new-items">
<input type="text" name="item" />
<input type="button" onclick="create_item()" name="Submit" value="Submit" />
</form>
page.php
<html>
<head>
<script>
$(document).ready(function(){
$("#add_items").click(function(){
event.preventDefault();
$("#content").load("form.php");
});
});
function create_item(){
var form_data = $("#new-items").serialize();
var request = $.ajax({
url: "create.php",
type: "POST",
data: form_data,
});
request.done(function(){
$("#content").append('<div>User was added successfully</div>');
setTimeout(function(){
$("#content").fadeOut("slow");
}, 5000);
setTimeout(function(){
$("#content").empty();
}, 8000);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
</script>
</head>
<body>
<nav>
Link1
Link2
Add New Items
</nav>
<div id="content"></div>
</body>
</html>
After you fadeOut the #content element, it remains hidden. The next time you call your AJAX function, it's loading create.php into an invisible element.
Try:
setTimeout(function(){
$("#content").fadeOut("slow", function() {
$(this).empty().show();
});
}, 5000);
Other issues: <div class="content"> should be <div id="content">; you didn't include jquery.js at the top of your script; you didn't pass the event object e to your click handler.
page.php should now look like:
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>
$(document).ready(function(){
$("#add_items").click(function(e){
e.preventDefault();
$("#content").load("form.php");
});
});
function create_item(){
var form_data = $("#new-items").serialize();
var request = $.ajax({
url: "create.php",
type: "POST",
data: form_data,
});
request.done(function(){
$("#content").append('<div>User was added successfully</div>');
setTimeout(function(){
$("#content").fadeOut("slow", function() {
$(this).empty().show();
});
}, 5000);
});
request.fail(function(jqXHR, textStatus) {
alert( "Request failed: " + textStatus );
});
}
</script>
</head>
<body>
<nav>Add New Items</nav>
<div id="content"></div>
</body>
</html>
The anchor links in the <nav> will natually 'refresh' the page with the new content.
If you want to load the content via an ajax request then you should try the following:
Add a common class to the links
<nav>
Link1
Link2
Add New Items
</nav>
Then attach a click event to each link which intercepts the default page refresh with e.preventDefault(). The you can perform the ajax request using the href attribute of that link.
$(function(){
$(".anchor").on('click', function(e){
e.preventDefault();
var $this=$(this);
$("#content").load($this.attr('href'));
});
});
The DOM was not being reloaded after AJAX call. Boostrap dropdown module has to be manually reinitialized after each call. Detailed answered here: answer
Related
So I have this simple AJAX load method to load an URL:
<div id="load">
<h1 id="status">Loading...</h1>
</div>
<script type="text/javascript">
$(document).ready(function(){
$.ajaxSetup({cache: false});
var url = "http://www.example.com/get.php?id=12345";
$('#load').replaceWith($('<div>').load(url));
});
});
</script>
At the moment I dont ever see the Loading... whilst the AJAX is loading, however shouldnt my method only replace it after it's loaded the new content. On a side note, if the AJAX load failed, how would I go about replacing that status class with Failed
if you load the page into a $('<div>') - then use the .load callback to complete the replacement of status - like so
<div id="load">
<h1 id="status">Loading...</h1>
</div>
<script type="text/javascript">
$(document).ready(function(){
$.ajaxSetup({cache: false});
var url = "http://www.example.com/get.php?id=12345";
$('<div>').load(url, function() {
$('status').replaceWith(this);
});
});
</script>
So i made an ajax request for get my "home" page and my "about" page in a "container" on click menu link button inside my index.php, and now i have three link in my "home" page, and i also want open each of these links inside my div "container" to replace the "home" page, so how can i make an ajax request after the first ajax call ?
This is my php request in the index.php:
<div id="container">
<?php
$d="contenu/";
if(isset($_GET['p'])){
$p=strtolower($_GET['p']);
if(preg_match("/^[a-z0-9\-]+$/",$p) && file_exists($d.$p.".html")){
include $d.$p.".html";
}
else{
include "pages/404.html";
}
}
else{
include "pages/home.html";
}
?>
</div>
In here my ajax:
$(document).ready(function(){
$("#menu a").click(function(){
page=$(this).attr("href");
$.ajax({
url: "pages/"+page,
cache:false,
success:function(html){
afficher(html);
},
error:function(XMLHttpRequest,textStatus, errorThrown){
afficher("erreur lors du chagement de la page");
}
});
return false;
});
});
function afficher(data){
$("#container").fadeOut(500,function(){
$("#container").empty();
$("#container").append(data);
$("#container").fadeIn(1200);
});
}
and finally my home.html ( i just show you the links ):
<div class="section vs-section" data-speed="0.4">
<div class="vs-transform title " data-speed="0.4"><h3>projet1</h3></div>
<div class="vs-transform title" data-speed="0.38"><h3>Projet2</h3></div>
<div class="vs-transform title" data-speed="0.4"><h3>projet3</h3></div>
</div>
Yes you can, you should just use event delegation on() to deal with the new HTML tags added dynamically to the DOM by the first ajax request :
$('body').on('click', '.vs-transform a', function(){
//Second ajax request
})
Hope this helps.
What i'm trying to do is simply post the forum asynchronously to a php page and return what it echos to a particular id.
When I first submit, everything works as expected. The text gets sent to the append.php and returns the new list of items promptly without refreshing the page.
The second time I submit text, it seems like it's ignoring the ajax stuff. Instead, it takes me to append.php and displays just the list. Though it still submits the form and adds to the array. This makes me suspect that my problem lies within the script.
So my question is, what do I need to do for my form to continuously work using AJAX more than once?
index.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>For Testing Ajax</title>
<script type="text/javascript" src="jquery.js"></script>
<script>
$(document).ready(function(){
// Bind to the submit event
$(".ajax").submit(function(event){
// Get local variables
var form = $(this);
// Get inputs of this form
var inputs = form.find("input, select, button, textarea");
// Get the data to post
var serializedData = form.serialize();
// prevent additional requests during the duration of this one
inputs.prop("disabled", true);
// Make the request to the form's ACTION property
var request = $.ajax({
url: form.prop("action"),
type: "post",
data: serializedData
}).done(function (response, textStatus, jqXHR){
// Success
console.log("Hooray, it worked!");
// Return response to the ID according to the form's NAME property
$("#"+form.prop("name")).html(response);
}).fail(function (jqXHR, textStatus, errorThrown){
// Failure
console.error(
"The following error occured: "+
textStatus, errorThrown
);
}).always(function () {
inputs.prop("disabled", false);
form.unbind('submit');
});
event.preventDefault();
return false;
});
});
</script>
</head>
<body>
<h1>You're on the main page.</h1>
<div id="list">
<form class="ajax" method="POST" name="list" action="append.php">
<input type="text" name="text">
<input type="submit" value="Append">
</form>
<?
$list = json_decode(file_get_contents('list.json'),true);
echo '<ul>';
foreach($list as $item){
echo '<li>'.$item.'</li>';
}
echo '</ul>';
?>
</div>
</body>
</html>
append.php
<?
// Get the POST stuff
$text = $_POST['text'];
Check if anything was indeed submitted
if (isset($_POST['text'])) {
// Get current array
$list = json_decode(file_get_contents('list.json'),true);
// Add to the array
$list[] = $text;
// Save changes to the file
file_put_contents('list.json',json_encode($list));
// Return the forum and the array in an unorganized list
echo '
<form class="ajax" method="POST" name="list" action="append.php">
<input type="text" name="text">
<input type="submit" value="Append">
</form>
<ul>';
foreach($list as $item){
echo '<li>'.$item.'</li>';
}
echo '</ul>';
}
?>
Thank you for your time!
PS: I am using jQuery v2.0.2
The problem is form.unbind('submit'); it is unbinding your event handler so it doesn't execute the next time.
Lets see, you have a form inside a DIV
<div id="list">
<form class="ajax" method="POST" name="list" action="append.php">
and in the success callback you do
$("#"+form.prop("name")).html(response);
As the name of the form is list, you're effectively replacing everything inside the DIV with the id #list with whatever the ajax call returns, and the element you inititally bound the event handler to is gone!
To solve it, use a delegated event handler that works with the new form you put in there as well
$(document).on("submit", ".ajax", function(event){
// your code here
});
You're also unbinding the event in the always handler, but that doesn't really matter as the form is no longer there after the ajax call is successful.
I use django create a website .and i just write a vote page ,when people click ,it will post data via jquery ajax .it work well
here is the code
<!doctype html>
<html>
<head>
<script src="jquery-1.10.2.min.js"></script>
<meta charset="utf-8">
<title>vote</title>
</head>
<body>
<script language="javascript" type="text/javascript">
$(function(){
$(".post_up").click(function(){
$.ajax({
url:"/article/{{post.id}}/vote_up/",
type:'post',
success:function(msg){
var beforevote = $(".btn").text();
if (msg==0){
$(".pop_up_vote").empty().text("thanks,i get your vote!").show(300).delay(7000).hide(300);
};
if (msg==1){
$(".pop_up_vote").empty().text("you already voted,do not need vote again").show(300).delay(7000).hide(300);
};
})
})
</script>
<span><i class="icon_add"></i>vote</span>
<div class ="pop_up_vote" >
</div>
</body>
</html>
Everything works well, and I just found the problem. I can not stop repeatedly click vote.
If I click repeatedly
<span><i class="icon_add"></i>vote</span>
it repeate show up the pop_up message,"i already voted ,do not vote again."
so i thought ,i may solve the problem by remove the class post_up ,in this way ,people can not activate ajax post function
so i add $(this).removeClass();
$(function(){
$(".post_up").click(function(){
$(this).removeClass();
$.ajax({
url:"/article/{{post.id}}/vote_up/",
type:'post',
success:function(msg){
var beforevote = $(".btn").text();
if (msg==0){
$(".pop_up_vote").empty().text("thanks,i get your vote!").show(300).delay(7000).hide(300);
};
if (msg==1){
$(".pop_up_vote").empty().text("you already voted,do not need vote again").show(300).delay(7000).hide(300);
};
})
})
When I remove the class, I still have the problem regarding ajax. How could I fix it?
Try this : http://api.jquery.com/one/.
$('.post_up').one('click', function () {
You can re-bind the same handler once Ajax is done :
$('.post_up').one('click', function handler() {
var el = this;
$.ajax({
url: '/article/{{post.id}}/vote_up/',
type: 'post',
success: function (msg) {
$(el).one('click', handler);
Here is a demo : http://jsfiddle.net/wared/CVm37/.
I think the problem is that the behaviour is already set for the link, so removing the class won't do anything
try this instead
$(".post_up").unbind("click");
I am trying to send post data to my post data file handler called postinfo.php with jQuery but so far I can make it.
Here is my post.php code:
<HTML>
<head>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<script type="text/javscript">
$('#form_id').on('submit', function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "http://www.vemvo.com/test/postinfo.php",
data: $(this).serialize(),
success: function() {
alert('success');
}
});
});
</script>
<form method="post" id="form_id">
<input type="text" name="ime">
<input type="submit" id="submit" name="submit" value="Send">
</form>
You can see the page here: http://www.vemvo.com/test/post.php
Here is the code from my postinfo.php:
<?PHP
$ime = $_POST['ime'];
echo "Your name is $ime";
?>
Here is located postinfo.php - http://www.vemvo.com/test/postinfo.php
So where is my mistake and how I can make it work?
Now it's not sending the data and not giving me the success alert.
Your jQuery selector isn't going to find that form, since the selector is running before the form tag exists in the DOM. Try wrapping it in the jQuery function to wait for the document to be ready:
$(function () {
$('#form_id').on('submit', function(e){
// the rest of your code
});
});
It also might be a good idea to return false at the end, to further suppress the form's default post action:
e.preventDefault();
$.ajax({
type: "POST",
url: "./postinfo.php",
data: $(this).serialize(),
success: function() {
alert('success');
}
});
return false;
Currently the form is posting as normal. Since the AJAX handler is never attached (because the element doesn't exist when the selector executes), it's just doing a normal document-level form post. And since there's no action attribute specified in the form tag, the page is posting to itself by default. Which just responds with the current page.
Edit: You also have a typo which may be preventing the browser from executing your JavaScript code at all:
<script type="text/javscript">
You're missing the second "a". This should be:
<script type="text/javascript">
You MUST spell text/javascript correctly
You need to assign the event handler on load
There should not be any need to return false as posted by some other people here
NEVER call anything submit in a form
Wrap your html in body tags
Use a correct DOCTYPE
For files you can have a look at uploadify or How can I upload files asynchronously?
Fixed code for point 1 to 6
<!DOCTYPE html>
<html>
<head>
<title>Test Ajax</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
$('#form_id').on('submit', function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "./postinfo.php",
data: $(this).serialize(),
success: function() {
alert('success');
}
});
});
});
</script>
</head>
<body>
<form method="post" id="form_id">
<input type="text" name="ime">
<input type="submit" value="Send">
</form>
</body>
</html>