Getting a Module AJAX Response

867 views
Skip to first unread message

George Wilson

unread,
May 17, 2013, 8:57:27 AM5/17/13
to joomla-de...@googlegroups.com

I've managed to successfully add AJAX into a Joomla module through the following kind of process

$( "#addSomething" ).click(function() {
$.ajax({
                    type: 'POST',
                    url: "<?php echo JUri::current() . '?task=addSomething'; ?>",
                    success:function(data){
                        //On Success Be awesome
                    },
                    error:function(){
                        //Display the error message
                    }
});  
});
then retrieving it through:

$input = new JInput();
$task = $input->get('task', null, 'cmd');

before doing all the processing.

My problem I've got is returning errors in that when I'm throwing errors to date in php I've just been throwing a JApplication message e.g.

JFactory::getApplication()->enqueueMessage('Some error message', 'error');
 

However this doesn't give the AJAX any sniff of an error so any time I submit it it calls it a 'success'. Hence my problem without having a component style JSON response available.

Too many users don't have Javascript enabled for me to feel happy to just add in a straight 400 header redirect (and in any case I would like the error message to be displayed to the user). I would still like the JApplication to just enqueue an error message through PHP as a fallback when javascript is disabled.

So what would be the best way of going about throwing an error message for the AJAX and then retrieve it so that I can display it to the User (yet still retain a nice non-javascript fallback?) Is there something in the platform I've missed (note I need it to be 2.5 and 3.x compatible if at all possible).

Cheers in advance for any ideas :)

George

Donald Gilbert

unread,
May 17, 2013, 9:38:17 AM5/17/13
to joomla-de...@googlegroups.com
From what I understand, the "error:" block only get's executed if there was an error with the request, not if the request was successful and resulted in a server side error (as in, couldn't save, or something like that) http://api.jquery.com/jQuery.ajax

So, what I do to work around this is actually never use the error block (although I should provide a fallback error just in case the request fails), and do all the parsing in my success block.

I typically send a standard JSON object back as the response. If successful, it's structured like this:

{
    success: true,
    msg: 'It Worked!',
    items: [] // if items are involved or whatever
}

Or if unsuccessful, like this:

{
    success: false,
    msg: 'AARRRRGGHHH!!!'
}


Then, my success block is structured like this:

success: function(data) {
    if (data.success) {
        // do stuff
    }
}

Hope that helps.

George Wilson

unread,
May 17, 2013, 10:00:29 AM5/17/13
to joomla-de...@googlegroups.com
Hi Don!


On Friday, May 17, 2013 2:38:17 PM UTC+1, Donald Gilbert wrote:
From what I understand, the "error:" block only get's executed if there was an error with the request, not if the request was successful and resulted in a server side error (as in, couldn't save, or something like that) http://api.jquery.com/jQuery.ajax

True but in a worse case scenario you can do something yucky like:

 
So, what I do to work around this is actually never use the error block (although I should provide a fallback error just in case the request fails), and do all the parsing in my success block.

I typically send a standard JSON object back as the response. If successful, it's structured like this:
 
{
    success: true,
    msg: 'It Worked!',
    items: [] // if items are involved or whatever
}

Or if unsuccessful, like this:

{
    success: false,
    msg: 'AARRRRGGHHH!!!'
}


Then, my success block is structured like this:

success: function(data) {
    if (data.success) {
        // do stuff
    }
}

Hope that helps.

That makes sense and is basically what I was looking to do - but how does the JSON work here? Are you placing it in the url or something? That's my problem because (just as is) data is currently throwing me back the entire contents of the page (which is a lot of stuff!)

Kind Regards,
George
 
 

Donald Gilbert

unread,
May 17, 2013, 10:40:36 AM5/17/13
to joomla-de...@googlegroups.com
I'll have to put together an example. But basically I use the view.json.php coupled with &tmpl=component&format=json and then manually exit the view display method via $app->close($response);

I'm not sure if that's the BEST way, but it works. 

Sent from Mailbox for iPhone


--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.
To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

George Wilson

unread,
May 17, 2013, 11:00:36 AM5/17/13
to joomla-de...@googlegroups.com
That's for a component though right? So I'd have to have an 'invisible' component sitting there to handle the response for the module? (it seems like a huge amount of pain lol)

Kind Regards,
George
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

Donald Gilbert

unread,
May 17, 2013, 11:14:05 AM5/17/13
to joomla-de...@googlegroups.com
I have a companion module that ties in with a component to provide "favorites" functionality. So yes, it is a component. Alternatively, you could set up a plugin to capture and parse the request to determine if you're trying to access your module via AJAX and go from there. Or you could just have the url for your ajax request go directly to the mod_whatever.php and make the request that way. 

Either way, you're going to have to do a bit of extra work to accomplish the proper routing if you're not using the component approach. Maybe it's time to add a com_ajax with easy ways to hook in to a method to accomplish those common tasks.



To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.

Matt Thomas

unread,
May 17, 2013, 11:33:16 AM5/17/13
to Joomla! General Development
Ironically, we were just discussing this on Twitter - https://twitter.com/betweenbrain/status/335353425644634112. It seems that many of us are thinking along these same lines for some time. A core component to support ajax seems like a win to me. I plan to work on a prototype, when times allows, and will be more than happy to share what I come up with.

Best,

Matt Thomas
Founder betweenbrain
Phone: 203.632.9322
Twitter: @betweenbrain

Amy Stephen

unread,
May 17, 2013, 11:33:40 AM5/17/13
to joomla-de...@googlegroups.com

On Fri, May 17, 2013 at 10:14 AM, Donald Gilbert <dilber...@gmail.com> wrote:
Maybe it's time to add a com_ajax with easy ways to hook in to a method to accomplish those common tasks.

LIKE

George Wilson

unread,
May 17, 2013, 11:50:49 AM5/17/13
to joomla-de...@googlegroups.com
I noticed you were talking about plugins being used to extend your com_ajax. Would modules be able to do this out the box as well without needing package a module and plugin together (as I may as well build a optimized component than package it with a plugin that extends a generic component).

Kind Regards,
George

--
You received this message because you are subscribed to a topic in the Google Groups "Joomla! General Development" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/joomla-dev-general/9lGEsozYgnA/unsubscribe?hl=en-GB.
To unsubscribe from this group and all of its topics, send an email to joomla-dev-gene...@googlegroups.com.

Evandromar Machado

unread,
May 17, 2013, 6:47:08 PM5/17/13
to joomla-de...@googlegroups.com
I have many ajax calls on my part, but I know I can improve, joomla support to perform tasks in ajax is a dream;)

Chris Davenport

unread,
May 18, 2013, 4:52:46 AM5/18/13
to joomla-de...@googlegroups.com

You might like to look at what the Web Services Working Group are up to.

http://docs.joomla.org/Web_Services_Working_Group

Chris

Message has been deleted

Donald Gilbert

unread,
May 18, 2013, 9:20:28 AM5/18/13
to joomla-de...@googlegroups.com
It's a perfectly valid method if you know what you're doing. Sure, it's not the "best" way but it is an option. There is much more setup involved with this approach so it's not for everyone.

Sent from Mailbox for iPhone


On Sat, May 18, 2013 at 7:58 AM, Jurian Even <in...@twentronix.com> wrote:

>> Or you could just have the url for your ajax request go directly to the mod_whatever.php and make the request that way. 

This is not recommended since you'll open an other entry point and possible security hole. The component and plugin approaches are valid methods. 

Amy Stephen

unread,
May 18, 2013, 10:03:33 AM5/18/13
to joomla-de...@googlegroups.com
Don - I agree with your idea about a common com_ajax in large part because it would help get rid of all those entry points that are now in extension plugins. It should be much easier to use Ajax with Joomla.

The best approach is to use the common index.php entry point. It travels the only path that we know is secure. A little tougher to deal with it, but in the end, folks are taking better care of their users doing so.

In the end, the com_ajax solution will be easier than the plugin, so, the problem will fix itself, so to speak.

Nikolaos K. Dionysopoulos

unread,
May 18, 2013, 10:10:42 AM5/18/13
to joomla-de...@googlegroups.com
I might be wagging the tail of the dragon, but the problem stems from the fact that Joomla! distinguishes components from modules. The idea of module positions in the template and displaying them under different occasions is a very neat feature that sets our CMS apart from its competition, but the distinction of modules and components is backwards thinking. Ideally we would dispense with modules altogether and just make it possible to render components on a page. That's where the universal page model fits in, but I guess that's another story :) In an ideal world UPM would render multiple components on the page and these components would perform AJAX requests to themselves (in the same or another view). The problem would be solved.

In the reality we're facing today, however, the proper method to handle AJAX requests is through a component. But having a com_ajax component? I'd say that an architecturally incorrect solution to a valid problem. I understand the reasoning, I have built the payments callback of my subscriptions component on the same principle (guilty as charged), yet I still think it's nothing more than a temporary solution.

Nicholas K. Dionysopoulos

Amy Stephen

unread,
May 18, 2013, 10:20:55 AM5/18/13
to joomla-de...@googlegroups.com
=)

Matt Thomas

unread,
May 18, 2013, 1:05:53 PM5/18/13
to joomla-de...@googlegroups.com

I certainly can't disagree. But, how could this be achieved otherwise,  without com_ajax, if there wasn't a substantial change made to the CMS? My personal goal is to have something working in days, not months or years.

I wholeheartedly agree that UPM and/or Web Services can adress this better architectually, but this might be a baby step in that direction. If anything, it can allow for a single, shared entry point and development of a plugin type for easier implementation of ajax.

Best,

Matt Thomas
Founder betweenbrain™
Lead Developer Construct Template Development Framework
Phone: 203.632.9322
Twitter: @betweenbrain
Github: https://github.com/betweenbrain

Sent from mobile. Please excuse any typos and brevity.

Amy Stephen

unread,
May 18, 2013, 1:38:00 PM5/18/13
to joomla-de...@googlegroups.com
Go Matt! Honestly, something here is needed. Thank you.

George Wilson

unread,
May 20, 2013, 9:36:47 AM5/20/13
to joomla-de...@googlegroups.com
I agree with Nick in the short term - but definitely a component in the short term (possibly even in for 3.x)!

However just pulling this back to my initial question - just to confirm (although I was pretty sure when I posted this to be honest). The only way to gather an AJAX response (I've got the submission to work as I showed above in the mod_whatever.php file) from a module at the moment is to install a 'silent' component on the side - correct?

Kind Regards,
George
=)


To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 


--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

To post to this group, send an email to joomla-de...@googlegroups.com.
Visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-general+unsub...@googlegroups.com.

Matt Thomas

unread,
May 20, 2013, 9:43:55 AM5/20/13
to Joomla! General Development
Hi George,

I'm certainly not an expert, but they way I've seen it achieved has always implemented a component to handle the requests. But, on Twitter, Julio Pontes stated:

we don't need component for request plugin ajax. we can use a system plugin onAfterRouter for dispatch our own plugin type - https://twitter.com/juliopontes/status/335548885579726848

I'm very intrigued by that idea, and hope to explore it very soon.

Hope that helps!

PS: And, yes, I also agree that there is a better long-term solution.

Best,

Matt Thomas
Founder betweenbrain
Phone: 203.632.9322
Twitter: @betweenbrain



Amy Stephen

unread,
May 20, 2013, 10:12:25 AM5/20/13
to joomla-de...@googlegroups.com
Just backing up a minute, the point about how to do Ajax that we are debating has only to do with setting up the Request to Response application flow so that it mirrors the normal process, as much as possible.

The reason for that is the activity is then subject to the same workflow - the same HTTP filtering - the same ACL checking - the same "Server is offline" checking - the same "Must be logged on" checking - the same "Is it enabled" - that everything else is verified with.

With an Ajax request, you still want all of that stuff to happen, you just don't want the rendered output delivered in the same manner.

Are there easier ways than a component? Absolutely. What many newer devs do is crack open another hole in the wall of the application and aim the request at it. So, instead of entering index.php, the request enters this new spot. Frequently, they add a quick connection to the database, having read the data from the configuration.php file - update at will - and get out of the place.

Now, did they replicate all the code that determines the user was verified? If they have access to the data requested? if they are timed out? if the site is online? Let alone is their solution multi-db applicable, and so on.

Doubtful. And, that hole they created in the application is available to anyone, even those with less noble intent. Bad news. JED shouldn't even list these, IMO, and we should discourage this.

Now, Julian's onAfterInitialise approach is better in that the request has traveled a good share of the normal route, but, the Request is still jumping out before the Route, Dispatch, Render, etc., triggered events. It really is always better to train the request to travel the same path, regardless of the protocol.

Now, a Component does not have to have a visible interface to it. In fact, it could be as simple as the entry point file, no MVC. The trick will be - what is it supposed to do once it gets there? The more reuse you can get by executing existing functions, the better. But, you'll have to figure out how to map the request to existing functionality. That might be a good use of plugins. (And a plugin can render a Module, in George's case). If the URL has the name of the plugin - the components job may be as simple as firing the plugin and it's done.


--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to joomla-dev-gene...@googlegroups.com.

Matt Thomas

unread,
May 20, 2013, 10:26:26 AM5/20/13
to Joomla! General Development
Amy,

As always, well said. These are all excellent points to consider.

Those last fourteen words sums up the first milestone I have in mind for something like this. Simple, efficient, and lets the plugin add whatever business logic is desired.

Best,

Matt Thomas
Founder betweenbrain
Phone: 203.632.9322
Twitter: @betweenbrain



Nikolaos K. Dionysopoulos

unread,
May 20, 2013, 11:07:44 AM5/20/13
to joomla-de...@googlegroups.com
Amy,

in so many words that's what I said I've implemented in my own software but I consider is architecturally incorrect. But, yeah, if the objective is not to let people open holes in the wall that's a good short term solution.

Nicholas K. Dionysopoulos

George Wilson

unread,
May 21, 2013, 8:36:15 AM5/21/13
to joomla-de...@googlegroups.com
Now, a Component does not have to have a visible interface to it. In fact, it could be as simple as the entry point file, no MVC. The trick will be - what is it supposed to do once it gets there? The more reuse you can get by executing existing functions, the better. But, you'll have to figure out how to map the request to existing functionality. That might be a good use of plugins. (And a plugin can render a Module, in George's case). If the URL has the name of the plugin - the components job may be as simple as firing the plugin and it's done. 

So the best scenario is that I need a 'invisi' component to call a plugin to do the AJAX to render my module? Because that seems pretty horrific (in terms of package sizes/loading times if nothing else)

Completely agree about the opening holes. I'm not defining JXEC or anything like that in the example I provided above - although the processing does involve adding the AJAX variables into the database (filtered through JInput etc.)

Kind Regards,
George 

Matt Thomas

unread,
May 21, 2013, 9:09:49 AM5/21/13
to Joomla! General Development

George,

In your specific case, you wouldn't need a plugin and component, as your specialized ajax component could have all of the necessary logic needed.

The plugin is related to using a generic, core ajax interface (which doesn't exist yet). My apologies if that confused anything. I do have a working prototype for that, and will start a new thread once the code is in a sufficient state to where it's worth discussing. It is on GitHub if you'd like to take a look at it, or even fork it for your use.

Best,

Matt Thomas
Founder betweenbrain™
Lead Developer Construct Template Development Framework
Phone: 203.632.9322
Twitter: @betweenbrain
Github: https://github.com/betweenbrain

Composed and delivered courtesy of Nexus 7.

--

Amy Stephen

unread,
May 21, 2013, 2:04:05 PM5/21/13
to joomla-de...@googlegroups.com


On Tuesday, May 21, 2013 7:36:15 AM UTC-5, George Wilson wrote:
Now, a Component does not have to have a visible interface to it. In fact, it could be as simple as the entry point file, no MVC. The trick will be - what is it supposed to do once it gets there? The more reuse you can get by executing existing functions, the better. But, you'll have to figure out how to map the request to existing functionality. That might be a good use of plugins. (And a plugin can render a Module, in George's case). If the URL has the name of the plugin - the components job may be as simple as firing the plugin and it's done. 

So the best scenario is that I need a 'invisi' component to call a plugin to do the AJAX to render my module? Because that seems pretty horrific (in terms of package sizes/loading times if nothing else)

Think of it this way, in Joomla an HTTP Request is implemented by dispatching a Component which fulfills the HTTP Request. The entire Joomla architecture is developed on that premise. I would be surprised to see any significant time issues using that approach.

Matt's approach for a component that fires a named plugin is quite useful, simple/elegant, supports the architecture, and would hopefully be a good inclusion for core someday. I agree that it's a bit much for everyone to build it when one can be used by everyone. That should help with packaging.
 

Anibal

unread,
May 23, 2013, 8:27:30 AM5/23/13
to joomla-de...@googlegroups.com
Hi Matt,

I've been working to port the J3 Installer from the current Mootools to jQuery. 

In the migration, I'm looking to integrate a Javascript Dependecy Manager (RequireJS), and Backbone (Javascript).

It's not ready yet, but you can grab some ideas.

For example, the JS model calls the backend controller:


define([ "backbone" ],
function(Backbone) {
"use strict";

// To define the Language access
var Language = Backbone.Model.extend({

url : function() {

return base + '?task=setup.setlanguage&format=json';
}
});

return Language;

});

In the controller:


...
// Get the posted values from the request and validate them.
$data = $inputJson->get('jform', array(), 'array');
$return = $model->validate($data, 'preinstall');
...
// Redirect to the page.
$r->view = $this->input->getWord('view', 'site');
$this->sendResponse($r);

In the Js View:

....
var processSiteResponse = function(r) {
var messages = r.get('messages'),
lang = jQuery('html').attr('lang'),
view = r.get('data').view;

Joomla.replaceTokens(r.get('token'));
if (messages) {
Joomla.renderMessages(messages);
}

if (lang.toLowerCase() === r.get('lang').toLowerCase()) {
return true;
}
else {
window.location = base + '?view=' + view;
}
};
...

Regards,
Anibal

 





Matt Thomas

unread,
May 24, 2013, 6:32:10 AM5/24/13
to Joomla! General Development
Hi Anibal,

That's very cool. I've actually been quietly watching your work. I'll take a look and see what I can understand <grin> and what ideas it may inspire. Thanks!

Best,

Matt Thomas
Founder betweenbrain
Phone: 203.632.9322
Twitter: @betweenbrain



Nick Savov

unread,
May 24, 2013, 1:58:24 PM5/24/13
to joomla-de...@googlegroups.com
Very nice, Anibal! It would be great to get RequireJS and Backbone in! :)

Cheers,
Nick
Reply all
Reply to author
Forward
0 new messages