I'm using jQuery address to enable loading specific content from other pages
and to change the URL in the address bar.
I'm working on a little Social Network alike website, so I'm reading out the IDs
of the posts table of my MySQL database via PHP. I want to use the possibilities of jQuery and AJAX to read everything out dynamically.
I found out, that I have to use live() (which turned out to be old), delegate() (which
also turned out to be old in 1.7.1) or on() (which turns out to be the best possibility
to make events work inside of dynamically loaded content via jQuery + AJAX).
I also read somewhere, that I can't use load() or get() to load new content from another
page inside of an already loaded content, because it doesn't "bubble" (I don't even know
what that means).
What do I have to do to load new content within an AJAX loaded page?
Here's a snippet I tried to work with (included on the loaded page):
<?php
if(exist('`posts`')) {
$load = mysql_query('SELECT `id` FROM `posts` ORDER BY `id` DESC LIMIT 10');
while($row = mysql_fetch_object($load)) {
?>
<script type="text/javascript">
$('body').on('body', 'load', function() {
$.get('getpost.php', { pid: <?= $row->id ?> }, function (data) {
$('#posts').html($('#post_<?= $row->id ?>', data).html()).show();
});
$('#posts').off('load');
});
</script>
<?php
}
}
else {
?>
<div align="center">No posts yet.</div>
<?php
}
?>
getpost.php is my file from which I can get the div_$row->id so that it appears on the start page.
PLUS (Just adding for your knowledge) I want the content to load the content without
a mouseover, click or blur event.
Thanks.
You want to use ".live()" if you want a particular event mapping to be applied dynamically to any new DOM elements which match its selector. Alternatively, you can attach the behavior to each chunk of content loaded.
Write and develop your ajax load independently of your DB lookup to make things simpler. The following snippet triggers another ajax call after each element loads.
<?php
$id = 'div'.mt_rand();
$counter = isset($_REQUEST['counter']) ? $_REQUEST['counter'] : 0;
$next = $counter + 1;
echo <<<END
<div id="{$id}">{$counter}
<script>
$(function() {
$.ajax('/url?counter={$next}', function(html) {
$(html).appendTo($('#{$id}').parent()); // or whatever your favorite method is for adding a sibling
});
});
</script>
</div>
END;
?>
Am I the only one who thinks that this approach is completely wrong? You're making an ajax request for each post, this could end up in making way too much requests, heavily slowing down the loading time. I can't see any reason why you don't want to directly write the posts' HTML inside the PHP while loop.
Related
For one of my wordpress site php files, I have the following code:
<div class="tabs">
Items
</div>
<div class="section" id="tab1">
<?php get_template_part('page/tab1'); ?>
</div>
So, it will call the tab1.php file into the div id="tab1"section.
However, I want to make it so that the get_template_part is only executed or called when the Items tab is clicked.
What would be the jQuery to call or execute the get_template_part function?
EDIT:
So, what I am trying to achieve is similar to Ajax. Since the get_template_part function won't be called till the "Items"tab is clicked, the browser does not have to call unnecessary files and slow down the page.
Let me know if you think this is the best way to do it.
Thanks!
Though the idea behind is already illustrated by Raphael in his answer, I intervene to add some details.
the best way to use AJAX with Wordpress is to use its built-in way of handling it, and that by sending requests to wp-admin/admin-ajax.php( I know the “admin” part of the file name is a bit misleading. but all requests in the front-end (the viewing side) as well as the admin can be processed in admin-ajax.php, with a lot of benefits, especially for security. And for the server-side code php that will be executed, it should be placed in functions.php.
Your jQuery code will look something like:
$(document).ready(function() {
$('.tabs a').click(function(e) {
e.preventDefault();
var tab_id = $(this).attr('id');
$.ajax({
type: "GET",
url: "wp-admin/admin-ajax.php",
dataType: 'html',
data: ({ action: 'yourFunction', id: tab_id}),
success: function(data){
$('#tab'+tab_id).html(data);
},
error: function(data)
{
alert("Error!");
return false;
}
});
});
});
infunctions.php of your theme (or directly in your plugin file), add:
add_action('wp_ajax_yourFunction', 'yourFunction');
add_action('wp_ajax_nopriv_yourFunction', 'yourFunction');
and define in the same file yourFunction callback function like this:
function yourFunction() {
// get id
// your php code
die();
}
For the javascript part, take a look at ajax() and its shorthand get(). And for the best practices using AJAX with Wordpress, there are many tutorials on the web (I will be back to give one). Good luck
Edit:
As it is mentionned by Karl, you can use .load() instead of ajax(), It should be noted that .load() is just a wrapper for $.ajax(). It adds functionality which allows you to define where in the document the returned data is to be inserted. Therefore really only usable when the call only will result in HTML. It is called slightly differently than the other as it is a method tied to a particular jQuery-wrapped DOM element. Therefore, one would do: $('#divWantingContent').load(...) which internally calls .ajax().
But my original answer is on how to organize php code respecting Wordpress best practices.
You can't really call a PHP function from javascript because by the time the browser sees the page, the PHP has already executed (or in your case, not executed )
The only way for you to do what you want is to spin the PHP function off into a separate script and then call that file using AJAX. Have the script echo HTML, and then insert the HTML into the tab1 div in the AJAX callback.
I think the easiest solution for you would be to use the jQuery load() function. It is the easiest way to achieve what you describe. The only issue that when someone clicks the header, there will be a delay to get the subitems as they do not exist yet (which would be the case for any situation where you delay the load.
HTML:
<div class="tabs">
Items
</div>
<div class="section" id="tab1"></div>
JS:
$(function () {
//wait for the page to finish loading
$('#items_id').click (function (e){
//watch for the items header to be clicked
e.preventDefault();
//prevent it from opening a link
$('#tab1').load('tab1.php');
//load the tab1.php file, or whatever file INTO the div
});
})
The problem is this:
I have a simple, two fields form which I submit with Ajax.
Upon completion I reload two div's to reflect the changes.
Everything is working perfect except a jQuery plugin. It's a simple plugin that can be called with simple
function(){
$('.myDiv').scrollbars();
}
It's simple and easy to use, but it doesn't work on Ajax loaded content. Here is the code I use to post form and reload div's:
$(function() {
$('#fotocoment').on('submit', function(e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
}).error(function() {
});
e.preventDefault();
});
});
I've tried creating a function and calling it in Ajax succes:, but no luck. Can anyone show me how to make it work ? How can that simple plugin can be reloaded or reinitialized or, maybe, refreshed. I've studied a lot of jQuery's functions, including ajaxStop, ajaxComplete ... nothing seems to be working or I'm doing something wrong here.
If you're loading elements dynamically after DOM Document is already loaded (like through AJAX in your case) simple binding .scrollbars() to element won't work, even in $(document).ready() - you need to use "live" event(s) - that way jQuery will "catch" dynamically added content:
$(selector).live(events, data, handler); // jQuery 1.3+
$(document).delegate(selector, events, data, handler); // jQuery 1.4.3+
$(document).on(events, selector, data, handler); // jQuery 1.7+
Source: jQuery Site
Even if I am totally against using such plugins, which tries to replicate your browser's components, I'll try to give some hints.
I suppose you are using this scrollbars plugin. In this case you may want to reinitialize the scrollbars element, and there are many ways to do this. You could create the element again like in the following example
<div class="holder">
<div class="scrollme">
<img src="http://placekitten.com/g/400/300" />
</div>
</div>
.....
$('.scrollme').scrollbars();
...
fakedata = "<div class='scrollme'>Fake response from your server<br /><img src='http://placekitten.com/g/500/300' /></div>";
$.post('/echo/html/', function(response){
$('.holder').html(fakedata);
$('.scrollme').scrollbars();
});
If you want to update the contents of an already initialized widget instead, then things gets more complicated. Once your plugin initialize, it moves the content in some custom wrappers in order to do its 'magic', so make sure you update the correct element, then trigger the resize event on window, pray and hopefully your widget gets re-evaluated.
If it doesn't help, then try to come up with some more details about your HTML structure.
I want to thank everyone of you who took their time to answer me with this problem I have. However, the answer came to me after 4 days of struggle and "inventions" :), and it's not a JS or Jquery solution, but a simple logic in the file.
Originally, I call my functions and plugins at the beginning of the document in "head" tag, like any other programmer out here (there are exceptions also ).
Then my visitors open my blog read it and they want to post comments. But there are a lot of comments, and I don't want to scroll the entire page, or use the default scroll bars, simply because they're ugly and we don't have cross browser support to style that, just yet.
So I .post() the form with the comment, and simply reload the containing all of them. Naturally .scrollbars() plugin doesn't work. Here come the solution.
If I put this :
<script>$('.showcoment').scrollbars();</script>
in the beginning of my loaded document (with load() ), will not work, because is not HTML and it's getting removed automatically. BUT !!! If i do this:
<div><script>$('.showcoment').scrollbars();</script></div>
at the same beginning of loaded document, MAGIC .... it works. The logic that got me there I found it in the basics of javascript. If your script is inside an HTML element, it will be parsed without any problem.
Thank you all again, and I hope my experience will help others.
If I understand you correctly, try this:
var scrollelement = $('.myDiv').scrollbars();
var api = scrollelement.data('jsp');
$(function () {
$('#fotocoment').on('submit', function (e) {
$.post('submitfotocoment.php', $(this).serialize(), function (data) {
$(".coment").load("fotocomajax.php");
api.reinitialise();
}).error(function () {
});
e.preventDefault();
});
});
reinitialise - standart api function, updates scrolbars.
I think I am close but I am stuck at the moment. Here is a little background.
I'm using Wordpress, and I have a plugin for a gallery. Each gallery has an ID and I'm trying to accomplish when a user clicks on the gallery link, the gallery will change to the corresponding gallery. The gallery is being displayed like so:
<?php echo do_shortcode('[slideshow gallery_id="1"]'); ?>
or
<?php if (function_exists('slideshow')) { slideshow(true, "1", false, array()); } ?>
both do the same thing -
where gallery_id specifies the correct gallery. I'm using AJAX to run some code to get back the correct gallery ID when the user clicks the link.
jQuery('.gallery-btn').click(function() {
var galleryId = jQuery(this).data('gallery');
jQuery.ajax({
url: "/wp-content/themes/thetheme/gallery.php",
data: {action: galleryId},
type: 'post',
success: function(output) {
console.log(output);
}
})
})
PHP code in gallery.php:
<?php
if(isset($_POST['action']) && !empty($_POST['action'])) {
$galleryId = $_POST['action'];
passId($galleryId);
}
function passId($id) {
echo $id;
}
?>
output returns the ID that I need to then pass into the PHP code [slideshow gallery_id="$theID"].
How can I use output from the success function in my PHP code?
The short answer is that you can't. At least not in the manner that you are proposing. The PHP code that generates your gallery is executed before the page is initially loaded. You can't have jQuery call a script after the page loads and pass it to an already executed PHP function.
That being said, you may have some other options to update the gallery after the page loads. Not being familiar with what gallery you are using, I can't give specific advice. However, I can talk about general approach.
You might be able to use javascript/jQuery to change the original HTML output by the gallery (i.e. <img> tags, src links, etc.). In this case you might use AJAX to pull down gallery metadata as needed to make these changes.
I simpler approach might be to simply output an entire new block of gallery HTML (perhaps using the initial function) and just replace this for the current HTML within the DOM. In this case you could have the AJAX call a server-side script that re-runs the gallery function and returns the HTML content for insertion into the DOM by javascript.
I am trying to load a static street view image, where the various parameters are stored in a mysql database. After trying lots of alternatives, I'm now passing the database data to a javascript variable and then trying to build the relevant URL (taking into account the page width along the way).
The page loads as restaurant.php?r=xyz where xyz is looked up on MySQL to return a line of data $r that is passed into a javascript array. Some of the array fields are used to create the URL of a Google Street view static image, which should then be loaded into the page.
This works fine if I enter the get to this page having started elsewhere on the site (or after a page refresh).
But if I start from this page and navigate around all future links to restaurant.php?r=abc do not load the image (it is downloaded and can be seen in the Chrome sources box). The pageinit event fires but the .html() fails to change the content (but reports no error).
I suspect I am breaking several laws of javascript, and jquery mobile....
Declared in header
var resto = {};
function insertSVPhoto() {
console.log("insertSVPhoto: Loaded data for: "+resto['rname']);
if ( Math.round(resto['heading']) != 0) {
var width = Math.round( $(document).width() * .9);
var s= "x250&location="+resto['lat']+",%20"+resto['lng']+"&fov=60&heading="+resto['heading']+"&pitch="+resto['pitch']+"&sensor=false";
var photo = "<img src='http://maps.googleapis.com/maps/api/streetview?size="+width+s+"'>";
console.log("Loading photo: "+photo);
$('#svphoto').html(photo);
} else {
console.log('No photo available');
$('#svphoto').html("<img src=''>");
}
}
And then below I have
<div data-role="page" data-add-back-btn="true">
<script type="text/javascript" >
<?php
echo "resto = ".json_encode($r).";";
?>
$( document ).on("pageinit", insertSVPhoto );
</script>
<div id='svphoto'></div>
I have to confess i'm no expert here but the way you're doing this doesn't seem quite right to me, i'd do the following:
window.onload = function () {
if(! window.device)
deviceReady()
}
document.addEventListener("deviceReady", deviceReady, false);
function deviceReady() {
$(document).delegate('#YOUR_PAGE_ID', 'pageshow', function () {
// Add your stuff here for doing the photo....
}
Again I only started using JQM a while ago but I know this works for an app i've done(and for a phonegap build too!)
EDIT: Also I would seriously consider putting everything all in one HTML document the way you've developed this is going to cause you a massive nose bleed if you try and build this as a mobile app, JQM is not designed to be used in the same way as Jquery, all of your "pages" should exist in one single html document and then use the navigation functions to move between pages.
Thanks
Marc
add data-ajax="false" or rel="external" to your links.. that should make it load properly
hello
OR
hello
Sorry if title is not too clear but I think it's about right. NEhow, what I would like to do is a bit like (well is to a certain extent) building a widget with JQuery (pref), PHP & CSS.
What I would really like to happen is for a "member" of my site to simply paste 2 lines of code in their HTML to load the widget. Something like this:
<script type="text/javascript" src="http://www.mydomain.com/script.js"></script>
Then to display the widget something like this <div id="displaywidget"></div>
OK that bit is "easy" and ok. But how do I include JQuery or "something" to generate the widget in script.js
What I mean is "displaywidget" - the ID of the widget div will be the name of a php file on my server so essentially script.js will need to load displaywidget.php into the div displaywidget.
I think I use document.getElementById('displaywidget') to get the div but how do I then "write/insert/load" displaywidget.php inside the div?
Thinking as I write "pure" java can do "most of what I want i.e. document.getElementById('displaywidget'), BUT I would prefer to also "include" Jquery.js as I would like some aspects of the widget to use JQuery. Example being the JQuery UI date function.
Sorry if I am rambling a bit but trying to think as I go along. My "real" problem is I am not too sure on "pure" javascript i.e. getting the div to display/load displaywidget.php
Suggestions please. (Oh if I am barking up the wrong tree please feel free to tell me - nicely:) )
Thanks in advance
I think I use document.getElementById('displaywidget') to get the div but how do I then "write/insert/load" displaywidget.php inside the div?
You're looking for the AJAX behaviors inside of jQuery which would make the call to the php page and then push the data into the div.
You should be loading jQuery early on in the process, right up front in your head element. Once its loaded it will be cached so no worries of its on every page. No real overhead incurred.
Once jQuery is installed you can call one of many AJAX functions related to obtaining data and popluation elements. Theres $.load(), $.ajax(), and a few others that escape me unless I go and check out their docs section.
You can do all of this without jQuery, but its more code and you have to control for browser differences.
You can load jquery into script.js, just copy and paste it after or before whatever javascript lives in script.js.
So if script.js is:
//start of file
alert('ex');
//end of file
Make it:
//start of file
alert('ex')
Copy and pasted Jquery source
//end of file
After a bit more "trawling & thought" I found this code:
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src","http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
script_tag.onload = scriptLoadHandler;
script_tag.onreadystatechange = function () { // Same thing but for IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "style.css"
});
css_link.appendTo('head');
/******* Load HTML *******/
var jsonp_url = "http://al.smeuh.org/cgi-bin/webwidget_tutorial.py?callback=?";
$.getJSON(jsonp_url, function(data) {
$('#example-widget-container').html("This data comes from another server: " + data.html);
});
});
}
})(); // We call our anonymous function immediately
writtend by Alex Marandon and found here http://alexmarandon.com/articles/web_widget_jquery/ - works a treat, exactly what I wanted, including/installing JQuery into a .js file