web-dev-qa-db-fra.com

Ajouter une classe CSS personnalisée aux champs de paiement WooCommerce

J'aimerais pouvoir ajouter une classe CSS personnalisée à mes champs de paiement WooCommerce. J'utilise Twitter Bootstrap et j'aimerais pouvoir utiliser leur classe .form-control.

J'ai regardé dans le dossier des modèles de woocommerce dans form-billing.php mais je ne sais pas où ajouter le .form-control classe à chaque champ de texte.

Voici le code pour form-billing.php

<?php
/**
 * Checkout billing information form
 *
 * @author      WooThemes
 * @package     WooCommerce/Templates
 * @version     2.1.2
 */

 if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
 ?>
 <div class="woocommerce-billing-fields">
<?php if ( WC()->cart->ship_to_billing_address_only() && WC()->cart->needs_shipping() ) : ?>

    <h3><?php _e( 'Billing &amp; Shipping', 'woocommerce' ); ?></h3>

<?php else : ?>

    <h3><?php _e( 'Billing Details', 'woocommerce' ); ?></h3>

<?php endif; ?>

<?php do_action( 'woocommerce_before_checkout_billing_form', $checkout ); ?>

<?php foreach ( $checkout->checkout_fields['billing'] as $key => $field ) : ?>

    <?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>

<?php endforeach; ?>

<?php do_action('woocommerce_after_checkout_billing_form', $checkout ); ?>

<?php if ( ! is_user_logged_in() && $checkout->enable_signup ) : ?>

    <?php if ( $checkout->enable_guest_checkout ) : ?>

        <p class="form-row form-row-wide create-account">
            <input class="input-checkbox" id="createaccount" <?php checked( ( true === $checkout->get_value( 'createaccount' ) || ( true === apply_filters( 'woocommerce_create_account_default_checked', false ) ) ), true) ?> type="checkbox" name="createaccount" value="1" /> <label for="createaccount" class="checkbox"><?php _e( 'Create an account?', 'woocommerce' ); ?></label>
        </p>

    <?php endif; ?>

    <?php do_action( 'woocommerce_before_checkout_registration_form', $checkout ); ?>

    <?php if ( ! empty( $checkout->checkout_fields['account'] ) ) : ?>

        <div class="create-account">

            <p><?php _e( 'Create an account by entering the information below. If you are a returning customer please login at the top of the page.', 'woocommerce' ); ?></p>

            <?php foreach ( $checkout->checkout_fields['account'] as $key => $field ) : ?>

                <?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>

            <?php endforeach; ?>

            <div class="clear"></div>

        </div>

    <?php endif; ?>

    <?php do_action( 'woocommerce_after_checkout_registration_form', $checkout ); ?>

<?php endif; ?>
</div>

Dois-je chercher dans un autre fichier de modèle?

Merci

13
NateW

la réponse d'icc97 est presque là mais ne fonctionne pas.

J'ai pris la réponse d'icc97 et l'ai déboguée:

add_filter('woocommerce_checkout_fields', 'addBootstrapToCheckoutFields' );
public function addBootstrapToCheckoutFields($fields) {
    foreach ($fields as &$fieldset) {
        foreach ($fieldset as &$field) {
            // if you want to add the form-group class around the label and the input
            $field['class'][] = 'form-group'; 

            // add form-control to the actual input
            $field['input_class'][] = 'form-control';
        }
    }
    return $fields;
}
35
Dan Smart

Comme l'a souligné @Peanuts, que se passe-t-il si nous voulons ajouter des classes CSS à certains types d'entrée uniquement?

Après avoir expérimenté avec les solutions publiées jusqu'ici (merci à tous!), J'ai trouvé un mod utilisant un simple "switch case", dans lequel la logique est tirée de /woocommerce/includes/wc-template-functions.php. La fonction nous permet de cibler tous les types d'entrée à la fois, que ce soit les types d'entrée par défaut ou même les types personnalisés.

Il n'est pas nécessaire de réécrire la fonction woocommerce_form_field Pour simplement changer les arguments $defaults Pour les types d'entrée. Il est valable de mentionner que la fonction nous permet également d'ajouter bien plus que des classes CSS aux champs.

- Alors, voici la fonction -

/*********************************************************************************************/
/** WooCommerce - Modify each individual input type $args defaults /**
/*********************************************************************************************/

add_filter('woocommerce_form_field_args','wc_form_field_args',10,3);

function wc_form_field_args( $args, $key, $value = null ) {

/*********************************************************************************************/
/** This is not meant to be here, but it serves as a reference
/** of what is possible to be changed. /**

$defaults = array(
    'type'              => 'text',
    'label'             => '',
    'description'       => '',
    'placeholder'       => '',
    'maxlength'         => false,
    'required'          => false,
    'id'                => $key,
    'class'             => array(),
    'label_class'       => array(),
    'input_class'       => array(),
    'return'            => false,
    'options'           => array(),
    'custom_attributes' => array(),
    'validate'          => array(),
    'default'           => '',
);
/*********************************************************************************************/

// Start field type switch case

switch ( $args['type'] ) {

    case "select" :  /* Targets all select input type elements, except the country and state select input types */
        $args['class'][] = 'form-group'; // Add a class to the field's html element wrapper - woocommerce input types (fields) are often wrapped within a <p></p> tag  
        $args['input_class'] = array('form-control', 'input-lg'); // Add a class to the form input itself
        //$args['custom_attributes']['data-plugin'] = 'select2';
        $args['label_class'] = array('control-label');
        $args['custom_attributes'] = array( 'data-plugin' => 'select2', 'data-allow-clear' => 'true', 'aria-hidden' => 'true',  ); // Add custom data attributes to the form input itself
    break;

    case 'country' : /* By default WooCommerce will populate a select with the country names - $args defined for this specific input type targets only the country select element */
        $args['class'][] = 'form-group single-country';
        $args['label_class'] = array('control-label');
    break;

    case "state" : /* By default WooCommerce will populate a select with state names - $args defined for this specific input type targets only the country select element */
        $args['class'][] = 'form-group'; // Add class to the field's html element wrapper 
        $args['input_class'] = array('form-control', 'input-lg'); // add class to the form input itself
        //$args['custom_attributes']['data-plugin'] = 'select2';
        $args['label_class'] = array('control-label');
        $args['custom_attributes'] = array( 'data-plugin' => 'select2', 'data-allow-clear' => 'true', 'aria-hidden' => 'true',  );
    break;


    case "password" :
    case "text" :
    case "email" :
    case "tel" :
    case "number" :
        $args['class'][] = 'form-group';
        //$args['input_class'][] = 'form-control input-lg'; // will return an array of classes, the same as bellow
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;

    case 'textarea' :
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;

    case 'checkbox' :  
    break;

    case 'radio' :
    break;

    default :
        $args['class'][] = 'form-group';
        $args['input_class'] = array('form-control', 'input-lg');
        $args['label_class'] = array('control-label');
    break;
    }

    return $args;
}

La fonction ci-dessus a complètement résolu le problème du ciblage des entrées du formulaire de paiement en une seule fois, ce qui est vraiment simple pour les types d'entrée par défaut du formulaire de paiement ou même de nouveaux personnalisés. Il ne semble cependant pas possible d'imprimer chaque sortie html de type d'entrée sans créer de nouvelle fonction comme @abhisek le montre dans sa réponse.

Prime

Il semble que la fonction puisse également affecter d'autres champs de formulaires imprimés par les fonctions ou modèles de WooCommerce en dehors de la page de paiement. J'ai réussi à appliquer conditionnellement la fonction uniquement sur la page de paiement en utilisant la fonction is_page(). Votre page de paiement peut avoir un slug différent, alors changez-le pour le refléter en conséquence.

Si vous devez appliquer la fonction uniquement pour la page de paiement, procédez comme suit:

Commentaire add_filter ()

//add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);

Et utilisez add_action à la place

add_action('woocommerce_form_field_args', 'wc_form_field_args', 10, 3);

function wc_form_field_args( $args, $key, $value = null ) {

...

// Right after 
    return $args;

// Place the following

if ( !is_page('checkout') ) {
  add_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
} else {
  remove_filter('woocommerce_form_field_args','wc_form_field_args', 10, 3);
}


}

Après cela, la fonction n'affectera que le formulaire de page de paiement.

20
Adriano Monecchi

@ Chetan's link and run réponse vous donne en quelque sorte ce que vous voulez, mais comme jamais ce ne sont jamais de très bonnes réponses.

La meilleure ressource pour cela est la page Codex WooCommerce sur Personnalisation des champs de paiement à l'aide d'actions et de filtres .

Dans la page `` Personnalisation des étiquettes de champs de paiement WooCommerce et du texte d'espace réservé '' de la page de Chetan, vous avez le code suivant que vous devez ajouter à vos fonctions.php, je l'ai modifié de telle sorte qu'il devrait faire ce que vous voulez, mais je n'ont pas testé le code:

// Hook in
add_filter( 'woocommerce_checkout_fields' , 'my_theme_custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function my_theme_custom_override_checkout_fields( $fields ) {
     foreach ($fields as $fieldset) {
         foreach ($fieldset as $field) {
             $field['class'] = array('form-control');
         }
     }
     return $fields;
}
3
icc97

J'ai résolu le problème en définissant une fonction personnalisée. La logique est tirée directement de wc-template-functions.php (je ne sais pas si c'est la bonne façon mais cela résout le problème).

/*
 * Custom form field function for Bootstrap 3
 */
function bootstrap_woocommerce_form_field( $key, $args, $value = null ) {
    $defaults = array(
        'type'              => 'text',
        'label'             => '',
        'placeholder'       => '',
        'maxlength'         => false,
        'required'          => false,
        'class'             => array(),
        'label_class'       => array(),
        'input_class'       => array(),
        'return'            => false,
        'options'           => array(),
        'custom_attributes' => array(),
        'validate'          => array(),
        'default'           => '',
    );

    $args = wp_parse_args( $args, $defaults  );

    if ( ( ! empty( $args['clear'] ) ) ) $after = '<div class="clear"></div>'; else $after = '';

    if ( $args['required'] ) {
        $args['class'][] = 'validate-required';
        $required = ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce'  ) . '">*</abbr>';
    } else {
        $required = '';
    }

    $args['maxlength'] = ( $args['maxlength'] ) ? 'maxlength="' . absint( $args['maxlength'] ) . '"' : '';

    if ( is_string( $args['label_class'] ) )
        $args['label_class'] = array( $args['label_class'] );

    if ( is_null( $value ) )
        $value = $args['default'];

    // Custom attribute handling
    $custom_attributes = array();

    if ( ! empty( $args['custom_attributes'] ) && is_array( $args['custom_attributes'] ) )
        foreach ( $args['custom_attributes'] as $attribute => $attribute_value )
            $custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $attribute_value ) . '"';

    if ( ! empty( $args['validate'] ) )
        foreach( $args['validate'] as $validate )
            $args['class'][] = 'validate-' . $validate;

    switch ( $args['type'] ) {
    case "country" :

        $countries = $key == 'shipping_country' ? WC()->countries->get_shipping_countries() : WC()->countries->get_allowed_countries();

        if ( sizeof( $countries ) == 1 ) {

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']  . '</label>';

            $field .= '<strong>' . current( array_values( $countries ) ) . '</strong>';

            $field .= '<input type="hidden" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="' . current( array_keys($countries ) ) . '" ' . implode( ' ', $custom_attributes ) . ' class="country_to_state" />';

            $field .= '</div>' . $after;

        } else {

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">'
                    . '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required  . '</label>'
                    . '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="country_to_state form-control country_select" ' . implode( ' ', $custom_attributes ) . '>'
                    . '<option value="">'.__( 'Select a country&hellip;', 'woocommerce' ) .'</option>';

            foreach ( $countries as $ckey => $cvalue )
                $field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';

            $field .= '</select>';

            $field .= '<noscript><input type="submit" name="woocommerce_checkout_update_totals" value="' . __( 'Update country', 'woocommerce' ) . '" /></noscript>';

            $field .= '</div>' . $after;

        }

        break;
    case "state" :

        /* Get Country */
        $country_key = $key == 'billing_state'? 'billing_country' : 'shipping_country';

        if ( isset( $_POST[ $country_key ] ) ) {
            $current_cc = wc_clean( $_POST[ $country_key ] );
        } elseif ( is_user_logged_in() ) {
            $current_cc = get_user_meta( get_current_user_id() , $country_key, true );
            if ( ! $current_cc) {
                $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_country()) ? WC()->customer->get_country() : WC()->countries->get_base_country());
            }
        } elseif ( $country_key == 'billing_country' ) {
            $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_country()) ? WC()->customer->get_country() : WC()->countries->get_base_country());
        } else {
            $current_cc = apply_filters('default_checkout_country', (WC()->customer->get_shipping_country()) ? WC()->customer->get_shipping_country() : WC()->countries->get_base_country());
        }

        $states = WC()->countries->get_states( $current_cc );

        if ( is_array( $states ) && empty( $states ) ) {

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field" style="display: none">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required . '</label>';
            $field .= '<input type="hidden" class="hidden" name="' . esc_attr( $key )  . '" id="' . esc_attr( $key ) . '" value="" ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '" />';
            $field .= '</div>' . $after;

        } elseif ( is_array( $states ) ) {

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
            $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="state_select form-control " ' . implode( ' ', $custom_attributes ) . ' placeholder="' . esc_attr( $args['placeholder'] ) . '">
                <option value="">'.__( 'Select a state&hellip;', 'woocommerce' ) .'</option>';

            foreach ( $states as $ckey => $cvalue )
                $field .= '<option value="' . esc_attr( $ckey ) . '" '.selected( $value, $ckey, false ) .'>'.__( $cvalue, 'woocommerce' ) .'</option>';

            $field .= '</select>';
            $field .= '</div>' . $after;

        } else {

            $field  = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';
            $field .= '<input type="text" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" value="' . esc_attr( $value ) . '"  placeholder="' . esc_attr( $args['placeholder'] ) . '" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" ' . implode( ' ', $custom_attributes ) . ' />';
            $field .= '</div>' . $after;

        }

        break;
    case "textarea" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required  . '</label>';

        $field .= '<textarea name="' . esc_attr( $key ) . '" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '"' . ( empty( $args['custom_attributes']['rows'] ) ? ' rows="2"' : '' ) . ( empty( $args['custom_attributes']['cols'] ) ? ' cols="5"' : '' ) . implode( ' ', $custom_attributes ) . '>'. esc_textarea( $value  ) .'</textarea>
            </div>' . $after;

        break;
    case "checkbox" :

        $field = '<div class="checkbox form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">
                <label for="' . esc_attr( $key ) . '" class="checkbox ' . implode( ' ', $args['label_class'] ) .'" ' . implode( ' ', $custom_attributes ) . '>
                    <input type="' . esc_attr( $args['type'] ) . '" class="input-checkbox" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" value="1" '.checked( $value, 1, false ) .' />'
                    . $args['label'] . $required . '</label>
            </div>' . $after;

        break;
    case "password" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';

        $field .= '<input type="password" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
            </div>' . $after;

        break;
    case "text" :

        $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

        if ( $args['label'] )
            $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label'] . $required . '</label>';

        $field .= '<input type="text" class="form-control input-text ' . implode( ' ', $args['input_class'] ) .'" name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" placeholder="' . esc_attr( $args['placeholder'] ) . '" '.$args['maxlength'].' value="' . esc_attr( $value ) . '" ' . implode( ' ', $custom_attributes ) . ' />
            </div>' . $after;

        break;
    case "select" :

        $options = '';

        if ( ! empty( $args['options'] ) )
            foreach ( $args['options'] as $option_key => $option_text )
                $options .= '<option value="' . esc_attr( $option_key ) . '" '. selected( $value, $option_key, false ) . '>' . esc_attr( $option_text ) .'</option>';

            $field = '<div class="form-group form-row ' . esc_attr( implode( ' ', $args['class'] ) ) .'" id="' . esc_attr( $key ) . '_field">';

            if ( $args['label'] )
                $field .= '<label for="' . esc_attr( $key ) . '" class="' . implode( ' ', $args['label_class'] ) .'">' . $args['label']. $required . '</label>';

            $field .= '<select name="' . esc_attr( $key ) . '" id="' . esc_attr( $key ) . '" class="select form-control" ' . implode( ' ', $custom_attributes ) . '>
                    ' . $options . '
                </select>
            </div>' . $after;

        break;
    default :

        $field = apply_filters( 'woocommerce_form_field_' . $args['type'], '', $key, $args, $value );

        break;
    }

    if ( $args['return'] ) return $field; else echo $field;
}

N'oubliez pas de remplacer toutes les occurrences de woocommerce_form_field avec bootstrap_woocommerce_form_field J'espère que ça aide!

3
abhisek