Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

What I am trying to do is create a custom post type, custom meta box that inserts the values of it into an array of 'colors' or, 'p_clrs'.

I have a jQuery script which works, allowing you to click a link to "Add Another Color", which adds another input field below the one which shows always by default (must show at least 1 colors metabox). The jQuery added input fields should store the values of each one that gets added, as another 'color' in the array of 'colors' which I'm trying to create.

When on the newpost page or edit page for existing posts, the colors metabox needs to run a foreach loop to create a metabox foreach 'color' that exists in the 'p_clrs' variable.

I am not good at all with arrays, and multi-arrays, and especially foreach loops. I hate foreach loops lol.

I've gotten it all so close to working, I don't want to do it all over using taxonomies, and once I get this to foreach loop over each color of the array which I am trying to create here, I will be able to handle anything else I need to with this stuff. I just can't get over the array/foreach hump I'm stuck on here.

This is my Product Class for my custom post type.

This is what I have all the values for the posts info (including my other metaboxes which the codes aren't included here for them).

class TypeProducts {

    public $prod_meta_fields = array( 
    'title', 'description', 'product_type', 'post_tag',
    'p_sku', 'p_price', 'p_discnt_price', 
    'p_weight', 'p_size_w', 'p_size_h', 
    'p_clrs'
);

Here is the method which also has my register_post_type() and register_taxonomy() codes but that isn't really needed for this so I left it out. After the register_ptype and _tax() functions are called, I add the actions for things that need to be added to the init and stuffs.

public function TypeProducts() {
    add_action( 'admin_init', array( &$this, 'product_meta_boxes' ));
    add_action( 'wp_insert_post', array( &$this, 'wp_insert_post' ), 10, 2 );
}

This method is what does all the inserting of information for each of the post form fields. It works for all my custom metaboxes too, *Except for the additional input fields that jQuery adds when you click the "Add Another Color" link/button.

public function wp_insert_post($post_id, $post = null) {
    if ($post->post_type == 'product') { // my custom post type is 'product'
        foreach ($this->prod_meta_fields as $key) { // loops over the $prod_meta_fields
            $value = @$_POST[$key];
            if (empty($value)) {
                delete_post_meta($post_id, $key);
                continue;
            }
            if (!is_array($value)) {
                if (!update_post_meta($post_id, $key, $value)) {
                    add_post_meta($post_id, $key, $value);
                }
            } else {
                delete_post_meta($post_id, $key);
                foreach ($value as $entry) add_post_meta($post_id, $key, $entry);
            }
        }
    }
}

Here's the method for adding my metabox(es). Not sure whether I could/should do the foreach within this, looping over the array of $p_clrs values to add a metabox foreach color that exists, if there are more than one. Otherwise, there should just be one metabox displayed (at all times there should be at least 1).

    function product_meta_boxes() {
    add_meta_box( 'products-price', 'Product SKU# & Price', array( &$this, 'prod_price_box' ), 'product', 'side', 'high' );
    add_meta_box( 'products-colors', 'Product Colors', array( &$this, 'prod_colors_box' ), 'product', 'normal', 'high' );
    }

Here's my method for outputting the metabox(es) itself, and also the jQuery script that adds and removes additional input fields which "could" potentially become metaboxes upon saving the post if the added boxes arent empty.

Here's a picture of what I mean to give you an idea of what I'm talking about. metabox

Currently the first input shows on page load with any value which is stored if any. When clicking the Add Another link, it adds another input with the same value, but when saving a different value in any input field, it saves the value of the last input that has a value. And only shows one input upon reloading the page when you save it too. I need to show inputs for each added value that was there, which needs to also be inserted to the 'p_clrs' variable/array in order to do that foreach 'p_clrs' value that exists. Lost yet?

    public function prod_colors_box() {
            global $post, $p_clr;
    $p_clr = array();
            $p_clrs = get_post_meta( $post->ID, 'p_clr', true );
    ?>

    <div id="p_colors">
        <p>
            <label for="p_clr_1">
            <strong>Color:</strong> <input id="p_clr_1" name="p_clr" value="<?php echo $p_clrs; ?>" />
            </label>
        </p>
    </div>
        <h4><a href="#" id="addClr">Add Another Color</a></h4>

    <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
    <script type="text/javascript">
    $(function() {

        var clrDiv = $('#p_colors');
        var j = $('#p_colors p').size() + 1;

        $('#addClr').live('click', function() {
            $('<p><label for="p_clr_' + j + '"><strong>Color:</strong> <input id="p_clr_' + j + '" name="p_clr" size="20" value="<?php echo $p_clrs; ?>" /></label> <a href="#" id="remClr">Remove</a></p>').appendTo(clrDiv);
            j++;
            return false;
        });
        $('#remClr').live('click', function() { 
            if( j > 2 ) {
                $(this).parents('p').remove(); 
                j--;
            } return false; 
        });
    });
    </script>

<?php
}

} // end of TypeProducts{} Class

Thanks for any help anyone can give me, and sorry if this is a little crazy of a post. I had a hard time cutting/pasting the code into this textarea. It was being wonky for me.

Let me know if my explanation of what I'm trying/need to do isn't entirely clear too. It's kind of difficult to easily describe without some sort of visual of it first.

share|improve this question
    
Where's the single-file packaging of your question you promised after your Twitter request to have me look at this? Give me something I can just include from my theme's functions.php file to have your code working in my test install of WordPress. –  MikeSchinkel Oct 30 '10 at 19:05
    
@sorich87's updated solution for this below has solved my problem. Thanks though. :) –  jaredwilli Oct 31 '10 at 12:01
add comment

1 Answer 1

up vote 2 down vote accepted

You just have to modify the name attribute of the generated input fields from p_clr to p_clr[]. $_POST['p_clr'] will then be an array with the values of all the input fields.

public function prod_colors_box() {
        global $post, $p_clr;
$p_clr = array();
        $p_clrs = get_post_meta( $post->ID, 'p_clr' );
?>

<div id="p_colors">
    <?php foreach( $p_clrs as $key => $p_clr ) { ?>
    <p>
        <label for="p_clr_<?php echo $key; ?>">
        <strong>Color:</strong> <input id="p_clr_<?php echo $key; ?>" name="p_clr[]" value="<?php echo $p_clr; ?>" />
        </label>
    </p>
    <?php } ?>
</div>
    <h4><a href="#" id="addClr">Add Another Color</a></h4>

<script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
<script type="text/javascript">
$(function() {

    var clrDiv = $('#p_colors');
    var j = $('#p_colors p').size() + 1;

    $('#addClr').live('click', function() {
        $('<p><label for="p_clr_' + j + '"><strong>Color:</strong> <input id="p_clr_' + j + '" name="p_clr[]" size="20" value="<?php echo $p_clrs; ?>" /></label> <a href="#" id="remClr">Remove</a></p>').appendTo(clrDiv);
        j++;
        return false;
    });
    $('#remClr').live('click', function() { 
        if( j > 2 ) {
            $(this).parents('p').remove(); 
            j--;
        } return false; 
    });
});
</script>

share|improve this answer
    
Just by doing this the metaboxes will be created for every existing color value that is in the array? No need to do a foreach loop at all? Seems like there's more to it than that, but I'll give it a try and see. –  jaredwilli Oct 30 '10 at 15:06
    
Yeah that definitely wasn't all there was to this. Just changing the jQuery generated input name values from name="p_clr" - to name="p_clr[]" did not work. Unless there is something you are trying to say that I missed here. It's more involved than that. –  jaredwilli Oct 30 '10 at 18:28
    
Maybe I did not fully understand your questions? "What I am trying to do is create a custom post type, custom meta box that inserts the values of it into an array of 'colors' or, 'p_clrs'." With the change I suggested $_POST['p_clr'] will be an array with all the values entered in the colors input fields. –  sorich87 Oct 30 '10 at 18:45
    
Just noticed there was no loop to display the stored values. I modified my answer. –  sorich87 Oct 30 '10 at 19:01
    
That's more like it :) I knew there needed to be a foreach loop in there somewhere. This works, and problem is solved. Thanks alot man :D –  jaredwilli Oct 31 '10 at 12:02
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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