Using AJAX In Your WordPress Theme Admin
I recently received an e-mail asking if I could help make an admin for a theme that was powered by AJAX & therefore did not need the page to be refreshed to save the data. Unfortunately I couldn’t help as although I have built admins for plugins & themes before, I didn’t have the knowledge to add the AJAX functionality to it. However I’ve spent the past day or so reading & trying to understand the theory behind AJAX usage within WordPress’ admin & I think I’ve managed to come up with something.
Good For You! How Does That Help Me?
Well I wanted to understand it so I could write a simple tutorial for those who are getting into theme development & want to add that little bit of ‘je ne sais quoi’ to the admin of a theme.
So How Do We Start?
We add our admin page link to WordPress’ menu. Since we are going to add code into the header we need to do a few things different to a normal admin page or the header code will be output to all of the pages in the WordPress admin. Exactly what we don’t want since it is useless for anything other than running our admin page.
Here is the code to add your page into the WordPress admin:
1 2 3 4 5 6 7 8 9 |
add_action('admin_menu', 'test_add_theme_page'); function test_add_theme_page() { if ( isset( $_GET['page'] ) && $_GET['page'] == basename(__FILE__) ) { add_action('admin_head', 'test_theme_page_head'); } add_theme_page(__('Test Admin'), __('Test Admin'), 'edit_themes', basename(__FILE__), 'test_theme_page'); } |
First we call add_action()
this tells WP to run a function into the admin_menu
hook. The function test_add_theme_page
, change the name if you like (just make sure they match), checks that the admin page we are on is actually the current file. If it is, we can add the code into the header (code coming in a minute) using the admin_head
hook. No matter what page we are on we still need to add the link for the admin page into the admin menu so we run the function add_theme_page()
. I explained the useage in my other tutorial, but just in case here it is again.
- __(‘Test Admin’)
- This is the text shown as the browser title, that’s the text shown in the title bar of your browser.
- __(‘Test Admin’)
- This is the text shown as the link title in the WordPress menu. It will appear under the Appearance tab
- edit_theme
- This is the role required to access the page.
- basename(__FILE__)
- This is a unique identifier. I’ve used the current file’s filename.
- test_theme_page
- The function that will create the contents of the options page.
Adding the jQuery
As I mentioned earlier add_action('admin_head', 'test_theme_page_head');
adds code into the header of the page. This is what we will use to add our jQuery code. Here is the function I have used:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
function test_theme_page_head() { ?> <script type="text/javascript"> jQuery(document).ready(function($) { jQuery('form#test_form').submit(function() { var data = jQuery(this).serialize(); jQuery.post(ajaxurl, data, function(response) { if(response == 1) { show_message(1); t = setTimeout('fade_message()', 2000); } else { show_message(2); t = setTimeout('fade_message()', 2000); } }); return false; }); }); function show_message(n) { if(n == 1) { jQuery('#saved').html('<div id="message" class="updated fade"><p><strong><?php _e('Options saved.'); ?></strong></p></div>').show(); } else { jQuery('#saved').html('<div id="message" class="error fade"><p><strong><?php _e('Options could not be saved.'); ?></strong></p></div>').show(); } } function fade_message() { jQuery('#saved').fadeOut(1000); clearTimeout(t); } </script> <?php } |
Ok, I’m going to attempt to explain everything written here. It might take a while so bare with me. 😆
First we define the function we named in our add_action()
call. We then break out of PHP so we can easily add our jQuery code. We open a script tag as normal, then we start our jQuery with a standard run on DOM load. I’ve passed the $
through the run on DOM function so you should be able to use the standard $
inside it, however I chose to continue using the jQuery
that WordPress defines for conflict prevention with other JS libraries.
Next we target our form, which hasn’t been made yet, so pick an ID or something here for it, and attach a function to it’s submit event. We serialize the data from the form, this excludes the submit buttons value & encodes data in standard URL query format, storing it in the variable data
. We can use jQuery(this)
because we are inside the element that is holding the data, in this case the form. Next we create a standard AJAX call using jQuery’s jQuery.post
function. ajaxurl
is a javascript global variable defined by WordPress & should always be used for AJAX requests inside WordPress for security reasons. data
is our serialized form data & the the function is to be ran on the completion (callback) of our AJAX request. response
is the data returned from the AJAX request.
Inside the callback we check the response data to see if it contains 1
. This will be sent back by our AJAX function we will create later, if it is 1
we take it as meaning true & show an options saved box, if it is anything else we show an options not saved box. The message boxes are simple jQuery that show a message in styling defined by WordPress & then use a simple setTimeout
& clearTimeout
to show & hide the boxes. I’m not going to add to the length of this tutorial by explaining them, if you want to know more about them leave a comment & I’ll explain more about the functions. We finally use return false
in the submit event to stop the form from submitting and refreshing the page.
Creating The HTML Form
Next we are going to create the form needed for the data to be inserted by the user. My form isn’t pretty & does absolutely nothing, by that I mean although it saves data the data isn’t used in any way. Here is my code, remember that this function is used by the add_theme_page
function we called earlier:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
function test_theme_page() { ?> <div class="wrap"> <h2><?php _e('Test Admin'); ?></h2> <div id="saved"></div> <?php $options = get_option('test_theme'); ?> <form action="/" name="test_form" id="test_form"> <input type="text" name="test_text" value="<?php echo $options['test_text']; ?>" /><br /> <input type="checkbox" name="test_check" value="on" <?php echo ($options['test-check'] == 'on') ? 'checked' : ''; ?> /><br /> <input type="hidden" name="action" value="test_theme_data_save" /> <input type="hidden" name="security" value="<?php echo wp_create_nonce('test-theme-data'); ?>" /> <input type="submit" value="Submit" /> </form> </div> <?php } |
The is the function that creates the page you see when you visit the admin page. Although you can use the header section to add your own CSS code I have just used the default WordPress CSS. That is why the HTML starts with a div with the class of wrap.
The form is the important part. You must give it a name, and the ID must be the same as the one you used in the jQuery submit event function earlier. The interior of the form can include anything your theme requires, however you need 2 extra input fields. These fields are hidden ones that send required data for the AJAX to work correctly. First is the action
hidden field, the value should be whatever you want WordPress to call it’s hook that will be used to hook the function we will make to get results from the AJAX call. The other hidden field security
is the infamous nonce code used by WordPress for security. The value must be as shown however you can change the word inside wp_create_nonce()
to anything you like (preferable something relevent to your theme), remember it though as we’ll need it later.
We have also added in some PHP to recall the options saved in the database. We simply store the options into a variable & then echo out the data into the value fields. In the case of checkboxes we check for the value on & the add ‘checked’ if it is detected. I’ve used a ternary as it is shorter when writing PHP inline with HTML.
Creating The PHP AJAX Function
Ok so we are nearly done. We just have to create the function called by jQuery, so here’s what I ended up with:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
add_action('wp_ajax_test_theme_data_save', 'test_theme_save_ajax'); function test_theme_save_ajax() { check_ajax_referer('test-theme-data', 'security'); $data = $_POST; unset($data['security'], $data['action']); if(!is_array(get_option('test_theme'))) { $options = array(); } else { $options = get_option('test_theme'); } if(!empty($data)) { $diff = array_diff($options, $data); $diff2 = array_diff($data, $options); $diff = array_merge($diff, $diff2); } else { $diff = array(); } if(!empty($diff)) { if(update_option('test_theme', $data)) { die('1'); } else { die('0'); } } else { die('1'); } } |
First is add_action
the name of this hook was determined by the value of our action
field in our form, you just prepend wp_ajax_
to the front of it. The function can be called anything you like again, but try to keep them all relevent to your theme.
Now onto the actual function. First we use a function defined by WordPress to check if the nonce key we received is active & valid. This is where you need to recall that string I told you to remember as it has to be written in the first parameter identically to the one you wrote in wp_create_nonce()
. If like me you haven’t used the default post value $_POST['_ajax_nonce']
you will need to tell the function what the $_POST
key for the nonce code is, in our case security
is the code. This is gotten from the name parameter of our hidden form field. Next we transfer our data from the $_POST
global array to a variable called $data
, we unset both the nonce key & our action which are passed by the form & are no longer needed. One thing to note is that if check_ajax_referer()
does not validate the code it will die outputting ‘-1’, so when debuging if you receive that value you know what is doing it.
To stop our next piece of code throwing an error we need to get the options stored in the database & if they are empty create a blank array on the variable that would normally hold them. get_option()
asks WordPress to go to the database and get the data in the wp_options
table with the key provided. In our case that is test_theme
. All we do is check if the returned value is an array. If it is we grab the data. If not we set a blank array.
Next it gets a little strange. I don’t know if it is a bug or not, but if the values sent from the form are the same as the current database values update_option()
will return as if it failed, so we need to screen the options first. We check to see if the options in the database are the same as the once recieved from the form submission by checking for differences using array_diff()
. To get the differences correctly we check both arrays against each other & then merge the results together. We also set a blank array if there is no data sent to trigger our jQuery error. If $diff
is not an empty array we have differences and can safely save the options. If the update is successful stop PHP processing & echo out 1 to our jQuery function. If it fails then stop processing & echo 0 to our jQuery function. Else if the variable $diff
is empty we do not need to update the database since the options are identical so just stop processing & echo out 1.
A quick note about update_option()
. You can change the part in the parentheses to anything you like, but try to make it unique & relevent to your theme in some way. Also you may wonder how it is storing an array in a single database field, this is because update_option()
auto serializes an array before saving it. In the same vein, get_option()
unserializes a serialized array back into a normal array when it grabs data. These are important things to remember when using both these functions.
We’ll that is it, I think. I don’t think I’ve missed anything. I’ve been at this post so long I’ve lost feeling in my legs. 😆 I hope this post helps you, despite it ending up a lot more complicated that I’d wanted it to. You may need to read the post a few times to get a proper understanding of what is going on. If you have any problems or notice something I’ve missed please, please, please email me or leave me a comment & I’ll sort it out as quickly as I can.
Thank you for reading, good luck, and I hope I haven’t made your brain explode. 😉
139 Comments
kathy
i’ve really been getting into WP options lately… and your post looks like everything i’ve been looking for, but didn’t know i was looking for! i really wish i had found this sooner.
and these options will be “magically” inserted into the wp_options table of the database? for some reason after pasting all your code into my functions.php file and attempting to add something into the dummy text box, i get the error message that the options could not be saved. i guess i had better re-read this a few more times.
also just curious, is there any reason why using a standard submit function would be better than submitting via ajax? i guess i mean, is there any downside to using ajax? i already have some options in a jquery tabs setup, it would be cool to mash what i have together with your awesome tut.
cheers!
Paul Robinson
Hi Kathy,
Was there some of your comment missing before the second paragraph? Just struck me a little weird that it stared with ‘and’. Anyway…
I’m not entirely sure there’s any real difference or benefit other than ease of use. The down side of AJAX is that it might cause a little more server load, but I doubt it as WP core uses AJAX all the time.
As for your error, I’ll take a look when I get up (I’m in bed, lol) as I’m sending this from my iPod and it’s not the easiest thing to be debugging code on. 😉
Kathy
Nope, nothing before the 2nd paragraph. that is just me blithely ignoring conventions of english and also not proofreading enough. 🙂
i would appreciate you taking a quick look, tho i feel like if it didn’t work someone would have said something before the 54th comment. i, too, will be taking a closer 2nd look at things when i am a bit more rested. i’m using WP3.0, with a child theme on a local server at the moment if that helps.
iPods can send emails? whoaaaa. mine just plays songs. 🙂
Paul Robinson
Don’t worry about it, just checking I wasn’t missing any comment. 😉
I don’t have much experience with child themes, but I don’t think it would interfere with the code & as far as I know it still works okay in WP 3. I even developed the code on a WP 3 beta blog a while ago & I don’t think much has changed.
The only error I can remember getting while developing this code, that is the same as yours, was caused by the nonce code not matching up properly.
You could try adding an alert to the AJAX callback to see what value the nonce checker is returning. If it returns -1 or 0 then the nonce is not being validated properly.
If you want to try that find this line in the jQuery code:
Then add this line after it:
Then try to save an option as normal & it should give you a little box with the value of data in it.
If you let me know what that turns up I’ll see if I can find any other reasons for the error.
Oh, and yes. iPod touch is just like an iPhone without the phone. 😆
kathy
the only thing i did was piece your snippets together and add the alert.
http://pastebin.com/dfmAjTiU
here is the info i am getting from teh alrt:
test_text=&test_check=on&action=test_theme_data&security=4e1882cb80
whick doesn’t look anything like a 0 or -1 like you mentioned. hmmm.
Paul Robinson
I apologise for being a complete idiot. I told you to alert the wrong thing. You need to alert
response
notdata
.Thanks for the pastebin I’ll have a check over it. Let me know what response comes out with & I’ll get back to you.
Kathy
Here is what I get:
Warning: array_diff() [function.array-diff]:Argument #1 is not an array in D:\helga\xampp\htdocs\plagueround\wp-content\themes\thematic_options_me\functions\test-admin.php on line 111 1
this is line 111:
$diff = array_diff(get_option(‘test_theme’), $data);
Paul Robinson
Is that error appearing when you click the button or when you load the page? I’m not sure why changing the value that the alert gives back would cause an error?
kathy
that is what i get when i click on the submit button… so i presume that is what i am getting for my ‘response’ variable. then once i click ok on the popup i get the fading message that my options could not be saved. do you have a working sample you’d be willing to pastebin? that might be easier than trying to figure out where i’ve gone astray.
Paul Robinson
That’s very odd. Unfortunately I don’t, the only code I have is for a theme I built & it has theme specific stuff tied into it.
You could try changing the code slightly to cope with the error. Try this:
Let me know how that goes.
kathy
Hi again Paul! Well I tried your latest tweak. There seems to be some progress. the alert(response) coughs up a 1 and i get the faded message that my options were saved. however, i don’t see them in the database and i draw a blank when i try to echo them back out…. with get_option(‘test_text’)
doing a bit of a manual labor project at the moment and all the time in the sun is zapping my brain power. i appreciate all your help with this.
Paul Robinson
Yeah this heat is driving me mad. I don’t mind it during the day, it on a night time that bothers me.
Well that means we are getting past the security check & the options are being retrieved, but for some reason they aren’t being saved. Due to some strange problem with update_option you need to check if it’s changed from the original value or it fails to update.
I thought the if…else at the end there did that, but for some reason it doesn’t seem to be doing the job? I’ll have a play around with it and see if I can find out what’s going on.
kathy
hi again,
i “think” i have at least isolated the problem down to array_diff(). From what I understand, array_diff checks the first array against the second array and returns as a result an array of things from the first array that are NOT in array 2.
BUT, if array1 is null… such as when the theme is first activated as well as at other times, then array_diff returns a null array and so nothing is ever updated to the database. i tried flipping the 2 around like array_diff($data,$options) and that got some things into the database, except when i went to uncheck the checkbox and save that… it wouldn’t work b/c if the checkbox is unmarked then there is no test_check is the $data.
still working…
kathy
ps- i meant to ask if you have any sort of failsafe in case a user does not have javascript enabled?
Paul Robinson
Hmm! No I hadn’t thought about that. I would say set the forms action to the php page that AJAX contacts. In that case the data will be sent as if it was being sent by AJAX.
I think I remember having a problem like you mentioned and I thought I’d fixed it. 🙁
I’ll have a look at the version I mentioned before and see if I can find how I got around it.
Paul Robinson
Can you please try this bit of code. If it works I’ll update the post. I fixed this a little while ago & it looks like I didn’t update the post. 🙁 I apologize.
The actual saving part would work it’s just the bit that checks to see if the options are different isn’t. Hopefully that will fix it. I have tested it & it seems to work.
Let me know how it goes.
kathy
we might have it!? i had to blend your last 2 suggestions together and now my whole function looks like:
http://pastebin.com/0WJsfsw7
this seems to work. i get options showing in the database. i can echo them back. i can delete the whole field from my database and it re-creates on the next save.
now… on to applying this to all my options! thank you so much for all the help.
kathy
i am sure that you know how to do this, but if you are going to update the post it might be nice to show up to get the data back out of the array for use in the theme, etc. for instance this would be how to show the current values in the form:
Paul Robinson
Ahhh yes. No worries. Also nice job on that addition to the code. I actually had that in & forgot to copy it over as part of the replacement. Doh!
I apologize for all the problems I’m assuming you’re in the UK (from your sun comment before), I think the heat has just killed my brain. 🙁
I’ll update the post tomorrow (well today, lol) and I’ll add in how to return the values back. Which I should have done in the first place.
kathy
nope… across the pond in ‘the colonies’, but we’ve (at least my area) been getting killed by the sun too.
yours is the only tutorial on ajaxifying theme options so it was a great find… and even better since you are up in the wee hours of the morning to help get it sorted when we both ought to be down the pub on a friday night.
thanks for everything!
Paul Robinson
Ooops. Haha. Yeah we don’t normally get much sun even in the summer but it’s been hitting 30 degrees. The problem Is we aren’t used to it so it kills us. We are all used to the crappy weather. Hehe.
I didn’t realise the was the only tutorial on how to ajaxify a WP them admin. I’ll go through it tomorrow & clean it up a bit.
Nah, not tonight. I’m saving all my drinking points for the England Vs Germany match on Sunday. Not usually a football fan but I make an exception for the world cup. 😉
Don’t worry about it, always glad to help. Nod it’s 2:37 in the morning here so I’m of to bed. 😉
Paul Robinson
Okay the post has been updated to include the updated information. I’ve also added the code on how to pull the options back into the form.
kathy
hi again paul. just dropping back in to point out an error in your new code.
get_options should be get_option otherwise you get a fatal call to an undefined function
here is a pastebin of all the pieces smushed together for anyone who needs it:
http://pastebin.com/vfxiPyMv
too bad about our footie teams.
Paul Robinson
Bollocks… That’s what you get for touch typing & then not proof reading your code. 🙁 I’ve fixed it now.
Yeah, it’s not like we can be suprised about the football though really. 🙁
Robert
There’s a small bug u said:
it should be “test_themes”, without it wont work.
Will keep testing..
Paul Robinson
Looks like your code was stripped by WordPress. I’ve found the error you mean though & have corrected it. Sorry for the inconvenience.
Robert
I found another bug, when I have many select type options with enabled disabled values inside, it will retrive as diffrence is 0 and wont update, it only happens if there are many enabled disabled options, i guess it thinks that some enabled values belong to other options and do not do the appropiarate match. I removed the diff check, and it’s fine now. any particular reason why to keep diff check?
Paul Robinson
I haven’t had much time to check out any upgrades WP may have made, but the difference check was there because
update_option()
seemed to cause an error (for me at least) if the options were the same as before.I should really get around to re-making this tutorial. I’m currently building our first theme to be released soon so I’ll try & re-make this when I’ve finished the admin for that. 🙂
Robert
Yea well, we also build our themes and now with your help also integrated some ajax.
I know that it shouldn’t cause any errors, before without ajax there is no diff check as seen at:
I almost finished with this ajax, last thing is to integrate a reset button, but im woundering if i should try to integrate ino existing form or a new one with delete_option
Paul Robinson
That was one of the strange things I never figured out. Without AJAX there was no need to check for changes, but as soon as I added AJAX it kept crashing unless I checked for changes to the options first.
I’m busy with my new theme now, so I’ll make it a priority to update this post as soon as I get my admin working.
I remember a reset button being a pain. The best way I found was a way I believe WooThemes use.
Have a default options function that inserts default options on theme activation (if no options are detected). Then have a button that triggers a deletion of the options (using
delete_option()
), then triggers the default options function.There may be a better way, but that was the most efficient & elegant (to an extent) way I have seen.
Robert
I actually use a different method, the default options are stored in the file, not DB.
Paul Robinson
My default options are in the file too. There is just a function that checks to see if any options from the theme exist in the database. If they don’t exist the defaults are saved into the database to be used.
To reset the options you use a function to delete the options from the database and retrigger the default function to restore the default options from the file to the database.
I hope that makes sense. The defaults are stored in the PHP file, but they are copied to the database for the theme admin to access them. Because they are in the file they can be restored to the database at any time.
Robert
I have built a reset button, if you use ajax with wp_ajax then it wont refresh the page, and people will be on the same page. any ideas on how to incorporate refresh capability within wp_ajax ?
Paul Robinson
I’m not sure I understand what you mean? The only way to refresh a page is either to trigger the browser refresh via Javascript or send a request that would require the page to be reloaded (eg a form) without intervening via JS to send the request via AJAX.
Kathy
Hi Paul, I’ve been doing all kinds of work with options. I collaborated with another developer and he built a panel that is very similar to Wootheme’s panel… then I used what I learned here to serialize the data, b/c I hate how Woo adds 100+ entries into the DB! there is also an “options machine” like with woo that lets you define all your options as an array and it will spit out the appropriate markup. it is a child theme of Thematic and it is on Git if you fancy a look:
https://github.com/helgatheviking/thematic-options-KIA
But, I’ve returned to dig up your thread up again as I have run into a bug involving those blasted checkboxes.
If I create multiple checkboxes like in the following (which is just all of your above code, but w/ extra checkboxes)
http://pastebin.com/BCHwsBi5
then check them all and save. now if i try to uncheck 1 or 2 and save…. on refresh they’ve not been saved. for some reason if i uncheck ALL the boxes they seem to save.
so far i believe this has something to do w/ serialize not picking up empty checkboxes… which is its normal behavior. so since they dont get serialized, they don’t end up in the array that we are passing to update_option. and if they are not there then update_option doesn’t delete them and so they stay permanently checked.
I’m working on figuring this out and would appreciate any insight. Maybe you ran into this in your own theme?
Cheers!
Paul Robinson
I’ve been meaning to develop a theme for WordPress but just haven’t had the time. 🙁
Haven’t worked on WP admins for a little while so please excuse any rustiness on my part, lol.
I’ve just checked the code over & realized that I think I may have overcomplicated things. All you really need to do is hand the array to WP and it will do everything you just need to deal with a little quirk the
update_option()
has.The code would just be this:
This seems to work flawlessly for me. The only little thing is that quirk.
update_option()
doesn’t return TRUE on success & FALSE on failure. It returns TRUE on data change & FALSE if the data is the same. So you wouldn’t need an ‘options saved’ & ‘options could not be saved’. You’d want an ‘options saved & ‘options not changed’.I just realized while I was staring at it and scanning through the WP codex. Really
update_option()
cannot fail unless MySQL goes on holiday & even then it would be the WP MySQL class that would deal with that error & I think ‘options not changed’ is a good compromise between they weren’t changed because they are the same & they weren’t changed because there was an error.I hope all that makes sense. It’s kinda hard for me to try & explain what I was thinking. Let me know if it doesn’t & I’ll try again, lol.
Kathy
that makes perfect sense actually! after staring at it for a long time i had finally isolated the problem down to all the array_diff() and array_merge()…. unchecking a box didn’t seem to create a value in array_diff. i got rid of that it seemed to start to work, so I am thrilled by the confirmation.
pretty much i think you could get away w/o the if statement and the resulting “options updated” versus “options not changed”. b/c if a user clicks saved and get an “options not changed” message it will still seem like an error. i think it might be better just to say “options saved” even though there is no difference- they were saved.. just not to anything new.
i’ve been working on this child theme for a while- trying to get something i can use every time and crank out whatever options are relevant to the theme. as a result i havent had time to get my own site up yet. it keeps going through endless iterations and after working on it for a few weeks i decide i don’t like it any more. craziness. i ‘think’ though (but i haven’t tried) that the options thing i’ve done doesn’t rely on thematic at all… and one of these days i will see if i can drop it into any theme.
thanks for the help!
Asag chertkoff
Hi.
First of all – you did a marvelous job! thank you.
It’s been very educational 😉
Now, i’m trying to add an input field that will upload an image after submitting.
I’ve used the wp_handle_upload () function, as always, and i can’t figure out why it doesn’t work.
http://pastebin.com/35HW8RSZ
Can you have a look and give me your opinion?
It will be very appreciated.
Thanks,
Asaf.
Paul Robinson
Hi,
I’m afraid I’m away from my computer all day today & It’s difficult to look at code on my phone.
If you can wait till tomorrow when I’m back at my computer I’ll be glad to take a peek for you.
Sorry for the inconvenience.
Asaf Chertkoff
Of course! 🙂
Thanks for your devotion.
Asaf.
Paul Robinson
Hi,
So I eventually got around to looking at your code. Really sorry about the delay.
Small note first. In the comment just above (with Kathy) I suggested a different way to store the information as the
array_diff()
doesn’t always work properly, so you may want to look into that. I just haven’t had time to modify the post as I need to look into it more before I can.I have a feeling your code is failing because you aren’t handing your file data to the
wp_handle_upload()
function. The file’s data won’t be stored inside the$data
variable since that is a clone of the$_POST
superglobal. Your file will be stored under the same key but inside the$_FILES
superglobal instead.One additional thing. Make sure your form has the
enctype="multipart/form-data"
as an attribute or it won’t pass along your file data.Hope that helps. 🙂
Asaf Chertkoff
I found a good solution for me: i used this tutorial for implementing the WordPress Generic Uploader.
kathy
@asaf – i’ve incorporated ajaxupload (atleast the older version) in with a hefty options panel at:
https://github.com/helgatheviking/thematic-options-KIA/
(it is a child theme of thematic). if you care to wade through some code there is an example of how to use the upload function.
@paul- ever thought of trying to do this with the Settings API? thought would make a useful tut i think. ps- you should look into a better way to highlight the code snippets. for some reason i am having the damnedest time getting it to select all. cheers!
Paul Robinson
Hehe. I did use ajaxupload in my experimental theme back end but I haven’t been back to it in a while. Ahh, evil AJAX memories. 😆
I haven’t actually played with the Settings API, in fact I’m ashamed to say I’d completely forgotten it existed until you mentioned it.
Which code snippets? The large ones in the code boxes or the inline grey ones?
kathy
the big code boxes. its strange b/c i hadn’t noticed it before. but i do like the 1 click to copy all option i’ve seen elsewhere. and ajaxupload was a bear to get working!! so much so that i have pretty much refused to upgrade, b/c the new version was so difficult! i have only marginally glanced at the settings API- but am trying to figure out how to best implement it w/ Ajax and all the rest of the shenanigans I have going on in my theme options.
Paul Robinson
Hmm. Very strange. They are ran using the most common code highlighter out there. I’ve switched it back to the older version, let me know if it works any better.
I’ll see if I can get some time to look at the settings API. I’ve just never seem to have enough time to do everything lately. 🙁
kathy
copy to clipboard = me like! i know exactly what you mean about time. seems like i need an army of minions to help me get all the coding things i want to do out of my head right now. but you have my email if you want to collab a little on the settings API + ajax. i have other things i should be doing, but i will probably work on that for a bit.
Paul Robinson
Will do, thanks for the offer.
I’ve got one more jQuery tutorial I want to get done, then I’ll see if I can get something put together about the settings API. 😉
kathy
ps- check out what Devin Price is doing with options and Settings API: http://wptheming.com/2011/02/options-framework-plugin/
Paul Robinson
I’ll take a look thanks Kathy. 🙂
Satish Gandham
I just ajaxified my theme options page following your tutorial.
Thanks a lot.
Paul Robinson
No worries. Glad it was helpful to you.
Jamie
Great job on your post! I had been working on an admin options page for a few months now and this was the last thing I wanted to get working in my admin test. I was easily able to follow your instructions, modify the code to fit my variables and I just finished my testing and it works. My biggest problem is that I set up the admin in jquery tabs and when I saved the options, it would refresh the page and move back to the first tab. This post fixed that issue. I am golden now. Keep up the good work! I appreciate your efforts
Paul Robinson
Thanks. I do keep meaning to come back to this subject and see if I can improve on anything, but It’s such a time consuming subject to delve into I haven’t been able to find the time to revise or improve on this post.
I promise I’ll get to it eventually though. 😆
jamie
The one thing you could do to update it is to change the form to the latest version of wordpress admin code. For example, I am using
add_settings_field and settings_section in my code rather than putting the input fields. It is suppose to handle all the security and verification so that you don’t have to add any nonce fileds.
Paul Robinson
I didn’t know that. Thanks I’ll add it in when I update it, hopefully soon.
sittipol
I just change a bit of your code and it works great.
Thanks! 😀
Paul Robinson
No problem. Thanks for reading. 🙂
Phillip
This is a great summary. I’ve done my own wordpress/ajax coding, but you’ve captured all the main points nicely.
I added your test code to an admin plugin I’m developing and it worked great. It saved me the timeof coding up my own template in order to add ajax.
Thanks!
Tom
Hi, thanks for this post – I’ve been playing around with it for a couple of hours and have a question. My options are set up like so:
So, I need to update the ajax php function to include all the options, not just one option (get_option(‘test_theme’)). Can you point me in the right direction with this? I’ve tried a foreach, then using options as $value, and calling $value[‘id’] in the update option. But I just can’t seem to get it to work.
Thanks for any help or guidance you can offer,
Tom
Paul Robinson
Hi Tom,
It’s a common misconception that you need a separate options entry for each piece of data. Doing that just clutters up the database with a lot of entries for the same plugin/theme.
The best way to keep your information is to serialize it and place that into the database. To do that is as easy as handing the array to the
update_option()
function as it auto serializes arrays before entering them into the database.Tom
Hi Paul – thanks a lot for the quick response. I really appreciate it.
So, first of all, let me say I’m no PHP expert – I’m learning, but still have a long way to go.
I have it so the Alert shows my change, and then the message tells me the options have been updated, but when I refresh the page, the change disappears. Can you take a look at my code and let me know if I’m missing anything obvious?
If I remove serialize from the update_option, it says the options could not be saved – but I also noticed you said update_option serializes it automatically, so I’m not sure what I’m doing wrong there.
Any help would be greatly appreciated! Thanks a lot =)
Tom
Tom
Ah, just a note. I got the exact same result from this code:
Says the options are saved, but they just disappear on refresh.
Thanks!
Tom
Paul Robinson
Hi Tom,
This line:
is confusing me a little. The first parameter of
update_option()
is the name of the field you would like to update, serializing it shouldn’t work? The second parameter is the data.Yes, the data is auto serialized by WordPress.
update_option()
runs all data through a function calledmaybe_serialize()
to see if it is an array or object & serializes it if needed.