When using Custom Posts and adding a Metabox, I was wondering how I could add a drop-down menu that would populate data that was added by the user.

For example I want to be able to select a 'source' for the post using the drop-down, but under that I want the user to be able to add sources to that same drop-down. I've tried doing this on my own by using taxonomies for the sources and trying to populate the drop-down with those taxonomies, but I probably did it wrong.

Any idea of how I can go about this?


NOTE: It's kind of late, so the code might not be perfect, but it should get you on the right track.

Well, you could theoretically just set up a custom taxonomy and then the user can just use the text box at the bottom and then the check boxes in the Taxonomy selection area.

I'll be assuming you are using the standard Post type for these, but you can adjust it in the register_taxonomy call.

Something like:

register_taxonomy("post_source", array("post"), array("hierarchical" => true, "label" => "Sources", "singular_label" => "Source", "rewrite" => true));

But, if you're set on the drop-down, you'll need to set it up a little differently.

The code below will be using Ajax to send the newly added source to the DB, and, if that is successful, add that source to the dropdown and select it automatically.

Step 1: Create a Table for Storing Sources

You'll want to create a table for storing these so that you can refer to them when the user tries to add a new source and make sure that it isn't already in the database.

And, you'll need them stored somewhere so that you can pull them into the dropdown.

Step 2: Create the Meta Box

//run this function on admin_init
//add source selection box to post editor
function add_post_source_box() {
     add_meta_box("post_source_meta", "Post Source", "post_source", "post", "side", "high");

Step 3: Populate the Meta Box

//populate the post_source box
function post_source() {
     global $post;
     $custom = get_post_custom($post->ID);
 $post_source = $custom['post_source'][0]; ?>

     <script type="text/javascript">
          jQuery(function() {
               jQuery("#post_source_add_button").click(function() {
                    var new_source = jQuery("$post_source_add").val();
                    var add_source = {"ajaxurl":"<?php echo get_bloginfo('wp_url'); ?>/wp-admin/admin-ajax.php"};
                    if(new_source.length) {
                                  action: 'add_source',
                                  source: new_source 
                              function(response,source_id) {
                                   if(response == 'success') {
                                        $("#post_source_dropdown").find('option').each(function() {
                                             if(jQuery(this).is('selected') {
                                             } else if(jQuery(this).attr('id') == source_id) {
                                   } else {
                                        alert('Error adding source.');

     <table cellpadding="0" cellspacing="5" border="0">
               <td><label for="post_source_dropdown">Post Source</label></td>
                   <select name="post_source_dropdown" id="post_source_dropdown">
                        <option value="">Select a Source</option>

                        <?php //get the various sources already added
                        $global wpdb;
                        $sources = $wpdb->get_results("SELECT * FROM wp_post_sources ORDER BY source_name");
                        foreach($sources as $source) {
                             if($source->id == $post_source) {
                                  $selected = ' selected';
                             } else {
                                  $selected = '';
                             echo '<option value="' . $source->id . '"' . $selected . '>' . $source->source_name . '</option>';
                        } ?>
               <td><label for="post_source_add">Add New Source</label></td>
                    <input type="text" name="post_source_add" id="post_source_add" value="" />
                    <br />
                    <input type="button" id="post_source_add_button" name="post_source_add_button" value="Add Source" />

<?php }

Step 4: Save the Custom Meta

//run this function when saving posts
//save the source when the user saves the post
function save_post_source() {
     $global post;


I'd recommend moving the JavaScript into a separate JS file that you include using the admin_enque_scripts action I just wrote it directly in there for this example.

This post has a great breakdown of using Ajax in a plug-in, which I would honestly recommend you turn this into instead of dropping it into the functions.php. That way if you ever want to swap themes, you won't have to worry about remembering to move things from the functions.php of the old theme.

Step 5: Process the New Source via Ajax

I'm going to leave this one up to you for right now because it's late, and getting all of this in here took longer than I expected. Just be sure to send back the response and the ID of the source added to the database.

EDIT: I forgot a really important part, it is outlined in that article I linked, but it should be noted again because it really is the lynch pin of the whole Ajax submission thing.

//run this function when admin-ajax receives the action 'add_source'
//add the new source to the db
function add_source_to_db() {
     //get the source from the $_POST array and then add it to the db
     //create the response object to send back to the JS function

Now you just need to fill in the add_source_to_db function and you're all set.

HINT: You'll want to use the global $wpdb object to insert the new source and then use $wpdb->insert_id to get the ID of the source that was just inserted.

Hopefully what I've provided can get you started.

If you need help with the processing file, let me know and I'll try to provide some code. However, the link regarding the Ajax in plug-ins should have everything you need to get it working.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.