I am trying to get some JSON from an external url. This works fine with the twitter request in the example in the dojo documentation.
I guess the problem comes with the callback function, as I'm not sure if I need one and where to place it.
The JSON looks like:
{"upcoming":[]}
and that's how I call it:
function getJSON(){
// Look up the node we'll stick the text under.
var targetNode = dojo.byId("results");
// The parameters to pass to xhrGet, the url, how to handle it, and the callbacks.
var jsonpArgs = {
url: url,
load: function(data){
console.log(data);
// Set the data from the search into the viewbox in nicely formatted JSON
targetNode.innerHTML = "<pre>" + dojo.toJson(data, true) + "</pre>";
},
error: function(error){
targetNode.innerHTML = "An unexpected error occurred: " + error;
}
};
test = dojo.io.script.get(jsonpArgs);
}
dojo.ready(getJSON);
ant that's the output I get:
JSON:
{
"returnValue": true,
"timeStamp": 1332858447300,
"eventPhase": 0,
"target": null,
"defaultPrevented": false,
"srcElement": null,
"type": "load",
"cancelable": false,
"currentTarget": null,
"bubbles": false,
"cancelBubble": false
}
Are you referring to this statement in your example?
// The parameters to pass to xhrGet, the url, how to handle it, and the callbacks.
If so, the "callbacks" are the load and error functions.
Related
What CGI API can you use to replace $.getJSON() with $(ajax)...POST. GET is used for everything (ie: GET, PUT, POST, DELETE) when using CGIDEV2 in an IBM i environment? I dont want to pass my parameters the traditiontal way eg: $('[name="EMAIL"]').val() rather I want to pass JSON object string eg: {"form" : [{ "email": "yardpenalty#yahoo.com"}]}.
We are able to perform PostToGet callbacks using the $.getJSON() using CGIDEV2 but I can't use $.ajax in its fullest. Here is what we do now which is all GET requests
PHP/JS:
// load all parameters
data = 'INSTANCE=<?echo trim($PATH_INSTANCE)?>' +
'&FUNCTION=<?echo urlencode(trim($FUNCTIONCODE))?>' +
'&USER=' + $('[name="USER"]').val() +
'&CONTACT=' + w$('[name="CONTACT"]').val() +
'&EMAIL=' + $("input[name='EMAIL']").val() +
'&MSG=' + $('[name="MSG"]').val() +
'&TYPE=' + $('[name="TYPE"]').val();
// Call the RPG REST JSONP program
$.getJSON( "http://www.domain.com:8082/rest/RPGLEPGM?callback=?",data )
.done(function( json ) { ... }
//Domain is actually
http://www.domain.com:8081
RPGLE PGM:
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // callback
p#Function = cgiParseGet('FUNCTION');
Endsr;
But I want to be able to use the other AJAX methods doing various actions such as simply updating records .post()/.ajax() on the fly or simple .get() ajax calls without creating a callback. I don't want to have to use getJSON every time I use ajax not to mention its bad practice to POST on a GET, but from what I understand the .getJSON() provides JSONP functionality while the others do not by default.
EDIT: We do have our ajax RPGLE PGMS on a different port than the actual website so JSONP is necessary and the client knows its JSONP because we pass the callback function back.
Since our ajax RPGLE PGM CALLS are on a different port than the PHP requests (think different domains on a host server) this qualifies as cross-domain requests; therefore, we must pass the &callback=? function/wrapper back to the client using JSONP (or Cors if security is an issue). I found a really good piece on JSONP here on SO and this is exactly what this ajax call is using.
RPGLE the jQuery ajax requests are made possible by using some sort of CGI API accessible on your OS/400 - IBM i Web environment. When calling (CALLB or CALLP) an RPGLE PGM using ajax we are actually making a procedural call, but when using global temps we are actually making a SQL Procedural CALL which is way more expensive in terms of resources which is why Web Services are becoming more popular.
It is more practical to not only pass javascript objects from the form data on request but to return JSON objects with Ajax requests than storing global temp data in the db2 environment and processing it into a PHP array on the response.
By processing the JSON string on the client instead of using both server memory and drive space and disk read/writes necessary for PHP arrays and global temp files we are really able to take advantage of more modern web design practices.
Here is a working example of using $.ajax/PHP/RPGLE correctly without using $.getJSON():
<script>
$(document).ready(function(){
GetEmail("#email", '<?php echo trim($USER)?>', '<?php echo $PATH_INSTANCE?>');
FormValidation();
});
function FormValidation(){
//Variables created without the keyword var, are always global, even if they are created inside a function.
var form = $('#<?echo $PAGEID?>');
var FormError = $('.alert-danger',form);
var success = $('.alert-success',form);
form.validate({
focusInvalid: false, // do not focus the last invalid input
onkeyup: false,
ignore: ".ignore", //required for hidden input validation ie: hiddenRecaptcha
rules:{
"TYPE": {
required: true,
},
"MSG": {
required: true,
rangelength:[40,1000]
},
"CONTACT": {
required: {
depends: "#newuser:checked"
}
},
"EMAIL": {
required: true,
email: {
depends: function() {
if(!$("#newuser:checked"))
return true;
else
return false;
}
},
HTH_TelephoneEmail: {
depends: function() {
if($("#newuser:checked"))
return true;
else
return false;
}
}
},
hiddenRecaptcha: {
required: function () {
if (grecaptcha.getResponse() == '') {
return true;
} else {
return false;
}
}
}
},
messages: { // custom messages for form validation input
"TYPE": {
required: 'Please select an option as it pertains to your inquiry'
},
"MSG": {
required: 'Please provide some content as it pertains to your inquiry'
},
"CONTACT": {
required: "Please enter a contact person or company"
},
hiddenRecaptcha: {
required: function() {
$(".g-recaptcha:first").tooltip("enable").tooltip("show");
}
}
},
showErrors: function(errorMap, errorList) {
// Clean up any tooltips for valid elements
$.each(this.validElements(), function (index, element) {
element = $(element);
NoError_ToolTip(element);
});
// Create new tooltips for invalid elements
$.each(errorList, function (index, error) {
element = $(error.element);
message = error.message;
Error_ToolTip(element,message);
});
},
invalidHandler: function (event, validator) { //display error alert on form submit
success.hide();
$(document).scrollTop( $(".form-body").offset().top );
},
submitHandler: function () {
Submit_Complete();
}
});
function Submit_Complete(){
var obj = form.serializeObject();
console.log(obj);
$(".g-recaptcha:first").tooltip("disable").tooltip("hide");
$('.shell').html('<div class="loading"><span class="caption">Sending...</span><img src="/images/loading.gif" alt="loading"></div>');
$.ajax({
type: "POST",
url: "http://www.domain.com:8082/rest/RPGPGM2?callback=?",
data: obj,
//contentType: "application/json; charset=utf-8",
dataType: "jsonp"}).
done(function(data){
$(".shell").html('<label class="msg xs-small">' + data["MESSAGE"] + '</label><br><br><br><br><br><br><br><br><br>'+
'<div class="caption right">'+
'Home <i class="fa fa-home"></i>'+
'</div>');
}).
fail(function(){
$(".shell").html("<label class='msg xs-small'>We're Sorry!<br><br><br><br><span class='text-danger'>Unfortunately this inquiry cannot be processed at this time." +
"<br>Please try again at a later time or give us a call at:</span><br><br>+1.800.406.1291</label><br><br><br><br><br><br><br><br><br>"+
'<div class="caption right">'+
'Home <i class="fa fa-home"></i>'+
'</div>');
});
}
}
/**
* Serializes form data/objects. This actually creates a javascript object which our CGIAPI is capable of handling!
*
*/
$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
var $value = '';
$.each(a, function() {
if (o[this.name]) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
</script>
We can make RESTful calls by using some type of CGI API such as QtmhRdStin or by creating Web Services. This solution is of the former.
Here is a list of the basic CGI APIs:
RPGLE PGM:
// $Incoming: Test and load the incoming parameters
Begsr $Incoming;
cgiPostToGet(); // Convert POST to GET
callback = cgiParseGet('callback'); // never delete - unique key for the request
p#UserID = cgiParseGet('USER');
if (%scan(#lf:p#UserID) <> 0);
p#UserID = *blanks;
endif;
p#Instance = cgiParseGet('INSTANCE');
if (%scan(#lf:p#Instance) <> 0);
p#Instance = *blanks;
endif;
p#Function = cgiParseGet('FUNCTION');
p#Contact = cgiParseGet('CONTACT');
if (%scan(#lf:p#Contact) <> 0);
p#Contact = *blanks;
endif;
p#Email = cgiParseGet('EMAIL');
p#Msg = cgiParseGet('MSG');
p#Related = cgiParseGet('TYPE');
exsr $InzSr;
Endsr;
Begsr $Outgoing;
// Tell Consumer that a JSON string will be sent
ajx_data = 'Content-type: text/javascript' + CRLF + CRLF; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = %trim(callback) + '(' + %char(LBrace); // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);// DO NOT CHANGE THIS LINE!!!
ajx_data = '"MESSAGE":"' + %trim(p#message) + '"';
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err);
// load the final right brace to complete the JSON string
ajx_data = %char(RBrace) + ');'; // DO NOT CHANGE THIS LINE!!!
QtmhWrStout(ajx_data: %len(%trimr(ajx_data)): ajx_err); // DO NOT CHANGE THIS LINE!!!
Endsr;
****NOTE****
If we can't serialize our form directly we must build a javascript object like this:
var obj = {USER : localProfile,
INSTANCE : "HTHACKNEY",
PAGE : $('select[name="PAGE"]').val(),
TITLE : $("input[name='TITLE']").val(),
HTML : html,
STARTDATE : $("input[name='STARTDATE']").val(),
ENDDATE : $("input[name='ENDDATE']").val(),
ARCHIVE : $("input[name='ARCHIVE']").val(),
ACTIVE : $("input[name='ACTIVE']").val(),
URGENT : $("input[name='URGENT']").val(),
AUTHLST : authStr};
$.ajax({
type: "POST",
url: "http://webservices.hthackney.com/web054S?callback=?",
data: data,
dataType:'jsonp'
}).done({ //do something on success });
Unfortunately you can POST using JSONP but you cannot read the header response.
I FINALLY found the solution to executing both db2 and ajax requests on a single DOMAIN.
SOLUTION HERE
If you need to perform AJAX requests on the SAME DOMAIN in an IBMi environment w/apache/PASE you need the following ScriptAlias and two directives in your http.conf file:
ScriptAliasMatch /rest/([0-9a-zA-Z]+$) /qsys.lib/rest.lib/$1.pgm
<Directory /qsys.lib/obj.lib/>
order allow,deny
allow from all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI +Includes -Indexes +MultiViews
CGIConvMode %%MIXED/MIXED%%
</Directory>
<Directory /qsys.lib/rest.lib>
CGIConvMode %%EBCDIC/EBCDIC%%
Order Allow,Deny
Allow From all
Header Always Set Access-Control-Allow-Origin *
Options +ExecCGI -FollowSymLinks -SymLinksIfOwnerMatch +Includes -IncludesNoExec -Indexes -MultiViews
</Directory>
rest.lib member is where all of the ajax rpgle pgms reside.
obj.lib is where all CALL WEBXXX for db2 calls in PHP are located.
Now you are able to call AJAX requests under the /rest/$1PGM pattern.
For instance:
$.ajax({
type: "POST",
url: "http://www.domain.com/rest/WEB055S",
data: obj,
contentType: "application/json; charset=utf-8"
).
done(function(data){
$("#signupForm .loading").addClass("hidden");
//Successful Submit!
if(typeof data.MESSAGE != "undefined"){
clicked = 0;
$("#ok_msg").html(data.MESSAGE).show();
}
else{//ERROR
//console.log(data.ERROR);
$("#attendee #hth_err_msg").html(data.ERROR).show();
$('.add-attendee').addClass('hidden');
$('.edit-attendee').addClass('hidden');
}
}).
fail(function(){
$("#hth_err_msg").html("We're sorry, you're request cannot be processed at this time. It is likely the corporate system is under maintenance.").show();
});
From a JSON stored in a variable I can get the name of the current id from a router function called show: function(id). However, when I fetch collection from an URL instead of using a JSON variable I get an undefined TypeError.
console.log(this.collection.get(id).get('name'));
What I have seen is that when I use a JSON variable the show function works fine, but when I fetch from URL, show function executes after fetch succeed.
What I am doing wrong? Why fetching from URL gets undefined? How can I make it work?
The following code is fictional, it only shows the relevant part of my code. See the two cases at the end of the code block.
jsFiddle here
// Data 1 with variable
var heroes = [
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
// Data 2 from url: http://example.com/heroes.json
[
{"id": "1", "name": "Batman"},
{"id": "2", "name": "Superman"},
];
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
// I use two shows to graphic this example
routes: {
'': 'index',
':id': 'show'
},
initialize: function(options) {
this.collection = options.collection;
this.collection.fetch();
// this.collection.fetch({async:false}); this fixes my problem, but I heard it is a bad practice
},
index: function() {
},
show: function(id) {
console.log(this.collection.get(id).get('name'));
// Case #1: When Collection loads from a Variable
// id 1 returns: 'Batman'
// Case #2: When Collection fetchs from URL, id 1 returns:
// TypeError: this.collection.get(...) is undefined
}
});
// Case #1: collection loads JSON from a variable
var heroesCollection = new HeroesCollection(heroes);
// Case #2: collection loads JSON with fetch in router's initialize
// var heroesCollection = new HeroesCollection();
var heroesRouter = new HeroesRouter({collection: heroesCollection});
How about this? It's been awhile, but this seems like a better approach to what you are trying to achieve. The basic concept is that once you navigate to your show route, it will execute show. This method will create a new, empty collection, and then fetch the data for it. Along with that, we pass in a success method (as François illustrated) which will execute when the request is finished with the JSON (which creates a collection of Heros).
I believe the reason you were running into the issue with the remote data is that you were trying to access this.collection before it was populated with data from the request.
You have to remember the request is asynchronous, which mean code execution continues while the request is processing.
HeroesCollection = Backbone.Collection.extend({
model: HeroesModel,
url: 'http://example.com/heroes.json'
});
HeroesRouter = Backbone.Router.extend({
routes: {
'': 'index',
':id': 'show'
},
index: function() {
},
show: function(id) {
this.herosCollection = new HerosCollection();
this.herosCollection.fetch({
success: function(collection, response, options) {
console.log(this.get(id).get('name'));
}
});
}
});
you need to trigger the router 'show' function when the collection has ended to load.
this.collection.fetch({async:false}); fixes your problem because the whole javascript code is waiting (async:false) the ajax call to be ended before going further.
The other and best solution is to wait that your collection is fetched before you try to use the results.
Basically:
MyCollection.fetch({
success: function(model, reponse) {
// do wtv you want with the result here or trigger router show method...
}
});
So, I'm using FineUploader 3.3 within a MVC 4 application, and this is a very cool plugin, well worth the nominal cost. Now, I just need to get it working correctly.
I'm pretty new to MVC and absolutely new to passing back JSON, so I need some help getting this to work. Here's what I'm using, all within doc.ready.
var manualuploader = $('#files-upload').fineUploader({
request:
{
endpoint: '#Url.Action("UploadFile", "Survey")',
customHeaders: { Accept: 'application/json' },
params: {
//variables are populated outside of this code snippet
surveyInstanceId: (function () { return instance; }),
surveyItemResultId: (function () { return surveyItemResultId; }),
itemId: (function () { return itemId; }),
imageLoopCounter: (function () { return counter++; })
},
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'bmp']
},
multiple: true,
text: {
uploadButton: '<i class="icon-plus icon-white"></i>Drop or Select Files'
},
callbacks: {
onComplete: function(id, fileName, responseJSON) {
alert("Success: " + responseJSON.success);
if (responseJSON.success) {
$('#files-upload').append('<img src="img/success.jpg" alt="' + fileName + '">');
}
}
}
}
EDIT: I had been using Internet Explorer 9, then switched to Chrome, Firefox and I can upload just fine. What's required for IE9? Validation doesn't work, regardless of browser.
Endpoint fires, and file/parameters are populated, so this is all good! Validation doesn't stop a user from selecting something outside of this list, but I can work with this for the time being. I can successfully save and do what I need to do with my upload, minus getting the OnComplete to fire. Actually, in IE, I get an OPEN/SAVE dialog with what I have currently.
Question: Are the function parameters in onComplete (id, filename, responseJSON) getting populated by the return or on the way out? I'm just confused about this. Does my JSON have to have these parameters in it, and populated?
I don't do this (populate those parameters), and my output method in C# returns JsonResult looking like this, just returning 'success' (if appropriate):
return Json(new { success = true });
Do I need to add more? This line is after the saving takes place, and all I want to do is tell the user all is good or not. Does the success property in my JSON match up with the responseJSON.success?
What am I missing, or have wrong?
Addressing the items in your question:
Regarding restrictions inside of the "select files" dialog, you must also set the acceptFiles validation option. See the validation option section in the readme for more details.
Your validation option property in the wrong place. It should not be under the request property/option. The same is true for your text, multiple, and callbacks options/properties. Also, you are not setting your callbacks correctly for the jQuery plug-in.
The open/save dialog in IE is caused by your server not returning a response with the correct "Content-Type" header. Your response's Content-Type should be "text/plain". See the server-side readme for more details.
Anything your server returns in it's response will be parsed by Fine Uploader using JSON.parse when handling the response client-side. The result of invoking JSON.parse on your server's response will be passed as the responseJSON parameter to your onComplete callback handler. If you want to pass specific information from your server to your client-side code, such as some text you may want to display client-side, the new name of the uploaded file, etc, you can do so by adding appropriate properties to your server response. This data will then be made available to you in your onComplete handler. If you don't have any need for this, you can simply return the "success" response you are currently returning. The server-side readme, which I have linked to, provides more information about all of this.
To clarify what I have said in #2, your code should look like this:
$('#files-upload').fineUploader({
request: {
endpoint: '#Url.Action("UploadFile", "Survey")',
customHeaders: { Accept: 'application/json' },
params: {
//variables are populated outside of this code snippet
surveyInstanceId: (function () { return instance; }),
surveyItemResultId: (function () { return surveyItemResultId; }),
itemId: (function () { return itemId; }),
imageLoopCounter: (function () { return counter++; })
}
},
validation: {
allowedExtensions: ['jpeg', 'jpg', 'gif', 'png', 'bmp']
},
text: {
uploadButton: '<i class="icon-plus icon-white"></i>Drop or Select Files'
}
})
.on('complete', function(event, id, fileName, responseJSON) {
alert("Success: " + responseJSON.success);
if (responseJSON.success) {
$('#files-upload').append('<img src="img/success.jpg" alt="' + fileName + '">');
}
});
The contents of my dataHelper.js file:
define(["dojo/_base/declare", "dojo/dom", "dojo/_base/xhr", "dojo/json"],
function(declare, dom, xhr, json){
return {
getJSON: function(){
xhr.get({
url: "../../cpuusage.json",
handleAs: "json",
load: function(jsonData){
return jsonData;
},
error: function() {
}
});
}
};
});
I'm trying to run this from my index.html as follows:
var chartData = dataHelper.getJSON();
I think I have several issues. First of all, I'm not sure my module and the getJSON function is defined correctly. Secondly I get errors on my console:
TypeError: this.source is undefined
[Break On This Error]
= [],
dojo.js (line 362)
SyntaxError: missing : after property id
},
dojo.js (line 330)
SyntaxError: missing : after property id
},
dojo.js (line 330)
SyntaxError: missing : after property id
},
All I want to achieve first is load the json data into the chartData variable. Many thanks.
The first issue I'm seeing is you are treating an asynchronous process as if it was a synchronous one. The xhr.get returns immediately after the request to the server is sent, it does not block until a response is received.
First, I would add a console.log to your module definition to ensure that your dataHelper module is being loaded correctly.
define(["dojo/_base/xhr"],
function(xhr){
console.log('dataHelper.js loaded');
return {
//
};
});
Also note that above you aren't using any of the base dojo modules except dojo/_base/xhr, so it is unnecessary to include them (unless they are used outside this snippet).
You need to update your code to handle this call asynchronously. To do this, you could take advantage of the fact that the xhr.get method returns a Deferred object. This class makes dealing with asynchronous in a consistent manner quite easy.
To do this, update the dataHelper module to return the result of the xhr call:
define(["dojo/_base/xhr"], function(xhr){
return {
getJSON: function(){
//this returns a Deferred object, what to do on load and error is then handled by the invoker
return xhr.get({
url: "../../cpuusage.json",
handleAs: "json"
});
}
};
});
Then, when utilizing this module:
//replace dataHelper with whatever it's path is
require(['dataHelper'],function(dataHelper){
var deferred = dataHelper.getJSON();
deferred.then(function(data){
//this function is invoked once the data has been fully loaded
}, function(error){
//this function is invoked if an error occurs while loading the data (in case of a server error response or if the response isn't in the format you specified)
});
});
This is my proposal:
Your dataHelper.js file:
define("dataHelper", ["dojo/_base/declare", "dojo/dom", "dojo/_base/xhr"],
function(declare, dom, xhr){
return declare("dataHelper", [], {
getJSON: function(){
return xhr.get({
url: "../../cpuusage.json",
handleAs: "json"
});
});
};
});
your invocation:
require(["dataHelper"], function(dataHelper) {
var chartData;
dataHelper.getJSON().then(function(jsonData) {
chartData = jsonData;
//Continue doing stuff with chartData in here, not outside
});
});
i have a dropdown list of WordPress pages with the class of 'page_id' (they repeat and can be added.. hence the livequery). on the change event i want to send an ajax request to pull out the title, excerpt and thumbnail for the page selected. at the moment I am just trying to get ANY kind of valid json response. i am using json_encode in my callback to return a json object back to my .ajax function. and then in the .ajax success function I am trying to parse this json object into something usable, but get an error every time instead.
the error seems to be a problem with JSON.parse:
JSON.parse
success(response="{"title":"bacon title","message":"bacon text"}0")
handleError(a=Object { url="http://localhost/single/wp-admin/admin-ajax.php", global=true, more...}, b=XMLHttpRequest { onreadystatechange=[xpconnect wrapped nsIDOMEventListener], readyState=4, more...}, d="success", e="{"title":"bacon title","message":"bacon text"}0") onreadystatechange(m=readystatechange )
[Break On This Error] var json = JSON.parse(response);
firebug console says the response looks like:
{"title":"bacon title","message":"bacon text"}0
i don't know if that extra 0 is the trouble-maker, but i also don't know how it is getting there. chrome reports the error as:
Uncaught SyntaxError: Unexpected number
$.livequery.$.change.$.ajax.success/single/wp-admin/post.php?post=2&action=edit&message=1:917
here is my jquery function:
<script type="text/javascript">
//<![CDATA[
jQuery(function($) {
$('.page_id').livequery(function(){
var loading = $(this).next('img.ajax-loader');
$(this).change( function() {
var value = $(this).val();
if (value.length) {
$(loading).fadeIn();
var data = {
action: 'featured_meta_action',
data: value,
security: '<?php echo wp_create_nonce('featured-ajax-nonce'); ?>',
};
$.ajax({
type: "POST",
data: data,
url: ajaxurl,
complete: function(){
$(loading).fadeOut();
},
success: function(response){
var str = '{ "title": "bar" }';
var json = JSON.parse(response);
alert(json['title']);
},
error: function(){
alert('fail');
}
});
}//end if
}); //end change
}); //end livequery
}); //end ready
/* ]]> */
</script>
my php callback looks like:
function featured_meta_action_callback(){
$responseVar = array(
'title'=>'bacon title',
'message'=>'bacon text',
);
echo json_encode($responseVar);
}
add_action('wp_ajax_featured_meta_action', 'featured_meta_action_callback');
this has turned out to be way harder than it seems like it ought to be. i just need to get the data back from the PHP function so I can use it in the jquery. where am i going wrong?
I think it could be this:
function featured_meta_action_callback(){
$responseVar = array(
'title'=>'bacon title',
'message'=>'bacon text' // <<< Here you do not need another comma
);
echo json_encode($responseVar);
}
See the comment within the array.
EDIT: Although unnecessary, in a test it doesn't output a 0 at the end of the JSON object if I leave it in there. So it's probable that it is coming from somewhere else (in other words, the WordPress code).
EDIT v2: Run these through Firebug's console. The second throws an error, but if you don't include the 0, it works just fine.
console.log(JSON.parse('{"title":"bacon title","message":"bacon text"}'));
console.log(JSON.parse('{"title":"bacon title","message":"bacon text"}0'));
EDIT v3: Ok, you apparently need to short circuit the rest of the WP process by calling exit/die at the end of the function, like so:
function featured_meta_action_callback(){
$responseVar = array(
'title'=>'bacon title',
'message'=>'bacon text' // <<< Here you do not need another comma
);
echo json_encode($responseVar);
exit;
}
Suggested here:
http://codex.wordpress.org/AJAX_in_Plugins#Ajax_on_the_Administration_Side
And here:
http://amiworks.co.in/talk/simplified-ajax-for-wordpress-plugin-developers-using-jquery/