4


I am working on my woocommerce e-shop and I would like to implement CSS "float labels" with https://github.com/tonystar/float-label-css for the checkout form fields, for better user experience. For this to work the<Label>has to come after the <Input>.
I can't seem to find a simple way to change the order in woocommerce.

The final code is generated by :

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

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

<?php endforeach; ?>

The function: woocommerce_form_field is a long code controlling the form generation the wc-template-functions.php. I think it is possible to achieve the result by changing code here, but would rather not change the long code in in this function though. Is there perhaps an easier way? I thought maybe if

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

could be modified to only generate the Input code first, then add a new line that only generates the <Label>, and loop these? I don't know how to do modify the above to only fetch label or input though (if even possible).
Any hints are much appreciated.

Martin
  • 63
  • 2
  • 8
  • Maybe use the filter [`woocommerce_form_field_' . $args['type']`](https://docs.woocommerce.com/wc-apidocs/source-function-woocommerce_form_field.html#1950) to filter the output of a particular field type? – helgatheviking Oct 18 '16 at 22:00
  • Thank you @helgatheviking . After your comment I saw one of your answers to a similar question some month ago [http://stackoverflow.com/a/39300503/6541251] The code you posted solved my problem. – Martin Oct 21 '16 at 20:08
  • @Martin, could you please share your resulting code snippet? I would like to publish it here: https://github.com/tonystar/float-label-css. Also, Float Label v1.0.1 allows you to nest inside – tonystar Oct 28 '16 at 17:12
  • @tonystar. please see my answer below. I will try v1.0.1 if it solves the issue I had. Thanks. – Martin Jan 06 '17 at 23:22

1 Answers1

0

@tonystar. I added a "has-float-label" class to each form-filed by changing the form-billing.php and form-shipping.php loop:

    <?php foreach ( $checkout->checkout_fields['billing'] as $key => $field ) : ?>
    <span class="has-float-label">
    <?php woocommerce_form_field( $key, $field, $checkout->get_value( $key ) ); ?>
    </span>

I enqued the float-label-css:

wp_enqueue_style( 'float-label-css', get_stylesheet_directory_uri() . '/bootstrap-float-label.min.css' )

Used the filter code that helgatheviking supplied in my functions.php:

function so_39267627_form_field( $field, $key, $args, $value ){

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

// 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 ) . '"';
    }
}

$field = '';
$label_id = $args['id'];
$field_container = '<p class="form-row %1$s" id="%2$s">%3$s</p>';

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

if ( ! empty( $field ) ) {
    $field_html = '';

    $field_html .= $field;

    if ( $args['description'] ) {
        $field_html .= '<span class="description">' . esc_html( $args['description'] ) . '</span>';
    }

    if ( $args['label'] && 'checkbox' != $args['type'] ) {
        $field_html .= '<label for="' . esc_attr( $label_id ) . '" class="' . esc_attr( implode( ' ', $args['label_class'] ) ) .'">' . $args['label'] . $required . '</label>';
    }

    $container_class = 'form-row ' . esc_attr( implode( ' ', $args['class'] ) );
    $container_id = esc_attr( $args['id'] ) . '_field';

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

    $field = sprintf( $field_container, $container_class, $container_id, $field_html ) . $after;
}
return $field; }

add_filter( 'woocommerce_form_field_password', 'so_39267627_form_field', 10, 4 );
add_filter( 'woocommerce_form_field_text', 'so_39267627_form_field', 10, 4 );
add_filter( 'woocommerce_form_field_email', 'so_39267627_form_field', 10, 4 );
add_filter( 'woocommerce_form_field_tel', 'so_39267627_form_field', 10, 4 );
add_filter( 'woocommerce_form_field_number', 'so_39267627_form_field', 10, 4 );

It got a bit difficult in the end because woocommerce? (or my theme?) is making some strange "data-o_class"es that messed up the city/postcode labels by adding the city and postcode under the same "span class". I didn't know how to solve this so I skipped using the float labels in the end. But it worked on all the other fields/labels with a really nice transition.

working float labels: working float labels

messed up city and postcode field labels: messed up city and postcode field labels

Martin
  • 63
  • 2
  • 8