Loading scripts & styles from a meta box callback function

Case:

I got a set of classes that build form fields based on data from an input array. The class can build the following types of form fields:

  • input (basic, hidden, password)
  • textarea
  • radio
  • checkbox
  • select
  • colorpicker
  • datepicker
  • file upload

EDIT: The class uses wp_register_script/_style & wp_enqueue_script/_style to load the scripts & styles. The functions containing the actions are hooked inside the class like this: add_action( 'admin_enqueue_scripts', array( &$this, 'enqueue' ) );.

Example:

(Inside functions.php)

// meta box callback function
function test_meta_box_cb()
{   
    $input_args = array(
         'type'         => 'color'
        ,'id'           => 'color-id'
        ,'label'        => 'Input Colorpicker Label'
        ,'opt_name'     => 'abc_xyz'
        ,'value'        => '009ee0'
     );
    new FormClass( $input_args, true );
}
// add the meta box
function add_test_meta_box()
{
    add_meta_box( 'test_box', __('TestBox'), 'test_meta_box_cb', 'post', 'advanced', 'high' );
}
add_action( 'add_meta_boxes', 'add_test_meta_box' );

Problem:

This way, my call for wp_enqueue_script & wp_enqueue_style doesn’t work. I get the form fields rendered, but no scripts or styles.

Situation & Backtracing of the problem:

So far I could track down the problem to the wordpress core architecture:

  • WP doesn’t question what happens inside the callback function until do_action('add_meta_boxes', $post_type, $post) get’s called (inside edit-form-advanced.php).
  • That call happens long after admin-header.php was called (which contains do_action('admin_enqueue_scripts', $hook_suffix);).
  • Therefore the script & style can’t get loaded (if I’m not wrong).

Question:

  1. How could i load styles before the meta box form fields get called?
  2. How could i avoid repeating the same stylesheet over and over again – i want to use wp_enqueue_style & wp_register_style?

I’m open to any answers including those who force me to rewrite my class architecture.

Note: I need to use this class in a lot of different szenarios, so bundling it to close together with the add_meta_box function is not good. I’m close to making an abstraction layer that divides the call for the meta box and the style/script part, but why would I want to add another layer above a core function?

3 Answers
3

Your problem is adding the scripts, styles inside the class, and because the class instance is created when the hook add_meta_box is fired, at that time the wp_enqueue_script/style are already finished.

A solution for you is adding the scripts, styles outside the function and the class. And because meta boxes are used only at editing pages, you can do as the following:

// the editing pages are actually post.php and post-new.php
add_action('admin_print_styles-post.php', 'custom_js_css');
add_action('admin_print_styles-post-new.php', 'custom_js_css');

function custom_js_css() {
    wp_enqueue_style('your-meta-box', $base_url . '/meta-box.css');
    wp_enqueue_script('your-meta-box', $base_url . '/meta-box.js', array('jquery'), null, true);
}

Actually, I wrote a meta box class for WP, that uses another approach. Instead of writing form class for form fields like you did, my class is a wrapper for meta boxes. If you interested in, it’s worth to take a look.

Leave a Comment