Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Adding AJAX form to a custom post type meta box WordPress

  • SOLVED

Hello everyone,

I'd like to implement a similar functionality as WP Categories screen in the Admin area - where you can add category and it will appear in the list of all categories straight away.

I have a CD custom post type and I would like to add tracks to a CD in the same way as WP Categories are added. So that after general CD info there will be an empty "New track info" form where a track's info is inserted and after hitting "Add track" - a track will appear under the general CD info, and again displaying an empty "New track info" form to add another track to a CD. Also, it will be grate if I could reorder tracks by dragging and dropping them.

<strong>So to break it down:</strong>

1) I have a custom post type for CDs
2) I want each CD to have multiple tracks
3) I want the ability to add tracks one-at-a-time through a custom edit form
4) I want to add tracks via AJAX (after hitting the "Add track" button, the track information is automatically added to the CD and you can add another track)
5) I would like the ability to dynamically drag-and-drop tracks into a different order

<strong>I've got to:</strong>

1) I've created a custom post type for CDs
2) I've added 15 static fields (with ids "static_tr_name_$i" and "static_tr_time_$i") in a meta box in CD edit screen by using "fields" array (in main $meta_boxes array). Please refer to the code here: <strong>http://wordpress.pastebin.com/npJrYaWZ</strong>
3) I've tried to add a form to the meta box on the CD edit screen. However, it appears that my form for adding a track is within a meta box, which in turn is within the main post form. As far as I know I can't have a form within another form.... So I'm stack :(

I really hope there must be a way to accomplish what I want - to have a form in a custom post type edit screen for edit items one at a time. Maybe I've taken a wrong approach..
I would really appreciate if someone could help me to get all this working! <em>Please</em> :) I really want to learn how to do something like that.

Many thanks,
Dasha

Answers (2)

2010-11-06

Nick Parsons answers:

Dasha,

I have some good news for you - that's definitely doable! I just put some code together that should take care of your requests. Add this to the top of your file:

global $post;
$saved_tracks = get_option('cd_tracks');
$num_fields = ($saved_tracks[$post->ID])? $saved_tracks[$post->ID] : 15;

if ( isset($_GET['add-track']) ){

if(!$saved_tracks){ $saved_tracks = array(); }
if(!$saved_tracks[$post->ID]){ $saved_tracks[$post->ID] = 15; }
$saved_tracks[$post->ID]++ ;
$n = $_GET['index'];
$saved_values = get_post_meta( $_GET['id'], 'custom_tracks', true);
$saved_values['static_tr_name_'.$n] = $_GET['name'];
$saved_values['static_tr_time_'.$n] = $_GET['time'];
print_r($saved_values);
update_option('cd_tracks', $saved_tracks);
update_post_meta( $post->ID, 'custom_tracks', $saved_values);
?>
<tr>
<th style="width:20%"><label for="static_tr_name_<?php echo $n; ?>">Track #<?php echo $n; ?> Name</label></th>
<td><input type="text" name="static_tr_name_<?php echo $n; ?>" id="static_tr_name_<?php echo $n; ?>" value="<?php echo $_GET['name']; ?>" size="30" style="width:97%" /><br />Track Name.</td>
</tr>
<tr>
<th style="width:20%"><label for="static_tr_time_<?php echo $n; ?>">Track #<?php echo $n; ?> Time</label></th>
<td><input type="text" name="static_tr_time_<?php echo $n; ?>" id="static_tr_time_<?php echo $n; ?>" value="<?php echo $_GET['time']; ?>" size="30" style="width:97%" /><br />Time of the track #<?php echo $n; ?>, specified above.<td>
</tr>
<?php
exit();
}


And then scroll down and change the add_post_enctype function to look like this:

function add_post_entype() {
echo '
<script type="text/javascript">
jQuery(document).ready(function(){
jQuery("#post").attr("enctype", "multipart/form-data");
jQuery("#post").attr("encoding", "multipart/form-data");


jQuery("#add-track").click( function(){
var staticForm = jQuery(".form-table:first");
var id = jQuery("#post_ID").val()
var nonce = jQuery("#cd_tracks_nonce").val()
var trackName = jQuery("#tr_name").val();
var trackTime = jQuery("#tr_time").val();
var lyrics = jQuery("#tr_lyrics").val();
var fieldNo = jQuery(".form-table:first tbody>tr").length/2+1;
if (trackName != "" && trackTime != ""){
jQuery.ajax({
data : "name="+trackName+"&time="+trackTime+"&tr_lyrics="+lyrics+"&id="+id+"&_wpnonce="+nonce+"&index="+fieldNo+"&id="+id+"&add-track=",
success : function(fields){ staticForm.append(fields); }
});
return false;
}
});
});

</script>';
}


Also, remove the form tags and change the submit button like this:
<br/><input type="button" class="button-primary" id="add-track" name="add-track" value="Add Track" />

I can add the drag and drop functionality that you mentioned, too, but try this and let me know if that is indeed what you're after before I spend too much time on it just to realize I misunderstood :)

Have a great weekend!


Nick Parsons comments:

Hey, I just realized I made a mistake - when you try this code out, change the line
var staticForm = jQuery(".form-table:first");
to be like this:
var staticForm = jQuery(".form-table:first tbody");

2010-11-08

Tobias Nyholm answers:

This does not sound very wordpressish.
Wordpress is a great platform if you want a pretty good site very quick. But if you want to build something more complex (as you describe) you will see that wordpress has its limits. The code gets messy and lacks the benefits of object orientation.

If you are 100% sure that you never will add more functionality to this site, you maybe should try what Nick Parsons said. Otherwise I recommend you to use an object oriented CMS like Drupal or a framework like Symfony.