WordPress: botón de opción para pagar woocommerce mostrar/ocultar campo obligatorio

7 minutos de lectura

avatar de usuario
francesco fazzari

Soy italiano (perdón por mi inglés) y no soy programador.

Necesito insertar en mi sitio de pago de woocommerce, un botón de radio con dos opciones para responder a esta pregunta: “Sei un privato cittadino, un’azienda o un libero professionista?”. Estas son las opciones: 1) Privato cittadino 2) Azienda o libero professionista

Cuando los usuarios hacen clic en la primera opción, debe mostrar un campo obligatorio: “codice fiscale”. Cuando los usuarios hacen clic en la segunda opción, debe mostrar dos campos obligatorios: “P.Iva” y “Ragione sociale”. Creé el campo de radio con este código en 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; ?>

Funciona correctamente, pero ahora no sé cómo puedo crear los campos obligatorios como describí. ¿Puedes ayudarme paso a paso? Por favor, considere que no soy un programador.

avatar de usuario
Tameem Safi

Para responder a la pregunta, será necesario hacerlo en 4 pasos.

  1. Agregue 4 campos personalizados a la página de pago de WooCommerce. La forma en que lo ha hecho no es la mejor práctica y debe hacerse mediante el uso de acciones/filtros.
  2. Valide los datos cuando se realiza la solicitud al back-end, esto es para asegurarse de que el usuario realmente seleccionó e ingresó lo que se requiere.
  3. Guarde los datos en el pedido como publicación meta para poder acceder a ellos más tarde.
  4. Implemente la función de alternancia de javascript para que, en función de lo que el usuario seleccione para la primera pregunta, se muestren los campos relacionados.

Agregar campos personalizados al pago de woocommerce

Deberá encontrar una acción adecuada para el lugar donde desea agregar los campos. Recomendaría usar la acción woocommerce_after_checkout_billing_form ya que mostrará campos después de toda la información personal/de facturación.

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

Alternar interfaz de Javascript

Deberá agregar javascript personalizado para alternar los 3 campos adicionales según la pregunta. He creado una función php que generará un html script etiqueta con algo de javascript. Luego se adjunta a la wp_footer acción.

Este no es un método recomendado y realmente debería separarlo en un nuevo archivo js y ponerlo en cola cuando sea necesario.

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

Obtener campos de la solicitud de publicación enviada

Necesitará obtener los datos de php $_POST array y también desinfectarlo para evitar la inyección de sql u otro código malicioso. Creé una función de ayuda que tomará todos los campos mediante las claves proporcionadas en una matriz y los desinfectará usando wordpress sanitize_text_field función auxiliar.

Este ayudante se puede usar al validar y también agregar meta 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;
  }
}

Validación de campos en el back-end

La validación es importante porque no se puede confiar en el front-end, es muy fácil para los usuarios modificar los campos obligatorios en el front-end. Puedes usar Woocommerce woocommerce_checkout_process acción para validar los campos y agregar mensajes de error si no cumple con lo requerido.

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

Guardar meta de publicación personalizada en el pedido

Puedes usar el woocommerce woocommerce_checkout_update_order_meta acción para guardar metadatos de publicación adicionales en el tipo de publicación de pedido. Aquí usaremos la función de ayuda custom_checkout_question_get_field_values creado arriba para obtener todos los campos de php $_POST array y también desinfectarlos antes de guardar cada uno en la publicación 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' );
}

¿Ha sido útil esta solución?