Edit post meta with checkboxes on front end

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).

Read More

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>

Related posts

Leave a Reply

1 comment

  1. 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.