Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wordpress - radio button checkout woocommerce show/hide required field

I'm Italian (sorry for my english) and I'm not a programmer.

I need to insert in my checkout woocommerce site, a radio button with two options to answer this question: "Sei un privato cittadino, un'azienda o un libero professionista?". These are the options: 1) Privato cittadino 2) Azienda o libero professionista

When users click on the first option, it has to show a required field: "codice fiscale". When users click on the second option, it has to show two required fields: "P.Iva" and "Ragione sociale". I've created the radio field with this code in form-billing.php:

    <div class="woocommerce-billing-fields">
    <?php if ( wc_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>
<?
if($key=='billing_first_name')
{
?>
<p>Sei un privato cittadino, un'azienda o un libero professionista?</p>
<input type="radio" name="choice" value="privato_cittadino">Privato cittadino
<input type="radio" name="choice" value="azienda_professionista">Azienda o libero professionista<br>
<?
}
?>
    <?php endif; ?>

It works properly, but now I don't know how can I create the required fields like I described. Can you help me step by step? Please, consider I'm not a programmer.

like image 933
Francesco Fazzari Avatar asked Sep 05 '16 19:09

Francesco Fazzari


People also ask

How do you make the fields required optional on the WooCommerce checkout page?

Inside the function, $fields['billing_phone']['required'] is assigned a “false” value implying that the field is not required or is optional. Adding the lines above to your child theme's function. php file will make the Phone field optional on the Checkout page, as depicted in the image below. There you go!

How do I manage checkout fields in WooCommerce?

There are three sets of Fields you can edit: Billing – Payment and billing address section of checkout (payment must be enabled) Shipping – Shipping section of checkout (shipping must be enabled) Additional – Appear after the billing and shipping sections of checkout, next to order notes (order notes must be enabled)

Can I customize WooCommerce checkout page?

The easiest way to customize checkout fields is to use the Checkout Field Editor plugin. This plugin provides a simple UI to move, edit, add, or remove any checkout fields. You can edit anything about the fields, including type, label, position, and more.


1 Answers

To answer the question, it will need to be done in 4 steps.

  1. Add 4 custom fields to the woocommerce checkout page. The way you have done it is not best practice and should be done through use of actions/filters.
  2. Validate the data when the request is made to the back-end, this is to make sure the user actually selected and entered what is required.
  3. Save the data to the order as post meta so it can be accessed later.
  4. Implement javascript toggle feature so that based on what the user selects for the first question, the related fields are then shown.

Adding custom fields to woocommerce checkout

You will need to find a suitable action for where you would like to add the fields. I would recommend using the action woocommerce_after_checkout_billing_form as it will display fields after all the personal/billing information.

if( !function_exists( 'custom_checkout_question_field' ) ) {
  /**
   * Add custom question field after the billing form fields
   *
   * @param Integer $order_id New order id
   */
  function custom_checkout_question_field( $checkout ) {

    echo "<div class='custom-question-field-wrapper custom-question-1'>";

    echo sprintf( '<p>%s</p>', __( "Sei un privato cittadino, un'azienda o un libero professionista?" ) );

    woocommerce_form_field( 'custom_question_field', array(
      'type'            => 'radio',
      'required'        => true,
      'class'           => array('custom-question-field', 'form-row-wide'),
      'options'         => array(
        'privato_cittadino'         => 'Privato cittadino',
        'azienda_professionista'    => 'Azienda o libero professionista',
      ),
    ), $checkout->get_value( 'custom_question_field' ) );

    woocommerce_form_field( 'custom_question_text_codice_fiscale', array(
      'type'            => 'text',
      'label'           => 'Codice Fiscale',
      'required'        => true,
      'class'           => array('custom-question-codice-fiscale-field', 'form-row-wide'),
    ), $checkout->get_value( 'custom_question_text_codice_fiscale' ) );

    woocommerce_form_field( 'custom_question_text_p_iva', array(
      'type'            => 'text',
      'label'           => 'P.Iva',
      'required'        => true,
      'class'           => array('custom-question-p-iva-field', 'form-row-wide'),
    ), $checkout->get_value( 'custom_question_text_p_iva' ) );

    woocommerce_form_field( 'custom_question_text_ragione_sociale', array(
      'type'            => 'text',
      'label'           => 'Ragione sociale',
      'required'        => true,
      'class'           => array('custom-question-ragione-sociale-field', 'form-row-wide'),
    ), $checkout->get_value( 'custom_question_text_ragione_sociale' ) );

    echo "</div>";

  }

  add_action( 'woocommerce_after_checkout_billing_form', 'custom_checkout_question_field' );
}

Javascript front-end toggle

You will need to add custom javascript in order to toggle the 3 additional fields depending on the question. I have created a php function which will output a html script tag with some javascript. This is then attached to the wp_footer action.

This is not recommended method and you should really separate it into a new file js and enqueue the file when needed.

See: https://codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts

if( !function_exists( 'custom_question_conditional_javascript' ) ) {
  function custom_question_conditional_javascript() {
    ?>
    <script type="text/javascript">
    (function() {

      // Check if jquery exists
      if(!window.jQuery) {
        return;
      };

      var $ = window.jQuery;

      $(document).ready(function() {

        var questionField       = $('.custom-question-field'),
            codiceFiscaleField  = $('.custom-question-codice-fiscale-field'),
            pIvaField           = $('.custom-question-p-iva-field'),
            ragioneSocialeField = $('.custom-question-ragione-sociale-field ');

        // Check that all fields exist
        if(
          !questionField.length ||
          !codiceFiscaleField.length ||
          !pIvaField.length ||
          !ragioneSocialeField.length
        ) {
          return;
        }

        function toggleVisibleFields() {
          var selectedAnswer = questionField.find('input:checked').val();

          if(selectedAnswer === 'privato_cittadino') {
            codiceFiscaleField.show();
            pIvaField.hide();
            ragioneSocialeField.hide();
          } else if(selectedAnswer === 'azienda_professionista') {
            codiceFiscaleField.hide();
            pIvaField.show();
            ragioneSocialeField.show();
          } else {
            codiceFiscaleField.hide();
            pIvaField.hide();
            ragioneSocialeField.hide();
          }
        }

        $(document).on('change', 'input[name=custom_question_field]', toggleVisibleFields);
        $(document).on('updated_checkout', toggleVisibleFields);

        toggleVisibleFields();

      });
    })();
    </script>
    <?php
  }

  add_action( 'wp_footer', 'custom_question_conditional_javascript', 1000 );
}

Getting fields from submitted post request

You will need to get the data from php $_POST array and also sanitise it to prevent sql injection or other malicious code. I have created a helper function which will grab all the fields by keys provided in an array and sanitise them using wordpress sanitize_text_field helper function.

This helper can then be used when validating and also adding post meta.

if( !function_exists( 'custom_checkout_question_get_field_values' ) ) {
  /**
   * Get all form field values based on user submitted post data
   *
   * @return Array Key/value pair of field values based on $_POST data
   */
  function custom_checkout_question_get_field_values() {
    $fields = [
      'custom_question_field'                       => '',
      'custom_question_text_codice_fiscale'     => '',
      'custom_question_text_p_iva'                => '',
      'custom_question_text_ragione_sociale'    => '',
    ];

    foreach( $fields as $field_name => $value ) {
      if( !empty( $_POST[ $field_name ] ) ) {
        $fields[ $field_name ] = sanitize_text_field( $_POST[ $field_name ] );
      } else {
        unset( $fields[ $field_name ] );
      }
    }

    return $fields;
  }
}

Validating fields on the back-end

Validation is important because front-end cannot be trusted, it is very easy for users to modify required fields on the front-end. You can use Woocommerce woocommerce_checkout_process action in order to validate the fields and add error messages if it does not meet what is required.

if( !function_exists( 'custom_checkout_question_field_validate' ) ) {
  /**
   * Custom woocommerce field validation to prevent user for completing checkout
   *
   * @param Integer $order_id New order id
   */
  function custom_checkout_question_field_validate() {
    $field_values = custom_checkout_question_get_field_values();

    if ( empty( $field_values['custom_question_field'] ) ) {
      wc_add_notice( 'Please select an answer for the question.', 'error' );
    }

    if (
      $field_values['custom_question_field'] === 'privato_cittadino' &&
      empty( $field_values['custom_question_text_codice_fiscale'] )
    ) {
      wc_add_notice( 'Please enter codice fiscale.', 'error' );
    }

    if (
      $field_values['custom_question_field'] === 'azienda_professionista' &&
      empty( $field_values['custom_question_text_p_iva'] )
    ) {
      wc_add_notice( 'Please enter p iva.', 'error' );
    }

    if (
      $field_values['custom_question_field'] === 'azienda_professionista' &&
      empty( $field_values['custom_question_text_ragione_sociale'] )
    ) {
      wc_add_notice( 'Please enter ragione sociale.', 'error' );
    }

  }

  add_action( 'woocommerce_checkout_process', 'custom_checkout_question_field_validate' );
}

Saving custom post meta to the order

You can use the woocommerce woocommerce_checkout_update_order_meta action in order to save additional post meta to the order post type. Here we will use the helper function custom_checkout_question_get_field_values created above to get all fields from php $_POST array and also sanitize them before saving each one to the post meta.

if( !function_exists( 'custom_checkout_question_field_save' ) ) {
  /**
   * Update order post meta based on submitted form values
   *
   * @param Integer $order_id New order id
   */
  function custom_checkout_question_field_save( $order_id ) {
    $field_values = custom_checkout_question_get_field_values();

    foreach( $field_values as $field_name => $value ) {
      if( !empty( $field_values[ $field_name ] ) ) {
        update_post_meta( $order_id, $field_name, $value );
      }
    }
  }

  add_action( 'woocommerce_checkout_update_order_meta', 'custom_checkout_question_field_save' );
}
like image 131
Tameem Safi Avatar answered Oct 12 '22 22:10

Tameem Safi