In Part 1 and Part 2 of our custom meta box template tutorial series, we learned how to create a field array to loop through and create a custom meta box with your standard fields. Now let’s throw in a bit of JavaScript for some fancy, but highly useful fields.

Finish Reading at WPTuts+

22 thoughts on "Reusable Custom Meta Boxes Part 3: Extra Fields"

  1. jerry says:

    thanks for the great work.
    problem is that only one meta box can be generated, how can we use those codes to get multiple meta boxes?

    1. Tammy Hart says:

      You can duplicate the code in new file that you’ll include in your functions file. Then change all of your function names to be unique to that meta box, such as add_custom_meta_box, show_custom_meta_box, etc. You’ll also need to change the field array name ($custom_meta_fields) and everywhere it’s called with global.

      1. jerry says:

        thanks for the reply. do you have any plan to improve codes to be reusable for multiple meta boxes not duplicate all codes as you mentioned above? like this one: http://www.deluxeblogtips.com/2010/05/howto-meta-box-wordpress.html
        i really like your codes, clean and understandable for starters to embedded into themes.

  2. Ryan says:

    LOVE the series – one thing I’m curious about though is how do you show the values you placed in the repeatable fields on your theme.

    In my particular example I’m trying to create a row of images – so I want them to be able to add the image url and then call it in the theme – what would I do to do this?

    Thanks!

    1. Tammy Hart says:

      Ryan,

      So glad you enjoyed the series! I do plan on writing a Bonus part about outputting the data, but haven’t gotten around to writing it yet.

      For images, you’re saving the ID of the iamge, so you should be able to use any of the attachment related functions: wp_get_attachment_image_src, wp_get_attachment_image_link, wp_get_attachment_image, etc.

      Hope that helps!

      1. Ryan says:

        Thanks! I was also curious if there was a way to have two of the metaboxes, each for a separate custom post type? I can get it on one, but can’t figure out how to add another.

        Thanks again for all your work on this!

      2. Tammy Hart says:

        Yep, you can duplicate the process, making sure you make all of your function names unique as well as the fields array, and change the post types in all the right places.

  3. Mic3000 says:

    Hi tammy, great work!
    I would know if repeatable fields can be like

    [text][/text] [tax1_select] [tax2_select] [text][/text]

    I’m not a good coder!

    i’m sorry for my bad english!

    1. Mic3000 says:

      My eg needs a changes

      [text1] [tax1_select] [text2] [tax2_select] [+][-]

      i’m sorry!

      1. Tammy Hart says:

        Your fields can be in whatever order you like. The order that you add them to the array will be the order that they are in the output. Hope that helps!

      2. Mic3000 says:

        I know about the order, but i’m not able to display more different fields in the same repeatable line, but maybe my approach is incorrect..

        1. Tammy Hart says:

          Oh, I see. You want to have more than just a text field in the repeatable. To do that, you’ll need to add another layer to the item’s array. So taking form our original example, the name is this:
          $field['id'].'['.$i.']

          If the field id is “repeatable”, several of these would create an array like this:

          $repeatable = array(
              '0' => 'text you entered',
              '1' => 'text you entered into the next one',
              '2' => 'and the last text you entered'
          ); 

          Change the id to something more like this: $field['id'].'['.$i.'].[text] and Then add more fields with similar names like this: $field['id'].'['.$i.'].[anothertext], $field['id'].'['.$i.'].[select], $field['id'].'['.$i.'].[checkbox], until you have all the fields you want. IMPORTANT: Be sure to add these to the foreach loop AND to the else so that you get them when there’s nothing saved for that current post AND when there is.

          Now your array should look like this:

          $repeatable = array(
              '0' => array(
                      'text' => 'text you entered',
                      'anothertext' => 'another text you entered',
                      'select' => 'select option you chose',
                      'checkbox' => 'on'
                  ),
              '1' => array(
                      'text' => 'text you entered',
                      'anothertext' => 'another text you entered',
                      'select' => 'select option you chose',
                      'checkbox' => 'on'
                  ),
              '2' => array(
                      'text' => 'text you entered',
                      'anothertext' => 'another text you entered',
                      'select' => 'select option you chose',
                      'checkbox' => 'on'
                  )
          ); 

          Hope that helps!

  4. Anton says:

    Hi Tammy!
    Is there any way to display checkbox as checked by default?
    For select I added 1 more parameter in custom meta fields array – ‘default’, where I keep my default value. Then I added simple if function to switch case, where we outputting select elements, just before foreach:
    if($meta==”) $meta=$field[‘default’];
    I’m not an expert, but it works fine, but is there a way to set default statement to checkboxes?
    Also I want to say thank you for this great tuts – great work!
    Is Part 3 a last tutorial of this series?
    Would be interesting to see part4, for example “how to use meta box values in the right way”.

    1. Tammy Hart says:

      Anton,

      So glad you liked the series! I do plan on doing a Bonus art that goes over how to use the data, I just haven’t gotten around to writing it yet.

      Good job on setting a default for your select boxes. For checkboxes it should work pretty much the same way. Have you tried it? what results did you get?

      I could caution you about setting defaults. Let’s say for isntance you create a post that doesn’t use the custom metabox for some reason. With a default set, it will save the data for the post unintentionally and unnecessarily.

      1. Anton says:

        I’m confused actually )))
        For select boxes exist at least one value. When we adding a new post $meta variable doesn’t exist or empty (not sure), but when we publishing post $meta variable equals to selected value and from this moment $meta will be not empty. So we can easily set a default value to $meta before post is published.
        But if talk about checkboxes or group of checkboxes, their $meta variable keeps only checkboxe’s state (“on” when is checked and empty when it unchecked). I can imagine how to set default values for them. There should be something, what tells us that we are on ADD NEW POST page (post-new.php) or $meta should keep 2 variables for each checkbox, one of them for example first_use => true.
        I we put the same if function (if($meta==”) $meta=$field[‘default’];), checkboxes will be always checked.
        I’m working on my second theme. I made some additional widget areas. I added a metabox with select boxes (user can choose sidebar to display in this widget areas)and also, I want to put checkboxes, with default condition – checked, so users can quickly choose, display widget area or not. That is why I’m so interested in default statement))
        Sorry If I do mistake, because english is not my native language, but anyway, I will look forward to your last tutorial about metaboxes, thanks!))

      2. Tammy Hart says:

        Anton.

        I’m not sure if I’m exactly following along with you, but try this code for your checkbox switch:

        case 'checkbox':
        	$checked = $field['checked'];
        	if (isset($meta) && $meta != 1) $checked = '';
        		else $checked = ' checked="checked"';
        	echo '<input id="'.$id.'" name="recipress_options['.$id.']" type="checkbox" value="1"'.$checked.' /> <label for="'.$id.'">'.$desc.'</label>';
        
  5. Ryan says:

    Hm…for some reason this seems to be breaking the WordPress Media Uploader (the new ajax one that does it in bulk – regular browser updater works)…any idea why that would happen?

    1. Ryan says:

      Ok I think I figured it out – it’s the jQuery(‘.custom_repeatable’).sortable({ in the custom-js.js file that is causing the issue. So the repeatable items aren’t sortable anymore, but the media uploader works.

  6. Anghel Gabriel says:

    @ryan.

    The problem is that you should enable the javascript file only in the custom post_type page. Edit and Add new. To do that you should include the CODE
    When the meta box is echo’ed meaning the function show_custom_metabox.

    And if you want to make the sortable fields realy be saved as sortable use this line of code.

    update: function(event,ui){
    var i = 0;
    jQuery(‘#ULID li input’).each(function() {
    jQuery(this).attr(‘name’, ‘NAMEATTRIBUTE[‘+ i++ +’]’);
    });
    }

    Check the jQuery sortable plugin page for more details. where to paste the code

  7. Kris says:

    Thank you for a great Tutorial!

    I’m trying to display the repeatable field’s values in a theme and am kinda lost.

  8. Kris says:

    I’m following your example to add additional fields to the “repeatable” form, but I’m getting “Array” in each of the fields… Here’s the code I’m using. Any idea what I’m doing wrong? Without the additional field it works great.


    // repeatable
    case ‘repeatable’:
    echo ‘+
    ‘;
    $i = 0;
    if ($meta) {
    foreach($meta as $row) {
    echo ‘|||

    ‘;
    $i++;
    }
    } else {
    echo ‘|||

    ‘;
    }
    echo ‘
    ‘.$field[‘desc’].”;

  9. Kris says:

    Sorry for the last question, the code didn’t display correctly on your site. Basically I’m copying your example to add additional fields to the “repeatable”. The fields are created but after I submit the form, nothing but “Array” appears in the field.

Leave a Reply

Your email address will not be published. Required fields are marked *