web-dev-qa-db-fra.com

Comment afficher/ajouter/enregistrer des métabox personnalisés sous forme de tableau de valeurs?

Ce que j'essaie de faire est de créer un type de message personnalisé, une méta-boîte personnalisée qui en insère les valeurs dans un tableau de "couleurs" ou "p_clrs".

J'ai un script jQuery qui fonctionne, vous permettant de cliquer sur un lien vers "Ajouter une autre couleur", qui ajoute un autre champ de saisie en dessous de celui qui indique toujours par défaut (doit montrer au moins 1 métabox de couleurs). Les champs de saisie ajoutés à jQuery doivent stocker les valeurs de chaque élément ajouté, sous la forme d'une autre "couleur" dans le tableau de "couleurs" que je tente de créer.

Sur la page newpost ou la page de modification des publications existantes, la méthode metabox color doit exécuter une boucle foreach pour créer une "couleur" metabox qui existe dans la variable 'p_clrs'.

Je ne suis pas bon du tout avec les tableaux, et les tableaux multiples, et particulièrement les boucles foreach. Je déteste les boucles foreach lol.

Je suis tellement près de travailler, je ne veux pas le faire en utilisant des taxonomies, et une fois que je parviendrai à cette boucle foreach sur chaque couleur du tableau que je tente de créer ici, je pourrai pour gérer tout ce dont j'ai besoin avec ce genre de choses. Je ne peux tout simplement pas passer au-dessus du tableau/Foreach bosse sur lequel je suis coincé.

Ceci est ma classe de produits pour mon type de publication personnalisé.

C’est ce que j’ai toutes les valeurs pour les articles (y compris mes autres métaboxes dont les codes ne sont pas inclus ici).

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'
);

Voici la méthode qui a aussi mes codes register_post_type () et register_taxonomy () mais ce n'est pas vraiment nécessaire, alors je l'ai laissée de côté. Une fois que les fonctions register_ptype et _tax () ont été appelées, j’ajoute les actions à appliquer aux éléments devant être ajoutés à init et aux éléments.

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

Cette méthode est ce qui fait toute l'insertion d'informations pour chacun des champs de formulaire de publication. Cela fonctionne également pour toutes mes métaboxes personnalisées, * À l'exception des champs de saisie supplémentaires que jQuery ajoute lorsque vous cliquez sur le lien/bouton "Ajouter une autre couleur".

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);
            }
        }
    }
}

Voici la méthode pour ajouter mes metabox. Je ne sais pas si je pourrais/devrais faire le foreach à l'intérieur, en parcourant le tableau de valeurs $ p_clrs pour ajouter une couleur metabox foreach existante, s'il en existe plusieurs. Sinon, il ne devrait y avoir qu'un seul métabox affiché (il devrait toujours y en avoir au moins 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' );
    }

Voici ma méthode pour afficher les métaboxes elles-mêmes, ainsi que le script jQuery qui ajoute et supprime les champs de saisie supplémentaires qui "pourraient" devenir potentiellement des métaboxes lors de l'enregistrement de la publication si les zones ajoutées ne sont pas vides.

Voici une image de ce que je veux dire pour vous donner une idée de ce dont je parle. metabox

Actuellement, la première entrée est affichée au chargement de la page avec toute valeur stockée, le cas échéant. Lorsque vous cliquez sur le lien Ajouter une autre, une autre entrée avec la même valeur est ajoutée, mais lorsque vous enregistrez une valeur différente dans un champ de saisie, elle enregistre la valeur de la dernière entrée ayant une valeur. Et ne montre qu'une entrée lors du rechargement de la page lorsque vous la sauvegardez également. Je dois montrer les entrées pour chaque valeur ajoutée qui était là, ce qui doit également être inséré dans la variable/tableau 'p_clrs' afin de le faire pour chaque valeur 'p_clrs' existante. Perdu encore?

    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

Merci pour toute aide que n'importe qui peut me donner, et désolé si c'est un peu fou d'un post. J'ai eu du mal à couper/coller le code dans cette zone de texte. Il était méchant pour moi.

Faites-moi savoir si mon explication de ce que j'essaie/dois faire n'est pas tout à fait claire aussi. Il est assez difficile de décrire facilement sans une sorte de visuel.

1
jaredwilli

Il vous suffit de modifier l'attribut name des champs de saisie générés de p_clr à p_clr[]. $_POST['p_clr'] sera alors un tableau avec les valeurs de tous les champs d'entrée.

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>
3
sorich87