I’ve come at this a few different ways and there doesn’t seem to be any documentation or forum threads speaking to the proper, best practices method of implementing a Control Panel-side AJAX post. Here are my thoughts, would love to hear back from anyone on this.
Option 1: Action ID
One of the most obvious choices would be to register an Action ID for your module to post to. Quick, clean and straightforward (tho very little documentation exists on them in general). the biggest downfall to this method, however, is MSM sites. I’ve noticed when you need to run specific database type methods on one site or another, the Control Panel isn’t always too kind when passing the site_id (depending on which site you’re logged into, your session/cookie preferences, proper site_short_name configuration, renamed index.php file, various installed extensions such as Freebie, etc). This can cause some potential issues.
Option 2: MCP Method
I’ve experimented with using a Control Panel url (e.g. &C=addons_modules&M=show_module_cp&module=module_name&method=ajax_function) to process the AJAX post in EE1, which works well if you flush the output buffer and exit() after your function, but this doesn’t work in EE2. EE2 seems to intercept the url and move any post data into GET parameters and redirect you to the CP homepage. This appears to be JavaScript/jQuery functionality intercepting the call, so I tried to use noConflict namespacing but to no avail. I saw a “process_” prefix thread in reference to Accessories, but nothing similar for Modules.
Option 3: You tell me
Not sure what else to try. Perhaps I’ve missed some memo along the way and I’m hoping someone can point me in the right direction.
Option 2 works for me if I do this in my MCP method
function ajax_function() {
return $this->EE->output->send_ajax_response($array);
}And my ajax call:
$.getJSON(EE.BASE+"&C=addons_modules&M=show_module_cp&module=module_name&method=ajax_function", {}, function(data) {
//whatever
});The only reliable way we found that is using ACT. The only problem we noticed is when posting file uploads to the ACT URL while the system is OFF.
Using an Module Page as the AJAX url doesn’t work if the user does not have access (permission) to the Module.
Would love to hear other thoughts.
I finally found another way to do this, using methods in the MCP. The problem i had before was having the POST redirected while GET would go through (not what i needed however). Apparently, the system prevents any POST data from being submitted in the CP unless it’s using Secure Forms.
So by targeting the method and adding an &XID; query string with the value from XID_SECURE_HASH, it would allow processing. I’m still testing and looking for any pitfalls here (member permissions is actually a bonus in this case), but it looks promising.
Well, it doesn’t matter what I use, EE just returns the entire control page instead of my AJAX response. As long as I just use GET calls, the MCP option works fine. As soon as I switch to POST calls, everything fails. Also tried adding the XID parameter in the query string but no happy moments there. Even worse: if I properly register an action and I use the ?ACT=xx way of calling EE, I still end up with a control page instead of an AJAX response. Switch to GET and all is fine, but I just don’t want to use GET calls due to the amount of actual data that will be send around.
I’d love to see how Jack got his code working because I’m having a very hard time getting something that seems so simple to actually work :(
Another thought/question: isn’t the XID hash supposed to change everytime someone performs an action? If you add the XID hash to JavaScript code that does the AJAX call, isn’t it sort of hardcoded, resulting in even more problems?
And something else to conclude: it’s nice to see that EE finally incorporates stuff like jQuery but would it perhaps be an idea to actually create some documentation on using AJAX stuff with EE2 and the control panel? This current path of trial and error sure isn’t the most effective…
Got it. Interpreted Jack’s suggestion wrong, fixed that and now it is working. For those who have the same problem, the following should work:
First define a constant (not actually necessary but keeps things a bit more readable)
define('AJAX_URL', html_entity_decode(BASE).'&C=addons_modules&M=show_module_cp&module=modulename');Then construct a piece of JavaScript code to perform the actual call:
function connectToFeedInputType()
{
$('#feedUrl').blur(function()
{
// Get the uri that was submitted
var url = $('#feedUrl').attr('value');
$.ajax({ url: '<?php echo AJAX_URL.'&method=check_uri'; ?>',
type:"POST",
data: { XID:"<?php echo XID_SECURE_HASH; ?>", uri:url },
success: function(response) { handleFeed(response); } });
});
}The thing that fixed it is as Jack stated but which I did wrong at first. You need to add the XID variable to the actual javascript data array, not to the action URL. In other words, it needs to be “POST-ed”.
Hope this helps other people.
p.s.: still not sure about the XID changing. Any pointers would be appreciated.
still not sure about the XID changing. Any pointers would be appreciated.
Glad you got it working! Apologies if I was unclear. As far as the XID changing – the TTL is set for 4 hours on a specific ID (line 30 of libraries/CP.php), so unless your users keep interacting with the AJAX without refreshing the page or doing anything else for a REALLY long time, you should be safe.
Just wanted to point out that if you are going straight Javascript the XID hash is available as EE.XID, so this works:data: { XID:EE.XID }
Beautiful. This is allowing me to perform repeated AJAX calls that were failing before, even when I passed back a new XID in the AJAX response (XID_SECURE_HASH) and used that. Thanks!
Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.