Добавить собственный класс css в поля оформления заказа WooCommerce

Я хотел бы иметь возможность добавить собственный класс CSS в поля оформления заказа WooCommerce. Я использую twitter Bootstrap и хотел бы иметь возможность использовать их класс .form-control.

Я просмотрел папку шаблонов woocommerce в form-billing.php, но я не уверен, где добавить класс .form-control в каждое текстовое поле.

Вот код для 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>

Нужно ли мне искать другой файл шаблона?

Спасибо


person NateW    schedule 29.05.2014    source источник


Ответы (4)


icc97 почти готов, но не работает.

Я взял ответ icc97 и отладил его:

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;
}
person Dan Smart    schedule 14.08.2014
comment
Что, если мы хотим добавить классы только к определенным типам ввода (например, к текстовым областям)? - person Peanuts; 07.04.2016
comment
Удалите public из этой функции. Это не метод - person kanlukasz; 07.01.2021
comment
У меня это работает. Проголосовать с моей стороны. - person user9437856; 27.01.2021

Как отметил @Peanuts, что, если мы хотим добавить классы CSS только к определенным типам ввода?

Поэкспериментировав с решениями, опубликованными здесь (спасибо всем!), Я придумал мод, использующий простой «случай переключения», в котором логика взята из /woocommerce/includes/wc-template-functions.php. Функция позволяет нам настроить таргетинг на все типы ввода одновременно, будь то типы ввода по умолчанию или даже пользовательские.

Нет необходимости переписывать woocommerce_form_field функцию, чтобы просто изменить $defaults аргументы для типов ввода. Следует отметить, что эта функция также позволяет нам добавлять в поля гораздо больше, чем просто классы CSS.

- Итак, вот функция -

/*********************************************************************************************/
/** 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;
}

Вышеупомянутая функция полностью решила проблему одновременного нацеливания всех входных данных формы оформления заказа, что действительно очевидно для типов ввода по умолчанию для формы оформления заказа или даже для новых пользовательских типов. Однако, похоже, невозможно распечатать каждый вывод html типа ввода без создания новой функции, как @abhisek показывает в своем ответе.

Бонус

Кажется, что эта функция также может влиять на другие поля форм, напечатанные функциями или шаблонами WooCommerce за пределами страницы оформления заказа. Мне удалось условно применить функцию только на странице оформления заказа с помощью функции is_page(). На вашей странице оформления заказа может быть другой ярлык, поэтому измените его, чтобы он отражался соответствующим образом.

Если вам нужно применить функцию только для страницы оформления заказа, сделайте следующее:

Комментарий add_filter ()

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

И вместо этого используйте add_action

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


}

После этого функция повлияет только на форму страницы оформления заказа.

person Adriano Monecchi    schedule 19.04.2016
comment
@Monecchi работает, но не влияет только на форму оформления заказа. Есть ли способ применить это только для формы оформления заказа и в то же время настроить таргетинг только на некоторые типы полей (ввод, текстовое поле, ...)? - person Sefran2; 22.02.2017
comment
@ Sefran2 Я не мог повторить это. На что еще влияет функция? Чтобы настроить таргетинг только на нужные поля, просто удалите ненужные случаи из функции switch(). - person Adriano Monecchi; 22.02.2017
comment
@ Sefran2 - После дальнейшего изучения действительно кажется, что эта функция влияет на другие формы woocommerce. Я только что проверил страницу оформления заказа с помощью функции is_page(), чтобы удалить фильтр, если это не страница оформления заказа. Я обновил функцию. - person Adriano Monecchi; 22.02.2017
comment
@AdrianoMonecchi: Если добавить комментарий к add_filter, что добавляется и удаляется в действии? Однако вы мне подсказали, и в фильтре я добавил if (is_checkout ()), и теперь все работает. Спасибо :) - person Sefran2; 23.02.2017
comment
@ Sefran2 Пожалуйста, проверьте бонусную часть ответа для объяснения. add_action() просто запускает функцию, которая, в свою очередь, выполняет условную проверку, находитесь ли вы на странице оформления заказа, а затем соответственно добавляет или удаляет фильтр. Я тестировал его на своем конце, и он работает. Затем вам нужно снова изменить функцию, чтобы настроить таргетинг только на нужные вам типы полей. Он не должен путаться с другими полями форм, напечатанными функциями или шаблонами woocommerce за пределами страницы оформления заказа. - person Adriano Monecchi; 23.02.2017

< / a> answer действительно дает вам то, что вы хотите, но, как всегда, они никогда не будут очень хорошими ответами.

Лучшим ресурсом для этого является страница кодекса WooCommerce на Настройка полей оформления заказа с помощью действий и фильтров.

В разделе «Настройка меток полей и текста-заполнителя WooCommerce Checkout» на странице Chetan у вас есть следующий код, который вам нужно добавить в свой functions.php, я изменил его таким образом, чтобы он делал то, что вы хотите, но я не тестировал код:

// 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;
}
person icc97    schedule 16.07.2014
comment
Вышеупомянутое не работает для меня. Вместо этого я подключил фильтр woocommerce_form_field_args, чтобы передать имя класса следующим образом: add_filter('woocommerce_form_field_args','wc_form_field_args',10,3); function wc_form_field_args($args, $key, $value) { $args['input_class'][] = 'form-control'; return $args; } - person Adriano Monecchi; 14.04.2016
comment
@AdrianoMonecchi см. ответ Дэна Смарта - он отладил мой ответ - person icc97; 14.04.2016

Я решил проблему, определив пользовательскую функцию. Логика взята непосредственно из wc-template-functions.php (я не уверен, что это правильный путь, но он решает проблему).

/*
 * 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;
}

Не забудьте заменить все вхождения woocommerce_form_field на bootstrap_woocommerce_form_field. Надеюсь, это поможет!

person abhisek    schedule 24.08.2014