Using .one() with .get() - php

QUESTION: What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?
MOST RECENT EDIT:
solution
<script>
$(document).ready(function(){
$('.tree li a').one("click", function() {
var currentAnchor = $('.tree li a').attr('href');
if(!currentAnchor){
var query = "page=1";
}
else
{
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
alert ("page=" + page);
}
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
return false;
});
});
</script>
More Specifically:
I'm using Javascript and PHP to load some external PHP pages as sections in my main template.
I'm using a switch and append() so the included files keep appending. I need every file to be able to be appended ONLY ONCE. Here is the scenario as I'd like it to happen
1) downloads link is clicked
2) downloads.php appears
3) errors link is clicked
4) errors.php appears below downloads.php
5) downloads link is clicked again
6) page just scrolls up to top of downloads.php
I need the same functionality as the example on the documentation page of .one() where every div can be clicked only once.
I also looked at Using .one() with .live() jQuery and I especially liked the approach used in the accepted answer.
Iried using boolean flag as suggested below but all it did was limit my consecutive clicks on the same link to one. So if I click one link 1 multiple times it'll show page 1.php only once but if I click on link 1, then link 2, then link 1 again it will display page 1.php, then append page 2.php and append another page 1.php.
I'm starting to think that the setInterval is wrong and I may use .one() for the whole checkAnchor() function and bind it to the <a> tags. I tried this but it's not working either :(((
core.js - using .one()
var currentAnchor = null;
//$(document).ready(checkAnchor);
//Function which chek if there are anchor changes, if there are, sends the ajax petition checkAnchor
$("a").one("click", function (){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
}
});
The other thing I liked as an approach is adding the names of the pages to an array and then checking that array to make sure the page wasn't displayed yet. I managed to fill up an array with the page names using .push() but I hit a dead end when looking up for a value in it. If you have an idea how that's supposed to look like that'd be very helpful as well.
core.js
///On load page
var contentLoaded;
$().ready(function(){
contentLoaded = false;
setInterval("checkAnchor()", 300);
alert (contentLoaded);
});
var currentAnchor = null;
//Function which chek if there are anchor changes, if there are, sends the ajax petition
function checkAnchor(){
//Check if it has changes
if(currentAnchor != document.location.hash){
currentAnchor = document.location.hash;
//if there is not anchor, the loads the default section
if(!currentAnchor){
query = "page=1";
}
else
{
//Creates the string callback. This converts the url URL/#main&id=2 in URL/?section=main&id=2
var splits = currentAnchor.substring(1).split('&');
//Get the section
var page = splits[0];
delete splits[0];
var query = "page=" + page;
}
alert ("hello");
//Send the petition
$("#loading").show();
alert (contentLoaded);
if (!contentLoaded){
$.get("callbacks.php",query, function(data){
$("#content").append(data);
$("#loading").hide();
});
alert (contentLoaded);
}
contentLoaded = true;
}
}
here is my
callbacks.php
<?php
//Captures the petition and load the suitable section
switch($_GET['page']){
case "4100errors" :
include 'template/4100errors.php';
break;
case "4100downloads" :
include 'template/4100downloads.php';
break;
}
?>
And my main file
4100.php
<?php
include 'template/header.php';
include 'template/4100menu.php';
include 'template/log.php';
include 'template/links.php';
include 'template/4100breadcrumbs.php';
?>
<div class="left-widget">
<div style="display:none; position:absolute; top:-9999; z-index:-100;">
</div>
<div id="side-nav-bar" class="Mwidget">
<h3>Contents</h3>
<ul class="tree">
<li><a href="#4100downloads" class="links" >Downloads</a> </li>
<li>Error Troubleshooting</li>
</ul>
</div>
</div>
<div id="content" style="margin-top:100px; margin-left:300px;">
<?
switch ($_GET['page'])
{
case "4100downloads": include 'template/4100downloads.php'; break;
case "4100errors": include 'template/4100errors.php'; break;
}
?>
</div>
</body>
</html>
4100dowloads.php
Downloads test page
4100error.php
Errors test page
Also you can look at the test page here http://period3designs.com/phptest/1/4100.php

"What is the proper way to use .get() in conjunction with .one() (or .live()) so that an external php file is appended only once?"
.one() and live() really have little to do with $.get. They're only for event handling.
If you intend to run the code every 50ms as you are, but want to replace the current content, then use .html() instead of .append().
$("#content").html(data);
This will overwrite the old content.
I assume you're aware of this, but just to be sure, your code is running at an interval because of this...
$().ready(function(){
setInterval("checkAnchor()", 50); // better--> setInterval(checkAnchor, 50);
});
If you only want it once on document load, then do this...
$(document).ready(checkAnchor);

Just use a boolean flag to determine if you loaded the data yet or not. Set it to false on page load, and just after the call to $.get set it to true. Then, wrap your $.get with an if (!contentLoaded) { $.get ... }.
That way you will execute the $.get only once.
BTW: $.one is used to bind an event to an element, that will execute only once and then unbind it self from it.

Related

Handle Ajax redirect and load content into new page

I am using Ajax to dynamically update a data table without refreshing. I have no problem so far. The user selects certain criteria from a Form . The issue is that , I no longer want to fetch content to this same page but I want to redirect and load content on a different template:
Users selection (Page1.html) -> Ajax -> redirect to Page2.html -> load data within Page2
Would someone please have a look at the code below and advise why it is not working ? I am able to redirect but there isn't any returned data.
Ajax
if (t && e ) {
dataArray = new Array;
dataArray[0] = e;
dataArray[1] = t;
$.ajax({
type: "POST",
url: "includes/filter.php",
data: {
Name: e,
Color: t,
},
success: function (e) {
window.location.href = 'Page2.html'; // Redirect to this page
$("#Wrapper").html(e); // Load content to this page in Div # Wrapper
// If I Uncomment the two lines above and just add $("#table").html(e); it will successfully load content within the table div on the same page
}
});
}
Where filter.php handles the server side query and outputs an html table with the data.
THanks
Pass e and t to your next page like
window.location.href = 'Page2.html?e=' + e + '&t=' + t;
Once page2 is loaded, get e and t and make your ajax call and replace html of wrapper. In your current solution page2 is loaded before wrapper html gets replaced.
for creating query string from array:
var array = [],
array["Name"] = "Car";
array["Color"] = "Red";
var queryStr = "";
for (var key in array){
if(queryStr != "") queryStr += "&";
queryStr += key + "=" + array[key];
}
var url = "Page2.html?" + queryStr;
Try this:
if (t && e ) {
dataArray = new Array;
dataArray[0] = e;
dataArray[1] = t;
$.ajax({
type: "POST",
url: "includes/filter.php",
data: {
Name: e,
Color: t,
},
success: function (data) {
window.location.href = 'Page2.html?data='+data ; // Redirect to this page
}
});
}
After send to the request to the page using POST. And add this line in
page2.html $("#Wrapper").html(e);
I would suggest to clearly choose your path :
Option 1 : drop the ajax request, and do open a new window
window.open('Page2.html?filter=yabayabayaba')
Option 2 : use an ajax request, and load the result in a dialog box (using bootstrap or jquery-ui)
success: function (e) { $(e).dialog(); }
There are a few things wrong here.
When window.location.href = 'Page2.html'; executes it stops the rest of the code from executing and redirects the browser.
The $("#Wrapper").html(e); is in your AJAX success function. So it
will only ever fire after the AJAX call. When the new page loads
this code isn't executed. (It will never fire anyway because of the redirect in front of it).
The whole point of AJAX is to not redirect the user. If you're redirecting them anyway then why not just have the correct content in Page2.html when it loads rather than inserting it with javascript?
Alternatively, you could drop the redirect and just load the entire Page2.html file into your current page in place of the original template using an AJAX request.
I don't know what your HTML looks like but if Page2.html has a div named #wrapper all you need to do is load everything from inside #wrapper of Page2.html into the #wrapper of Page1.html like this:
$('#wrapper').load('Page2.html #wrapper');
That code you should go in your AJAX success function in place of the redirect. You can see more about .load() here.

Reload div using jquery load function working only once and how to pass a variable

I have very limited knowledge with scripts so I hope you guys can help me with a simple solution to a small problem that I have...
I'm using the following jquery function to refresh a div with new content when a link is clicked
<script>
$(function() {
$("#myButton").click(function() {
$("#loaddiv").fadeOut('slow').load("reload.php").fadeIn("slow");
});
});
</script>
My problem is, I need to send 2 variables to the reload.php page to use in a mysql query (I have no idea how to accomplish that), also I need to make multiple links work with this function, at the moment I have multiples links with the same id and only the first link works so I guess I must associate different ids to the function in order for this to work, how can I do that?
here's the page where i'm using this: http://www.emulegion.info/teste/games/game.php
You may want to use document ready instead of function on your first line as this will make sure the code is not executed until the full page (and all elements) have loaded.
You can then use the callback functions of the fade and load to perform actions in a timely manner.
additional variables you can add after the .php, these can then be read in your reload.php file as $var1 = $_GET['var1'];
Do make sure to sanitize these though for security.
<script type="text/javascript">
// execute when document is ready
$(document).ready(function() {
// add click handler to your button
$("#myButton").click(function() {
// fade div out
$("#loaddiv").fadeOut('slow',function(){
// load new content
$("#loaddiv").load("reload.php?var1=foo&var2=bar",function(){
// content has finished loading, fade div in.
$("#loaddiv").fadeIn('slow');
}); // end load content
}); // end fade div out
}); // end add click to button
}); // end document ready
</script>
For different variables you could add a HTML5 style variable to your button.
<input type="button" id="myButton" data-var1="foo" data-var2="bar" />
You can retrieve this when the button is clicked:
// add click handler to your button
$("#myButton").click(function() {
// get vars to use
var var1 = $(this).data('var1');
var var2 = $(this).data('var2');
...
load("reload.php?var1="+var1+"&var2="+var2
if you have multiple buttons/links I would use class instead of id "myButton". that way you can apply the function to all buttons with the above script. Just replace "#myButton" for ".myButton"
First, you should use .on('click', function() or .live('click', function() to resolve your one click issue.
You'll want to do something like:
<script>
$(function() {
$("#myButton").on('click', function() {
var a = 'somthing';
var b = 'something_else';
$.post('url.php', {param1: a, param2: b}, function(data) {
//data = url.php response
if(data != '') {
$("#loaddiv").fadeOut('slow').html(data).fadeIn("slow");
}
});
});
});
</script>
Then you can just put var_dump($_POST); in url.php to find out what data is being sent.
Try creating a function that would accept parameters that you want.
Like:
$(document).ready(function(){
$('.link').click(function(){
reload(p1,p2);
});
});
function reload(param1, param2){
$("#loaddiv").fadeOut('slow').load("reload.php?param1="+param1+"&param2="+param2).fadeIn("slow");
}
But by doing the above code your reload.php should be using $GET. Also you need to use class names for your links instead of id.
<script type="text/javascript">
// execute when document is ready
**$(document).ready(function() {**
**$("#myButton").click(function() {**
**$("#loaddiv").fadeOut('slow',function(){**
**$("#loaddiv").load("reload.php?var1=foo&var2=bar",function(){**
// content has finished loading, fade div in.
$("#loaddiv").fadeIn('slow');
});
});
});
});
</script>
$("#myButton").click(function() {
// get vars to use
var var1 = $(this).data('var1');
var var2 = $(this).data('var2');

AJAX pagination solution for PHP

Right now I use a pagination system that requires url like
http://mypage.com/index.php?page=1
http://mypage.com/index.php?page=2
http://mypage.com/index.php?page=3
http://mypage.com/index.php?page=4
etc...
So it uses $_GET method to find out what page the user is on.
I decided to switch most of my website to ajax and came over a problem. When I use Ajax to load new content on a page the url stays the same all the time e.g. http://mypage.com/index.php . Therefore pagination system I use is useless.
I was not able to find efficient AJAX pagination systems, (e.g some where lagy, most required user to scrol to the tiop each time he / she clicked on a next page, because they stayed at the bottom of the page when they clicked next page. etc...)
So I decided to ask you lot if anyone has an efficient pagination solution that works with ajax.
Example of what needs to be paginated:
$sql = mysql_query("SELECT * FROM myMembers WHERE username='$username' LIMIT 1") or die (mysql_error("There was an error in connection"));
//Gather profile information
while($row = mysql_fetch_assoc($sql)){
$username = $row["username"];
$id = $row["id"];
$data_display .= '<b>'.Name.'</b> has an id of <span style="color: f0f0f0;">'.$id.'</span>';
}
<!doctype>
<html>
<?php echo "$data_display"; ?> //and I need to paginate this entries
</html>
jQuery that loads new content from different pages into #content div
<script type="text/javascript">
function viewHome(){
$('#woodheader').load("inc/home_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/home.php", function () {
$(this).hide().fadeIn(700)
});
}
function viewAbout(){
$('#woodheader').load("inc/about_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/about.php", function () {
$(this).hide().fadeIn(700)
});
}
function viewProducts(){
$('#woodheader').load("inc/products_top.php", function () {
$(this).hide().fadeIn(700)
});
$('#content').html('<span class="loader">Loading.. <img class="loaderimg" src="images/ajax_loader.gif"/></span>').load("inc/products.php", function () {
$(this).hide().fadeIn(700)
});
}
</script>
Pagination is not as hard as you can think, you can use jQuery's load() function to load content into an element with the page's content.
So for example you have:
<div id="page-content"></div>
Page 1
Page 1
Page 3
<script>
$.ready(function(){
var currPage = <?=$pageNumber; ?>; // The page number loaded on page refresh
$('#link1,#link2,#link3').onclick(function(){
// Get the first number inside the id
var pageNum = parseInt($(this).attr('id'));
// Don't load the same page
if(currPage == pageNum) return;
// Show loading animation or whatever
// Load the page using ajax
$('#page-content').load('pages.php?page='+pageNum, function(){
// End loading animation
currPage = pageNum;
});
return false; // Important for not scrolling up
});
});
</script>
Regarding the url, you have three options to choose from when a user clicks a page link:
Just load the page with no changing of the url
Use the HTML5 history.pushState(see MDN resource) if supported and with option 3 as fallback for unsupported browsers
Use #page1, #page1 etc. as the href value of the links so that the user knows on what page they are on and parse the value of the url in php:
$uri = explode('#page', $_SERVER['REQUEST_URI']);
$pageNumber = intval($uri[1]);
I would create a index.php that doesn't load any $data_display initially.
Internally in javascript I would keep a variable named $page that would initially equals 1.
After load it would make a ajax call to names.php?page=$page and pass the results to a handler that presents it to the user.
Then on the links to "back" and "next" I would put a javascript function that first sets $page to the previous or next number, then calls names.php?page=$page and pass the results to the same handler.

How to check for contents of a loaded div tag using jquery load?

I'm working with jqueries address change event and am hitting a roadblock when a user copies and pastes a URL in the browser. I need to fist load a portion of the page that contains a form. I could do this after every pagination call but it seems really ineffecient.
Here is my current code block:
$.address.change(function(e) {
var urlAux = e.value.split('=');
var page = urlAux[0];
var start = urlAux[1];
if (page == "/visits") {
$.address.title("Profile Views");
if (start) {
$('#start').val(start);
// ***** If a user has copied and pasted this URL with a start value then I first need to load visits.php in the main div tag. Is it possible to see if this is loaded or not?
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits=" + start;
});
}
else {
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () { });
}
}
My attempted work around was this:
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () {
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
$('#search_results').html(data);
location.href = "#visits=" + start;
});
});
There must be a better way...this is realoading the same portion of the page (visits.php) with every pagination event. Is there a better way to load URLs and not have them trigger an address change?
Using paul's work around from his comments, but instead of Regex'ing html content in the visits.php form this solution will look for data() attached to #mainID.
Paul's work around notes:
After a bit more hacking I came up with this solution that seems to do
the trick. I'm not sure how good it is but it seems to do the trick. I
now get the main div id and do a regex match on a unique string in the
form. If I don't see it I load the form and then load the results. Not
sure if this is good practice or not but it seems to solve my issue.
Methodology to use .data() instead of a regex search of visits.php's html:
/*check if we're missing visits.php by looking for data() flag*/
if( !($("#main").data()["hasVisitsPhp"]) ){
var args = localStorage.getItem("visits");
$('#main').load("visits.php?" + args, function () {
$('#start').val(start);
$.post("visits_results.php", $("#profile_form_id").serialize(),
function(data) {
/* we've loaded visits.php, set the data flag on #main*/
$('#main').data("hasVisitsPhp","loaded");
$('#search_results').html(data);
location.href = "#visits=" + start;
});
});
}
try window.location.hash instead. Changing the whole href can/will trigger a whole-page reload, while changing just the hash by itself should at most cause the page to scroll.

.load() jquery php General question

This is a general question, I have two pages, a main and a backgound function one (file.php)
Main page loads file.php passing variables:
$(document).ready(function() {
var page = $('#page').attr('value');
var user = $('#user').attr('value');
$('#DIV').load('file.php?user=' + user + '&page=' + page);
});
File.php queries database, inserts variables into more jquery stuff..
echos result...
The result on the main page is the desired one. If I fixe the variables in file.php (and load through browser) the script is fully functionnal and interactive.
My problem is as follows:
The file.php part of the main page is not interacive, i.e. when I click on it nothing happens, yet the 2 work fine idependently, together variables are passed, but the result is static.
My question, is this due to the .load() function? Should I be using $.ajax() type GET ...
Thanks in advance.
It sounds like you have jQuery behaviours attached to the DOM that are not being applied to the new content. This is because the new content is loaded after the DOM is ready (ie, after the load event fires).
This can be solved by using the .live jQuery function to attach events to a selector that will be applied to all elements, regardless of when they're added. E.g, instead of:
$('#button').click(function() { alert('hi'); });
Use:
$('#button').live('click', function() { alert('hi'); });
Is #DIV referring to:
<div id="DIV"></div>
Perhaps you should try this:
$(document).ready(function() {
var page = $('#page').attr('value');
var user = $('#user').attr('value');
// see the DIV below with the ID = "myId"
$("#myId").load("file.php?user=' + user + '&page=' + page", function(response, status, xhr) {
if (status == "error") {
var msg = "Sorry but there was an error: ";
$("#error").html(msg + xhr.status + " " + xhr.statusText);
}
});
});
<!-- empty containers with ID attributes -->
<div id="myId"></div>
<div id="error"></div>
If there is an error in the returned data, this will also tell you what the error is. Also, what does your debugger tell you?

Categories