【问题标题】:Make Woocommerce checkout phone field optional based on shipping country根据发货国家/地区将 Woocommerce 结帐电话字段设为可选
【发布时间】:2019-08-07 22:53:55
【问题描述】:

在 Woocommerce 结帐中,我正在尝试使特定发货国家/地区不需要电话字段。基于 "Make checkout phone field optional for specific countries in WooCommerce" 答案代码,它工作正常,我尝试进行一些更改以使此代码适用于 shipping 国家而不是 billing 国家。

经过多次尝试,我无法弄清楚如何让它发挥作用。

任何帮助都会很棒,非常感谢。

【问题讨论】:

    标签: php jquery wordpress woocommerce checkout


    【解决方案1】:

    非常感谢@LoicTheAztec 的原始答案,但是该解决方案现在给出了不稳定的结果,只是在必需和可选状态(开/关)之间交替切换电话字段。

    最初的答案也没有考虑到只使用账单地址并且没有输入单独的送货地址或送货地址的客户。

    请查看以下 2019 年的更新版本

    // SETTINGS: The countries codes (2 capital letters) in the array
    function defined_countries_for_phone_field(){
        return array( 'GB', 'JE', 'GG', 'IM' );
    }
    
    // Remove "(optional)" from non required "Billing phone" field
    add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
    function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address for billing phone field
        if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
        && in_array($shipping_country, $countries) ) || is_checkout() ) ) {
            $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
            $field = str_replace( $optional, '', $field );
        }
        return $field;
    }
    
    // Make the billing phone field optional (by default)
    add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
    function filter_billing_phone_field( $fields ) {
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Get Customer shipping country
        $shipping_country = WC()->customer->get_shipping_country();
    
        // Only on checkout page and My account > Edit address
        if ( ( is_wc_endpoint_url( 'edit-address' )
        && in_array($shipping_country, $countries) ) || is_checkout() )
            $fields['billing_phone']['required'] = false;
    
        return $fields;
    }
    
    // Real time shipping country selection actions
    add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
    function custom_checkout_scripts_and_fields( $checkout ) {
        $required = esc_attr__( 'required', 'woocommerce' );
    
        // Get the defined countries codes
        $countries = defined_countries_for_phone_field();
    
        // Hidden field for the phone number validation
        echo '<input type="hidden"  name="billing_phone_check" id="billing_phone_check" value="0">';
        $countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
        ?>
        <script type="text/javascript">
            (function($){
                var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>';
                var countries = [<?php echo $countries_str; ?>];
                    if($('.shipping_address').is(':visible')) {
                        // ship to different country selected
                        var selectedcountry = $('#shipping_country option:selected').val();
                    } else {
                        var selectedcountry = $('#billing_country option:selected').val();
                    }
                 //var selectedcountry = $('#shipping_country option:selected').val();
                 var phoneCheck = 'input#billing_phone_check';
                 var phoneField = '#billing_phone_field';
    
                function actionRequire( actionToDo='yes', selector='' ){
                    if ( actionToDo == 'yes' ) {
                        $(selector).addClass("validate-required");
                        $(selector+' label > .required').remove();
                        $(selector+' label').append(required);
                    } else {
                        $(selector).removeClass("validate-required");
                        $(selector+' label > .required').remove();
                    }
                    $(selector).removeClass("woocommerce-validated");
                    $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
                }
    
                // Default value Once DOM is loaded (with a 300 ms delay)
                setTimeout( function(){
                    if($('.shipping_address').is(':visible')) {
                        // ship to different country selected
                        var selectedcountry = $('#shipping_country option:selected').val();
                    } else {
                        var selectedcountry = $('#billing_country option:selected').val();
                    }
                    actionRequire( 'no', phoneField );
                    if( $.inArray( selectedcountry, countries ) == -1){
                        actionRequire( 'yes',phoneField );
                        $(phoneCheck).val('1');
                    }
                }, 300 );
    
                // Live value
                $( 'form.checkout' ).on( 'change', '#billing_country, #shipping_country, #ship-to-different-address-checkbox', function(){
                    setTimeout( function(){
                        if($('.shipping_address').is(':visible')) {
                            // ship to different country selected
                            var selectedcountry = $('#shipping_country option:selected').val();
                        } else {
                            var selectedcountry = $('#billing_country option:selected').val();
                        }
    
                        if ( $.inArray( selectedcountry, countries ) == -1) {
                            actionRequire( 'yes' ,phoneField );
                            $(phoneCheck).val('1');
                        } else {
                            actionRequire( 'no' ,phoneField );
                            $(phoneCheck).val('0');
                        }
                    }, 300 );
                });
           })(jQuery);
            </script>
        <?php
    }
    
    // Phone number validation, when the field is required
    add_action('woocommerce_checkout_process', 'billing_phone_field_process');
    function billing_phone_field_process() {
        // Check if set, if its not set add an error.
        if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
            wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
    }
    

    【讨论】:

      【解决方案2】:

      以下代码将使计费电话字段仅适用于特定的“送货”国家/地区。

      自 Woocommerce 3.4+ 版以来,Woocommerce 表单字段发生了一些变化,因此需要额外的功能和代码。

      我还扩展了代码以处理“我的帐户”>“编辑地址”中的电话字段行为,客户可以在其中更改其帐户数据。

      这是完整的代码(在第一个函数中定义你的国家代码)

      // SETTINGS: The countries codes (2 capital letters) in the array
      function defined_countries_for_phone_field(){
          return array( 'UK', 'BE', 'GE', 'IT', 'ES' );
      }
      
      // Remove "(optional)" from non required "Billing phone" field
      add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
      function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
      
          // Get the defined countries codes
          $countries = defined_countries_for_phone_field();
      
          // Get Customer shipping country
          $shipping_country = WC()->customer->get_shipping_country();
      
          // Only on checkout page and My account > Edit address for billing phone field
          if( 'billing_phone' === $key && ( ( is_wc_endpoint_url( 'edit-address' )
          && ! in_array($shipping_country, $countries) ) || is_checkout() ) ) {
              $optional = '&nbsp;<span class="optional">(' . esc_html__( 'optional', 'woocommerce' ) . ')</span>';
              $field = str_replace( $optional, '', $field );
          }
          return $field;
      }
      
      // Make the billing phone field optional (by default)
      add_filter( 'woocommerce_billing_fields', 'filter_billing_phone_field', 10, 1 );
      function filter_billing_phone_field( $fields ) {
      
          // Get the defined countries codes
          $countries = defined_countries_for_phone_field();
      
          // Get Customer shipping country
          $shipping_country = WC()->customer->get_shipping_country();
      
          // Only on checkout page and My account > Edit address
          if ( ( is_wc_endpoint_url( 'edit-address' )
          && ! in_array($shipping_country, $countries) ) || is_checkout() )
              $fields['billing_phone']['required'] = false;
      
          return $fields;
      }
      
      // Real time shipping country selection actions
      add_action( 'woocommerce_after_order_notes', 'custom_checkout_scripts_and_fields', 10, 1 );
      function custom_checkout_scripts_and_fields( $checkout ) {
          $required = esc_attr__( 'required', 'woocommerce' );
      
          // Get the defined countries codes
          $countries = defined_countries_for_phone_field();
      
          // Hidden field for the phone number validation
          echo '<input type="hidden"  name="billing_phone_check" id="billing_phone_check" value="0">';
          $countries_str = "'".implode( "', '", $countries )."'"; // Formatting countries for jQuery
          ?>
          <script type="text/javascript">
              (function($){
                  var required = '<abbr class="required" title="<?php echo $required; ?>">*</abbr>',
                      countries = [<?php echo $countries_str; ?>],
                      location = $('#shipping_country option:selected').val(),
                      phoneCheck = 'input#billing_phone_check',
                      phoneField = '#billing_phone_field';
      
                  function actionRequire( actionToDo='yes', selector='' ){
                      if ( actionToDo == 'yes' ) {
                          $(selector).addClass("validate-required");
                          $(selector+' label').append(required);
                      } else {
                          $(selector).removeClass("validate-required");
                          $(selector+' label > .required').remove();
                      }
                      $(selector).removeClass("woocommerce-validated");
                      $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
                  }
      
                  // Default value Once DOM is loaded (with a 300 ms delay)
                  setTimeout( function(){
                      actionRequire( 'no', phoneField );
                      if( $.inArray( location, countries ) >= 0  && $(phoneCheck).val() == '0' ){
                          actionRequire( 'yes',phoneField );
                          $(phoneCheck).val('1');
                      }
                  }, 300 );
      
                  // Live value
                  $( 'form.checkout' ).on( 'change', '#shipping_country', function(){
                      var location = $('#shipping_country option:selected').val();
                      if ( $.inArray( location, countries ) >= 0 && $(phoneCheck).val() == 0 ) {
                          actionRequire( 'yes' ,phoneField );
                          $(phoneCheck).val('1');
                      } else if ( $(phoneCheck).val() == 1 ) {
                          actionRequire( 'no' ,phoneField );
                          $(phoneCheck).val('0');
                      }
                  });
             })(jQuery);
              </script>
          <?php
      }
      
      // Phone number validation, when the field is required
      add_action('woocommerce_checkout_process', 'billing_phone_field_process');
      function billing_phone_field_process() {
          // Check if set, if its not set add an error.
          if ( ! $_POST['billing_phone'] && $_POST['billing_phone_check'] == '1' )
              wc_add_notice( __( 'Please enter a number phone.' ), 'error' );
      }
      

      代码进入您的活动子主题(或活动主题)的 function.php 文件中。已在 WooCommerce 3.4 及更高版本中测试并运行。

      相关:

      【讨论】:

      • 现在给出不稳定的结果,不确定 WooCommerce 中是否发生了一些会发生冲突的变化,但请查看我的答案以获取更新版本
      猜你喜欢
      • 2018-05-05
      • 2021-10-27
      • 1970-01-01
      • 2016-01-01
      • 1970-01-01
      • 2021-11-22
      • 2019-04-07
      • 1970-01-01
      • 2021-04-24
      相关资源
      最近更新 更多