News:

Join the Facebook Fan Page.

Main Menu

SMF + AJAX

Started by marcinikj, January 20, 2009, 11:06:19 AM

Previous topic - Next topic

marcinikj

Hi all.  I am trying to use a bit of AJAX with a mod I am working on and I have problems.  Specifically I'm trying to use AJAX to run a script and have it output the results to a footer div I have setup in my template.

I've approached this problem from two angles, using a publicly available AJAX framework and using SMF's implementation.

The AJAX framework I am using does work with SMF, but only if I pass the URL with the action/subaction query string, which ends up loading the entire SMF site into my target div.  Is there a way to request a page using a 3rd party AJAX tool and still stay inside the SMF environment?  The page I am executing needs access to SMF variables and functions . . . perhaps there is an example of this I can refer to?  I spent quite a bit of time searching for this and did not have much luck.

The other angle was my "attempt" to use SMF's AJAX implementation.  I'll be honest, I am finding it hard to understand.   My main reference was this thread.  I have managed to use a barebones method similiar to the one described in the thread to execute a page via AJAX . . . but I cannot figure out how to put the results of the AJAX request into my footer div.  This is what I have so far:

my javascript:
if (window.XMLHttpRequest)
{
document.getElementById('update_footer').innerHTML = '<img src="Themes/default/images/bnt/ajax-loader.gif" />';
getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + "action=blacknova;sa=scheduler;xml", UpdateFooter());
return false;
}


inside my main function:
function Scheduler()
{
global $context, $boarddir, $txt;

require_once($boarddir . '/bnt/scheduler.php');

// Run the BNT Scheduler page
if (isset($_REQUEST['xml']))
$context['sub_template'] = 'bnt_scheduler';
}


And I have an empty function inside Xml.template.php . . . because I don't really know what to do with it :)  I'm trying to look at other implementations of this inside SMF as I go along, but if anyone could help out, well that would be great :)

marcinikj

Well, I came up with a solution to my own question.  I ended up using the Prototype framework for my ajax calls.  When I need to make an ajax call, I call the Prototype ajax object, using a properly formatted SMF query string with ";xml" at the end.  My main smf function looks for xml queries before doing anything else to ensure they are handled properly.  By "properly", as if any of this is proper :), I mean the code loads the language file, loads only the xml template using and empty function defined in xml.template and then initiates the action defined in the query string.  Output from the function is then handled/directed using Prototype.

So compared to the code I posted above, this is what I have now.

Here is a small example of what I am trying to describe.  Anywhere I need an AJAX call, it would look something like this:

new Ajax.Updater("bnt_footer", smf_prepareScriptUrl(smf_scripturl) + "action=blacknova;sa=scheduler;xml", { method: "get", evalScripts: true });

Bearing in mind I have evalScripts set to true as I pass a lot of javascript around.

When my main function runs, called by the "action", I have the xml "handler" at the top of the code ready to catch the xml calls:

if (isset($_REQUEST['xml']))
{
// Load the BlackNova language file.
loadLanguage('BlackNova');

//Load standard empty template for ajax calls
$context['sub_template'] = 'bnt_scheduler';

require_once($boarddir . '/bnt/scheduler.php');

return;
}


I have that setup just for one script, but it should be pretty easy to modify that to make it do whatever you want.

And then the empty function in Xml.template, where the function names matches the sub-action name from the query string.

function template_bnt_scheduler()
{
}


And it works, no errors . . . inside the coding guidelines?  Not so sure.

SoLoGHoST

Yet, this still seems to be a problem in SMF.  You can't perform simple jQuery $.ajax calls without a 403 Forbidden Error loading resource problem for the url!  And that is with xml in the url.  If you take xml out of the url, the entire site loads instead.  Hopefully they have better support for this in SMF 2.1.

Arantor

Congratulations, you have successfully bumped a topic that's almost 5 years old.

I get the impression the problem is not with SMF but the way you're trying to do it... SMF 2.1 makes use of $ just fine in the places it uses it (which, for backwards compatibility reasons, is sparingly)... but it makes use of $.load to AJAXively get HTML content just fine.

But without seeing what you're trying to do (bear in mind, the above was for probably 1.1.x, or perhaps 2.0 beta 4 judging by the age of it and the fact it wasn't specified), it's very hard to give advice.
Holder of controversial views, all of which my own.


SoLoGHoST

Bumping a topic that was old is simply a result of a search.  Don't hate the playa, hate the game!

I have a form on a page, that when submitted should prepend some HTML data to the #success_msg element, however, this is not happening, and is giving me 403 error.  If I remove xml from the url, I get the entire SMF page loaded in there instead.

$context['html_headers'] .= '
<script type="text/javascript"><!-- // --><![CDATA[
if (!String.prototype.trim) {
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, "");};
}
$(function() {
$("#comment_submit").click(function() {
var rating = $("#rating").val();
var comment = $("#comment").val();
var dataString = "comment=" + comment + ";rating=" + rating + ";lang_name=' . $context['dp_downloads']['lang_name'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '";

if(comment.trim() == "" || rating.trim() == "")
{
alert("Please fill out all areas.");
}
else
{
$.ajax({
type: "POST",
url: smf_prepareScriptUrl(smf_scripturl) + "action=downloads;area=packs;sa=addcomment;xml",
data: dataString,
cache: false,
success: function(html){
$("#rating").val("");
$("#comment").val("");
$("#success_msg").prepend(html);
}
});
}
return false;
});
});
// ]]></script>';


But I suppose you'll most likely need more code to see the full problem huh?

The main problem is this works perfectly fine in an actual environment without SMF, but with SMF, there are problems.

Arantor

So look at the network tab in your browser's inspector and see exactly what request is being made, and exactly what the page's response is.

Of course, you don't actually need to invoke jQuery just to do AJAX... SMF was doing AJAX before jQuery even existed. getXmlDocument exists for a reason, you know (in both 1.1 and 2.0), or in your case sendXmlDocument to perform a post.

That, and the fact that you're using ; as the arg separator in the post body (as opposed to &) which may not work properly on various configurations.
Holder of controversial views, all of which my own.


SoLoGHoST

Ahhhh, yes, you got it Arantor, it needed & in the dataString variable for the separators.  Got used to SMF's way of handling it.  Thanks.

I prefer doing it the jQuery way nowadays.

Arantor

That's fine but there's really no need to load jQuery just for this. If you have to load a double-digits KB worth of file because you don't want to use the methods already available to you, that's kinda lazy and uses bandwidth needlessly.
Holder of controversial views, all of which my own.


SoLoGHoST

SMF 2.1 will load jQuery on every page correct?  So who's being lazy now?

It's not a matter of being lazy to tell you the truth.  And loading up a jquery.min.js file, that most likely is already cached in the users browser and from a CDN isn't any problem that I can see.

Arantor

You can't blame me for the choices made before I got here.

Loading a large library - cached or not - just to do something occasional, that's lazy. Loading a large library - cached or not - when you're going to use its code every page, that's not lazy.

Plus it means all the issues that modders have in trying to load jQuery also go away.
Holder of controversial views, all of which my own.


SoLoGHoST

First, off it is not a large library.  Most images that load are bigger than jQuery at it's min state.  2nd, this shouldn't be a problem once SMF 2.1 is released and jQuery loads on every single page by default.  3rd, Thanks for your help with this and have a nice day.

Advertisement: