I have a website where on the main page there is a content div and content is being switched using ajax. Everytime I switch between different pages it seems to me like ajax keeps making double the amount of requests. Here is the code handling the page switching:
$(document).on('click','#sideNav a',function(e){
e.preventDefault();
var url = $(this).attr('href'); //get the link you want to load data from
$.ajax({
type: 'GET',
url: url,
success: function(data) {
$("#content").empty();
$("#content").html(data);
}
});
//window.history.pushState('object', 'New Title', url);
});
});
Now lets say I switch to my templates page where it displays created templates and lets me create templates.
Now the first time I switch to this page and create a new template everyhting is fine, one post is made to php and one new entry is made to the database. Now if I switch between pages and back to my templates page and create a new template, only this time ajax makes two posts to php and 2 database entries are made, now if I do that one more time 4 posts are mad and so on.
It happens with every function that uses ajax. It doesn't happen when I go to my templates page seperately not through my main page with the content div, so I suspect something is messed up with how I switch pages.
Edit: it actually isn't doubling but adding one request each time.
UPDATE
Somehow I fixed it, not exactly sure how but here's the things I did: I added .off('click','#sideNav a') to my function and I also put the function into separate .js file. I feel like it was loading the script again every time, again not exactly sure what exactly fixed it, hope it helps somebody.
As a solution to this you could use off() to dettach the click event (if exist) before attaching :
$(document).off('click','#sideNav a').on('click','#sideNav a',function(e){
e.preventDefault();
var url = $(this).attr('href'); //get the link you want to load data from
$.ajax({
type: 'GET',
url: url,
success: function(data) {
$("#content").empty();
$("#content").html(data);
}
});
//window.history.pushState('object', 'New Title', url);
});
});
IMO the cause of this problem comes from the posted code when you call it multiple time every time you call it the event will be attached another time and so on.
Your above script works just fine. Check out this plunk:
Html:
<!DOCTYPE html>
<html>
<head>
<script data-require="jquery#3.2.1" data-semver="3.2.1" src="https://cdn.jsdelivr.net/npm/jquery#3.2.1/dist/jquery.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<h1>Ajax request</h1>
<div id="sideNav">
Link 1
Link 2
</div>
<div id="content">
Some Content Goes Here
</div>
</body>
</html>
Javascript:
$(document).on('click', '#sideNav a', function(e) {
e.preventDefault();
var url = $(this).attr('href'); //get the link you want to load data from
$.ajax({
type: 'GET',
url: url,
success: function(data) {
console.log(data)
$("#content").empty();
html = `<p><b>Name:</b> ${data.name}</p>
<p><b>Email:</b> ${data.email}</p>
<p><b>body:</b> ${data.body}</p>`
$("#content").html(html);
}
});
// window.history.pushState('object', 'New Title', url);
});
Checkout this issue for other reasons that may cause your requests to be doubled.
Related
I have a page where there's a table with a button and when I click the button I store the value in a JS variable in order to send it to another page using post.
I get the values on the other page but after that the page does not load.
this is the button code to send the variable:
<script>
function ObtenerDatosFila(oButton)
{
var dgvVerGrupos = document.getElementById('dtBasicExample');
$.ajax({
url: 'FormularioAMGrupo.php',
type: 'post',
data:
{
Modificar:'Modificar',
IDGrupo:dgvVerGrupos.rows[oButton.parentNode.parentNode.rowIndex].cells[0].innerHTML,
},
dataType: 'json',
success:function(){}
});
return false;
}
</script>
</script>
Is there another easier a way to do this other than using post method?
You could make a one page site, no need to send the data around.
You'll have to change your structure a bit and change your ajax functions to a generic 'ShowPage(id)' function to achieve this.
If you are interested and need any help just say so.
button's page:
<script>
function ObtenerDatosFila(oButton)
{
var dgvVerGrupos = document.getElementById('dtBasicExample');
localStorage.setItem("CodigoGrupo",dgvVerGrupos.rows[oButton.parentNode.parentNode.rowIndex].cells[0].innerHTML);
localStorage.setItem("Modificar",'Modificar');
location.href ="FormularioAMGrupo.php";
}
</script>
2nd page:
<script type="text/javascript">
window.onload = alert(localStorage.getItem("CodigoGrupo"));
</script>
I have a page that pulls order statuses from a backend system and then shows the status updates on the page. I need to make the page dynamic to load, since now the page takes too long to update at once.
I got my code working so that the HTML page loads up first and then a single status update is loaded on the page.
Components:
index.php -page - basic page w. jQuery code that requests orders_updatestatus.php.
orders_updatestatus.php -page. Pulls info from a backend system and displays info. Receives what order to update via GET.
HTML (index.php - this works)
<div id="updateref"></div>
jQuery: (part of index.php - this works)
<script type="text/javascript">
// Update order status
$(function () {
$.ajax({
url: 'orders_updatestatus.php?reference=100000025',
success: function (data) {
$('#updateref').html(data);
}
});
});
</script>
UPDATED CODE
What I was thinking was that that I need to create a div for every single order so that they could then be updated individually.
$results = $mysqli->query("SELECT reference FROM orders;");
while($row = $results->fetch_assoc()) {
print '<div id="updateref'.$row['reference'].'"></div>';
}
So, with the code above I'll something like this:
<div id="updateref20000"></div>
<div id="updateref20001"></div>
<div id="updateref20002"></div>
<div id="updateref20003"></div>
<div id="updateref20004"></div>
etc..
Everything works great until this point. Now I need your help on building the corresponding jQuery code so that it would update every 'updaterefXX' -div that it sees.
My question is: How to update the following code so that it every updateref -div is updated on the page:
<script type="text/javascript">
// Update order status
$(function () {
$.ajax({
url: 'orders_updatestatus.php?reference=100000025',
success: function (data) {
$('#updateref').html(data);
}
});
});
</script>
Update/clarification: What I need is for the script to pull the orders_updatestatus.php with a GET variable for every div.
Example:
With <div id="updateref1000"> the script requests orders_updatestatus.php?reference=1000 and displays it in <div id="updateref1000"> when ready
With <div id="updateref1001"> the script requests orders_updatestatus.php?reference=1001 and displays it in <div id="updateref1001"> when ready
etc. Thank you!
You can use attribute begins with selector and .each() to iterate all elements having id beginning with "updateref", .replace() to replace portion of id that are not digits to set at query string, set .innerHTML the current element within success callback of $.ajax() call
$("[id^=updateref]").each(function(index, element) {
$.ajax({
url: "orders_updatestatus.php?reference=" + element.id.replace(/\D/g, ""),
success: function(data) {
element.innerHTML = data;
}
});
})
some info
I'm working on a webpage that can load data on multiple layouts, so user can choose which one is best. It can be loaded in a list or a cards like interface, and the data is loaded using ajax.
In this page I also have a notifier for new messages that the user received. The ajax function is new, and when page was loaded by the php scripts, the js script (that add a badge with the number of unread messages to a link on a menu item) was working ok.
I'm using HTML5, PHP, jQuery and a mySQL DB.
jQuery is imported onto the HTML using
<script src="https://code.jquery.com/jquery.js"> </script>
So it's a recent version.
the problem
Now, when I load the data onto the page using ajax, the js script won't work anymore. I had the same issue with another js script and I managed to solve it by using the delegate event binder.
But my unread messages updater runs on a time interval, using
<body onload="setInterval('unread()', 1000)">
the unread() js is quite simple:
function unread() {
$(document).ready(function(){
$('#menu_item').load('ajax_countNewMsgs.php');
});
}
it calls a php script which grabs the unread msgs count from the DB and echo into a element that jQuery will point. Hope I'm being clear.
The problem is that I cannot figure out how I would call a timed event using delegate. Without much hope I've tried
$(document).on('ready()','#menu_item', function () {
$(this).load('ajax_countNewMsgs.php');
});
That didn't work.
I read many posts about js stop working after changes in the DOM, but, again, I couldn't figure out a way to solve that, nor found a similar question.
Any help or tips would be highly appreciated.
EDITED to change second php script's name
2nd EDIT - trying to make things clearer
I tried the way #carter suggested
$(document).ready(function(){
function unread(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
$('#menu_item').html(response);
},
error: function(response){
//no error handling at this time
}
});
}
setInterval(unread(), 1000);
});
the ajax_countNewMsgs.php script connects to the DB, fetch the unread messages, and echoes the number of unread messages.
If I try to apply the ajax reponse to another element, say, the <body> the results are as expected: at each 1 sec , the body html is changed. So the function is working.
As I said, none of my JS changes the #menu_item. Actuallly this element is part of another php scritp (menu.php) which is imported to the top of the page.
the page structure is this way:
<html>
<head>
some tags here
</head>
<body>
<?php include (php/menu.html); ?>this will include menu with the #menu_item element here
<div id='wrapper'>
<div id='data'>
here goes the data displayed in two ways (card and list like). Itens outside div wrapper are not being changed.
</div>
</div>
</body>
</html>
Even though the elemente is not being rewritten js cannot find it to update it's value.
It's not the full code, but I think you can see what is being done.
$(document).on('ready()','#menu_item', function () {
is an invalid event listener. If you wanted to be made aware of when the DOM is ready you should do this:
$(document).ready(function () {
However I don't think that is actually what you want. Your function unread will fire repeatedly but it attaches an event listener everytime. Instead if you want to make an ajax call every so many seconds after initial page load, you should do something like this (dataType property could be html, json, etc. pick your poison):
$(document).ready(function(){
function makeCall(){
$.ajax({
url: 'ajax_countNewMsgs.php',
type: 'GET',
dataType: 'html',
success: function(response){
//handle your response
},
error: function(response){
//handle your error
}
});
}
setInterval(makeCall, 1000);
});
remove that on your unread function:
$(document).ready(function(){
WHY?
The Document is already "ready" and this document state will only fired 1x - After that the "ready state" will never ever called. Use follwing syntax:
jQuery(function($){
I have a jquery tab set:
<div id="tabs">
<ul>
<li>Mileage Log</li>
<li>Trips</li>
</ul>
<div id="tabs-1">something</div>
<div-id="tabs-2">something</div>
</div>
My content on my tabs fires some javascript code that posts form data (I included that code). The problem is that I would like the tab element to refresh so any new content can be shown. Is there a built-in way to refresh the tabs using the "success:" option. I am currently using "location.reload();" but it just refreshes the whole page. Not ideal.
Thanks.
My Javascript
<script>
$(document).ready(function () {
//Submit form to add record.
$('#addmileage').submit(function (e)
{
e.preventDefault();
$.ajax({
data: $('#addmileage').serialize(),
type:'POST',
url:'actionpages/add_trip.cfm?ticketid=<cfoutput>#url.ticketid#</cfoutput>',
success: function(){
$('.success').fadeIn(200).show();
location.reload();
$('.error').fadeOut(200).hide();
}
});
});
$('.deleteMileageForm').submit(function (e)
{
e.preventDefault();
$.ajax({
data: $(this).serialize(), // **** modified this line ****
type:'POST',
url:'actionpages/delete_trip.cfm',
success: function () {
$('.successTab2').fadeIn(200).show();
location.reload();
$('.errorTab2', $row).fadeOut(200).hide();
}
});
});
});
</script>
The only way I think you could achieve this, is to have the server-side functions you're calling in AJAX, return a block of HTML which you could inject into the of the tab you want to reload. And if you're going to do that, you'll need to put the functions in a CFC instead of the CFM page you're calling now.
So, you would generate the way you're doing now to build the initial page, but save the generated HTML as a string and then return it to the jQuery AJAX call.
As just a really bare-bones example:
$('.deleteMileageForm').submit(function (e)
{
e.preventDefault();
$.ajax({
data: $(this).serialize(), // **** modified this line ****
type:'post',
dataType: 'json',
url:'actionpages/actions.cfc?method=deleteTrip&returnformat=json',
success: function (result) {
$('.successTab2').fadeIn(200).show();
$('.errorTab2', $row).fadeOut(200).hide();
$('#tab2').html(result);
}
});
Then on the server you'll need an actions.cfc with remotely accessible functions:
<component>
<cffunction name="deleteTrip" access="remote">
<cfset newHTML = "<h1>This is new HTML!</h1>">
<cfreturn newHTML>
</cffunction>
</component>
I've put everything into JSON format, just because I always use JSON. :)
Not sure how familiar you are with CFCs, returnformats, etc. But hopefully this is a push in the right direction.
You need to refresh the tabs in the success function using DOM Manipulation. It may be the case, that your scripts like actionpages/delete_trip.cfm have to return new information which you need to refresh the tabs (for example in the JSON format).
Some notes:
The function location.reload(); may reload the page from the browser cache. Use location.reload(true); if you do not want this behavior.
$('.successTab2').fadeIn(200) should be enough (.show() is not needed). You also do not need the .hide() function.
Since, I am new to jQuery I am facing problem in parsing html data retrieved from ajax.
I have a form which is using ajax to post form data and retrieve the content back to that page by adding one div ( on the same page as that of form ) to display that data.
I want to perform some jQuery / Javascript operations on that data, but since I am not reloading the page, jQuery or javascript is not able to parse that data.
How can I force javascript or jquery to reparse the whole page without loading it.
Here is the code
html
<div class="col col-lg-9 search-data well">
<div class="no-results">
Search Results will appear here.
</div>
</div>
jQuery
$('.search-form').click(function(e)
{
console.log('same-page');
e.preventDefault();
var form_var = this.form;
var postData = $(this.form).serialize();
var formURL = $(this.form).attr("action");
$.ajax(
{
url : formURL,
type: "POST",
data : postData,
success:function(data, textStatus, jqXHR)
{
// console.log(data)
$('.search-data').empty(); // Delete all child nodes
$('.search-data').html(data);
},
error: function(jqXHR, textStatus, errorThrown)
{
$('.search-data').empty(); // Delete all child nodes
$('.search-data').html(data);
}
});
return false;
});
Thankyou
my question is how can I perform jQuery operations on the data I have got back from server.
If you want to do something to the HTML before you add it to the page, you can do this:
var fragment = $(data);
That will parse the HTML into elements and give you a jQuery wrapper around those elements, without adding them to the page anywhere. You can then manipulate those with jQuery. Eventually, of course, if you want them to appear on the page, you have to add them to the page somewhere (via html or append or similar on an existing element).
data has some a links, I want to parse those links perform some operations on click of them
You can do that. Example: Live Copy | Live Source
HTML fragment:
<div>
Stack Overflow
w3schools
</div>
Here's a page using it. In this case, I remove a link we don't want and hook the click event on the ones that remain, then append them to the page:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<meta charset=utf-8 />
<title>Modify HTML Before Appending</title>
</head>
<body>
<script>
$.ajax({
url: "http://jsbin.com/IsixODa/1",
dataType: "html",
success: function(data) {
var fragment = $(data);
// Remove some links we don't want
fragment.find(".remove").remove();
// Hook the others
fragment.find("a").click(function() {
alert("You clicked a link: " + this.href);
return false;
});
// Put them on the page
fragment.appendTo(document.body);
},
error: function() {
$("<p>Ajax call failed</p>").appendTo(document.body);
}
});
</script>
</body>
</html>