2

I'm trying to build an interface so that two custom fields for a custom post type can be edited on the front end with checkboxes. I'd like to display empty checkboxes if neither of those the fields have values, and allow a user to check one or both boxes, and have the corresponding fields be set to true (or just have some value, I suppose - not sure if a postmeta can have a boolean value) (preferably via AJAX).

My first thought is to use Scribu's Front End Editor plugin, although it obviously doesn't solve this use case without some tweaking. However, I figured I'd ask to see if anyone else has done something like this before, or has suggestions on how specifically to implement the FEE plugin to do this (or if I should look elsewhere).

Edit to expand: this is going on a page listing multiple posts, so I'm trying to figure out a way to make this work for more than just one post on a page. Here's what the page looks like right now:

enter image description here

And here's the markup for that table:

    <table>
                <thead>
                    <tr>
                        <th>Date/Time</th>
                        <th>Job ID</th>
                        <th>Customer Name</th>
                        <th>File Size</th>
                        <th>Details</th>
                        <th>Download</th>
                        <th>Scheduled</th>
                        <th>Completed</th>
                    </tr>
                </thead>
                <tr class="job">
                        <td>8/8/12 1:12pm</td>
                        <td>28</td>
                        <td>Selina Kyle</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/selina-kyle/" target="_blank">Details</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/CC-Content-Checklist.docx">Download File</a></td>
                        <td><input type="checkbox" name="28-scheduled"  /></td> 
                        <td><input type="checkbox" name="28-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="28" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 1:06pm</td>
                        <td>26</td>
                        <td>Jim Gordon</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/jim-gordon/" target="_blank">Details</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/Copy-Corner-Proposal-7-17-121.pdf">Download File</a></td>
                        <td><input type="checkbox" name="26-scheduled"  /></td> 
                        <td><input type="checkbox" name="26-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="26" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 1:05pm</td>
                        <td>25</td>
                        <td>Lucius Fox</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/lucius-fox-2/" target="_blank">Details</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/Process-and-deadlines-Copy-Corner2.pdf">Download File</a></td>
                        <td><input type="checkbox" name="25-scheduled"  /></td> 
                        <td><input type="checkbox" name="25-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="25" /></td>
                        <td><span class="response"></span></td>
                </tr>
                <tr class="job">
                        <td>8/8/12 12:51pm</td>
                        <td>22</td>
                        <td>Bruce Wayne</td>
                        <td>filesize</td>
                        <td><a href="http://example.com/jobs/bruce-wayne-2/" target="_blank">Details</a></td>
                        <td><a href="http://example.com/wp-content/uploads/gravity_forms/1-884e859c1f31e83338dbdaefd3bb2853/2012/08/CC-Wireframes1.pdf">Download File</a></td>
                        <td><input type="checkbox" name="22-scheduled"  /></td> 
                        <td><input type="checkbox" name="22-completed"  /></td> 
                        <td><input type="hidden" name="post_id" value="22" /></td>
                        <td><span class="response"></span></td>
                </tr>
   </table>
2
  • Can you give us some sample markup for the page? That will help us narrow down proper JS selectors ...
    – EAMann
    Aug 10, 2012 at 22:29
  • @EAMann good call. I also added a screenshot. Aug 10, 2012 at 22:48

1 Answer 1

3

My gut instinct would be to roll my own AJAX callback. You obviously know the post ID (since you have it on the front end) and the names of the fields, just post that back to WP using AJAX and programmatically set the values there.

An untested example (props to Kailey Lampert):

// Add checkboxes to post content
add_filter( 'the_content', 'cba_add_checkboxes'); 
function cba_add_checkboxes( $c ) {

    $first = get_post_meta( get_the_ID(), 'first_item_key', true );
    $second = get_post_meta( get_the_ID(), 'second_item_key', true );

    $c .= '<p class="cba"><input type="checkbox"  name="test_value_1" '. checked( $first, 'true', false ) .' /><br />
    <input type="checkbox" name="test_value_2" '. checked( $second, 'true', false ) .' />
    <input type="hidden" name="post_id" value="'. get_the_ID() .'" /><br /><span class="response"></span></p>';

    return $c;
}
// Add scripts to the footer
add_action('wp_footer', 'cba_script');
function cba_script() {
    wp_enqueue_script('jquery');
    ?><script>
    jQuery(function($) {
        var ajaxurl = '<?php echo admin_url( 'admin-ajax.php' ); ?>';
        var spinner = '<?php echo admin_url( 'images/loading.gif' ); ?>';
        $('.cba input').click( function() {
            var p = $(this).parent('p');
            p.find('.response').html('<img src="'+spinner+'" />');
            $.post(ajaxurl, {
                'action': 'update_custom_fields',
                'post_id': p.find('input[name="post_id"]').val(),
                'first_item': p.find('input[name="test_value_1"]').is(':checked'),
                'second_item': p.find('input[name="test_value_2"]').is(':checked')
            }, function( response ) {

                p.find('.response').html(response);

            }, 'text');
        });
    });
    </script><?php
}
// Add handlers within WordPress to deal with the AJAX post
add_action( 'wp_ajax_update_custom_fields', 'cba_update_custom_fields' ); // for logged-in users
add_action( 'wp_ajax_nopriv_update_custom_fields', 'cba_update_custom_fields' ); // for logged-out users
function cba_update_custom_fields() {
    $post_id = $_POST[ 'post_id' ];
    $first_item = $_POST[ 'first_item' ];
    $second_item = $_POST[ 'second_item' ];

    update_post_meta( $post_id, 'first_item_key', $first_item );
    update_post_meta( $post_id, 'second_item_key', $second_item );

    die( 'updated' );
}

Update Based on Markup

Now that we know a little more what you're doing, we can be a bit more specific on the JS code you need to use.

Basically, what I recommend you do is set up a custom class and some data elements inside your checkboxes. So where you have things like:

<td><input type="checkbox" name="28-scheduled"  /></td> 
<td><input type="checkbox" name="28-completed"  /></td> 

Become things like:

<td><input type="checkbox" name="28-scheduled" class="ajax-checkbox" data-post="28" data-type="scheduled" /></td> 
<td><input type="checkbox" name="28-completed" class="ajax-checkbox" data-post="28" data-type="completed" /></td> 

Now, you can set up a jQuery event listener on the entire table that looks at each input individually:

jQuery(function($) {
    $('table').on('change', 'input.ajax-checkbox', function() {
        var $this = $(this), 
            type = $this.data('type'), 
            postID = $this.data('post');

        // ... Now send off your AJAX request as before
    });
});

This event listener will wait for the change event of all <input> elements that have the ajax-checkbox class. It will then extract the values you've hard-coded (PHP-generated, I hope) from the data-attributes so you can send them in your AJAX request. You'll have to merge this in with the examples above or the custom code you're already written to dispatch the messages.

3
  • 4
    Expanding on @EAMann's idea, here's a demo/test plugin that adds some checkboxes and saves their selection via ajax: gist.github.com/3308061 Aug 9, 2012 at 21:11
  • @KaileyLampert wow, awesome! I've got this almost working at this point - the only hangup is that I'm getting a response of '0' instead of 'Updated'. Any suggestions on how to debug that? Aug 10, 2012 at 18:40
  • I think part of my problem is that I'm trying to make this work for multiple posts on the same page (see my edit above), but the javascript only checks whether an input of each type is checked or not, without checking which post id the checked boxes correspond to. I'm not sure how to rectify the situation, though. Aug 10, 2012 at 22:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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