WooCommerce自定义在结账时创建帐户的复选框

huangapple go评论64阅读模式
英文:

WooCommerce custom create account checkbox on checkout

问题

以下是您要翻译的代码部分:

// Move Account password field into billing section
function move_password_field($checkout_fields){
    // Move Account Password into Billing
    $checkout_fields['billing']['account_password'] = $checkout_fields['account']['account_password']; 

    // Remove Password from Billing
    unset($checkout_fields['account']['account_password']);

    return $checkout_fields;
}

add_filter('woocommerce_checkout_fields', 'move_password_field', 999); 

// CSS rules
add_action( 'woocommerce_before_checkout_billing_form', 'move_checkout_create_an_account_css' );
function move_checkout_create_an_account_css() {
    if( ! is_user_logged_in() ) :
    ?><style>
        .woocommerce-account-fields label.woocommerce-form__label-for-checkbox {display: none !important;}
        #account_cb_field {margin-top: 32px;}
        #account_cb_field input {margin-right: 6px;}
    </style>
    <?php
    endif;
}

// Add a checkbox to billing section
add_filter( 'woocommerce_checkout_fields', 'move_checkout_create_an_account_checkbox' );
function move_checkout_create_an_account_checkbox( $fields ) {
    if( ! is_user_logged_in() ) {
        // Make email field on half on left side
        $fields['billing']['billing_email']['class'] = array('form-row-wide');

        // Custom checkbox on half right side
        $fields['billing']['account_cb'] = array(
            'type'  => 'checkbox',
            'label' => __("Create an account?", "woocommerce"),
            'class' => array('form-row-wide'),
        );
    }
    return $fields;
}

// remove "(optional)" from the new checkbox
add_filter( 'woocommerce_form_field' , 'remove_checkout_optional_fields_label', 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    // Only on checkout page
    if ( is_checkout() && ! is_wc_endpoint_url() && $key === 'account_cb' ) {
        $optional = '&nbsp;<span class="optional">' . esc_html__( 'optional', 'woocommerce' ) . '</span>';
        $field = str_replace( $optional, '', $field );
    }
    return $field;
}

// The jQuery code
add_action( 'wp_footer', 'move_checkout_create_an_account_js' );
function move_checkout_create_an_account_js() {
    if ( ! is_user_logged_in() && is_checkout() && ! is_wc_endpoint_url() ) :
    ?><script>
    (function($){
        $('input[name=account_cb]').on( 'click', function() {
            $('input[name=createaccount]').trigger('click');
        });
    })(jQuery);
    </script>
    <?php
    endif;
}

希望这有所帮助。

英文:

We just moved and merged the WooCommerce account password field on the checkout page from the "Account" group to the "Billing" field group. This works nicely. Also, we create a new checkbox field and add this to the billing section. Without that, the "Create an account" checkbox will still be at the default position. To do so, we created a new checkbox with jQuery.

Thanks to the following articles:

With our current code, the moved password field is always visible. We want to have it the same way as WooCommerce default works. This means the password field should only be visible when the checkbox is active. WooCommerce by default has an excellent hide & Show CSS in place. However, I'm not able to use the identical CSS (or maybe script?!).

How can we connect the custom checkbox with the account password field?

// Move Account password field into billing section
function move_password_field($checkout_fields){
// Move Account Password into Billing
$checkout_fields[&#39;billing&#39;][&#39;account_password&#39;] = $checkout_fields[&#39;account&#39;][&#39;account_password&#39;]; 
// Remove Password from Billing
unset($checkout_fields[&#39;account&#39;][&#39;account_password&#39;]);
return $checkout_fields;
}
add_filter(&#39;woocommerce_checkout_fields&#39;, &#39;move_password_field&#39;, 999); 
// CSS rules
add_action( &#39;woocommerce_before_checkout_billing_form&#39;, &#39;move_checkout_create_an_account_css&#39; );
function move_checkout_create_an_account_css() {
if( ! is_user_logged_in() ) :
?&gt;&lt;style&gt;
.woocommerce-account-fields label.woocommerce-form__label-for-checkbox {display: none !important;}
#account_cb_field {margin-top: 32px;}
#account_cb_field input {margin-right: 6px;}
&lt;/style&gt;
&lt;?php
endif;
}
// Add a checkbox to billing section
add_filter( &#39;woocommerce_checkout_fields&#39;, &#39;move_checkout_create_an_account_checkbox&#39; );
function move_checkout_create_an_account_checkbox( $fields ) {
if( ! is_user_logged_in() ) {
// Make email field on half on left side
$fields[&#39;billing&#39;][&#39;billing_email&#39;][&#39;class&#39;] = array(&#39;form-row-wide&#39;);
// Custom checkbox on half right side
$fields[&#39;billing&#39;][&#39;account_cb&#39;] = array(
&#39;type&#39;  =&gt; &#39;checkbox&#39;,
&#39;label&#39; =&gt; __(&quot;Create an account?&quot;, &quot;woocommerce&quot;),
&#39;class&#39; =&gt; array(&#39;form-row-wide&#39;),
);
}
return $fields;
}
// remove &quot;(optional)&quot; from the new checkbox
add_filter( &#39;woocommerce_form_field&#39; , &#39;remove_checkout_optional_fields_label&#39;, 10, 4 );
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
// Only on checkout page
if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() &amp;&amp; $key === &#39;account_cb&#39; ) {
$optional = &#39;&amp;nbsp;&lt;span class=&quot;optional&quot;&gt;(&#39; . esc_html__( &#39;optional&#39;, &#39;woocommerce&#39; ) . &#39;)&lt;/span&gt;&#39;;
$field = str_replace( $optional, &#39;&#39;, $field );
}
return $field;
}
// The jQuery code
add_action( &#39;wp_footer&#39;, &#39;move_checkout_create_an_account_js&#39; );
function move_checkout_create_an_account_js() {
if ( ! is_user_logged_in() &amp;&amp; is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) :
?&gt;&lt;script&gt;
(function($){
$(&#39;input[name=account_cb]&#39;).on( &#39;click&#39;, function() {
$(&#39;input[name=createaccount]&#39;).trigger(&#39;click&#39;);
});
})(jQuery);
&lt;/script&gt;
&lt;?php
endif;
}

答案1

得分: 3

这是您提供的代码的翻译部分:

// 移动账户密码字段到结算部分
function move_password_field( $checkout_fields ) {
    // 如果已登录,则不执行
    if ( is_user_logged_in() ) {
        return $checkout_fields;
    }
    // 如果未登录,则将账户密码字段移动到结算部分
    $checkout_fields['billing']['account_password'] = $checkout_fields['account']['account_password'];
    $checkout_fields['billing']['account_password'] = array(
        'label'       => __( '密码', 'woocommerce' ), // 添加自定义字段标签
        'placeholder' => _x( '密码', '占位符', 'woocommerce' ), // 添加自定义字段占位符
        'clear'       => false, // 是否清除字段
        'type'        => 'text', // 添加字段类型
    );
    unset( $checkout_fields['account']['account_password'] );
    return $checkout_fields;
}
add_filter( 'woocommerce_checkout_fields', 'move_password_field', 999 );

// 在结算部分添加复选框
function move_checkout_create_an_account_checkbox( $fields ) {
    if ( is_user_logged_in() ) {
        return $fields;
    }
    // 将电子邮件字段设置为左侧一半
    $fields['billing']['billing_email']['class'] = array( 'form-row-wide' );
    // 在右侧添加自定义复选框
    $fields['billing']['account_cb'] = array(
        'type'        => 'checkbox',
        'label'       => __( '创建帐户?', 'woocommerce' ),
        'placeholder' => _x( '创建帐户?', '占位符', 'woocommerce' ),
        'class'       => array( 'form-row-wide' ),
    );
    return $fields;
}
add_filter( 'woocommerce_checkout_fields', 'move_checkout_create_an_account_checkbox' );

// 从新复选框中删除“(可选)”文本
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
    // 仅在结算页面执行
    if ( is_checkout() && ! is_wc_endpoint_url() && ( $key === 'account_cb' || 'account_password' === $key ) ) {
        $optional = '&nbsp;<span class="optional">(' . esc_html__( '可选', 'woocommerce' ) . ')</span>';
        $field    = str_replace( $optional, '', $field );
    }
    return $field;
}
add_filter( 'woocommerce_form_field', 'remove_checkout_optional_fields_label', 10, 4 );

/**
 * 在结算提交时验证密码字段是否已选中
 *
 * @return void
 * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
 */
function woocomerce_validate_pass($fields, $errors): void {
    if ( isset( $_POST['account_cb'] ) && empty( $_POST['account_password'] ) ) {
        $errors->add( 'validation', '请输入密码。' );
    }
}
add_action( 'woocommerce_after_checkout_validation', 'woocomerce_validate_pass', 10, 2 );

// jQuery代码
add_action( 'wp_footer', 'move_checkout_create_an_account_js' );
function move_checkout_create_an_account_js() {
    if ( ! is_user_logged_in() && is_checkout() && ! is_wc_endpoint_url() ) :
        ?>
        <script>
        (function($) {
            // 可重用的函数,如果需要,可用于处理结算字段
            const toggleElmVisibility = (selector = '', show = true, duration = 200) => {
                if (show) {
                    $(selector).show(duration, () => {
                        $(selector).addClass("validate-required");
                    });
                } else {
                    $(selector).hide(duration, () => {
                        $(selector).removeClass("validate-required");
                    });
                }
                $(selector).removeClass("woocommerce-validated");
                $(selector).removeClass("woocommerce-invalid woocommerce-invalid-required-field");
            }

            // 在页面加载时隐藏密码字段,除非他们已选中复选框
            toggleElmVisibility('#account_password_field', $('#account_cb').is(':checked'));

            $('#account_cb').on('change', function() {
                toggleElmVisibility('#account_password_field', $(this).is(':checked'));
            });

            $('input[name=account_cb]').on('click', function() {
                $('input[name=createaccount]').trigger('click');
            });
        })(jQuery);
        </script>
        <?php
    endif;
}

这是您提供的代码的翻译。如果您有任何其他问题,请随时提问。

英文:

there are a fair few issues with that code
namely Warning: Undefined array key &quot;account_password&quot; in /var/www/html/wp-content/themes/storefront/functions.php

but here is the solution to your initial problem

// The jQuery code
add_action( &#39;wp_footer&#39;, &#39;move_checkout_create_an_account_js&#39; );
function move_checkout_create_an_account_js() {
	if ( ! is_user_logged_in() &amp;&amp; is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) :
		?&gt;
	&lt;script&gt;
	(function($) {
		// re-usable function to play around with the checkout fields if needed in the
		// future
		const toggleElmVisibility = (selector = &#39;&#39;, show = true, duration = 200) =&gt; {
			if (show) {
				$(selector).show(duration);
				return;
			}
			$(selector).hide(duration);
		}

		// hide password fields on page load, unless they have alredy checked the checkbox
		toggleElmVisibility(&#39;#account_password_field&#39;, $(&#39;#account_cb&#39;).is(&#39;:checked&#39;));

		$(&#39;#account_cb&#39;).on(&#39;change&#39;, function() {
			toggleElmVisibility(&#39;#account_password_field&#39;, $(this).is(&#39;:checked&#39;));
		});



		$(&#39;input[name=account_cb]&#39;).on(&#39;click&#39;, function() {
			$(&#39;input[name=createaccount]&#39;).trigger(&#39;click&#39;);
		});
	})(jQuery);
	&lt;/script&gt;
		&lt;?php
	endif;
}

Edit:

Changes to function to add the password field

// Move Account password field into billing section
function move_password_field( $checkout_fields ) {
	//bail if not logged in
	if ( is_user_logged_in() ) {
		return $checkout_fields;
	}
	// Move Account Password into Billing if not logged in
	$checkout_fields[&#39;billing&#39;][&#39;account_password&#39;] = $checkout_fields[&#39;account&#39;][&#39;account_password&#39;];
	$checkout_fields[&#39;billing&#39;][&#39;account_password&#39;] = array(
		&#39;label&#39;       =&gt; __( &#39;Password&#39;, &#39;woocommerce&#39; ), // Add custom field label
		&#39;placeholder&#39; =&gt; _x( &#39;Password&#39;, &#39;placeholder&#39;, &#39;woocommerce&#39; ), // Add custom field placeholder
		&#39;clear&#39;       =&gt; false, // add clear or not
		&#39;type&#39;        =&gt; &#39;text&#39;, // add field type
	);
	unset( $checkout_fields[&#39;account&#39;][&#39;account_password&#39;] );
	return $checkout_fields;
} add_filter( &#39;woocommerce_checkout_fields&#39;, &#39;move_password_field&#39;, 999 );

change the remove optional text function to catch the new field

// remove &quot;(optional)&quot; from the new checkbox
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
	// Only on checkout page
	if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() &amp;&amp; ( $key === &#39;account_cb&#39; || &#39;account_password&#39; === $key ) ) {
		$optional = &#39;&amp;nbsp;&lt;span class=&quot;optional&quot;&gt;(&#39; . esc_html__( &#39;optional&#39;, &#39;woocommerce&#39; ) . &#39;)&lt;/span&gt;&#39;;
		$field    = str_replace( $optional, &#39;&#39;, $field );
	}
	return $field;
} add_filter( &#39;woocommerce_form_field&#39;, &#39;remove_checkout_optional_fields_label&#39;, 10, 4 );

submit validation

/**
 * Validate the password field if checkbox is checked on checkout submit
 *
 * @return void
 * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
 */
function woocomerce_validate_pass(): void {
	if ( isset( $_POST[&#39;account_cb&#39;] ) &amp;&amp; empty( $_POST[&#39;account_password&#39;] ) ) {
		wc_add_notice( __( &#39;Please enter a password.&#39;, &#39;woocommerce&#39; ), &#39;error&#39; );
	}
} add_action( &#39;woocommerce_after_checkout_validation&#39;, &#39;woocomerce_validate_pass&#39; );

and changes to js to pickup that the field is required

	(function($) {
		// re-usable function to play around with the checkout fields if needed in the
		const toggleElmVisibility = (selector = &#39;&#39;, show = true, duration = 200) =&gt; {
			if (show) {
				$(selector).show(duration, () =&gt; {
					$(selector).addClass(&quot;validate-required&quot;);
				});
			} else {
				$(selector).hide(duration, () =&gt; {
					$(selector).removeClass(&quot;validate-required&quot;);
				});
			}
			$(selector).removeClass(&quot;woocommerce-validated&quot;);
			$(selector).removeClass(&quot;woocommerce-invalid woocommerce-invalid-required-field&quot;);
		}

		// hide password fields on page load, unless they have alredy checked the checkbox
		toggleElmVisibility(&#39;#account_password_field&#39;, $(&#39;#account_cb&#39;).is(&#39;:checked&#39;));

		$(&#39;#account_cb&#39;).on(&#39;change&#39;, function() {
			toggleElmVisibility(&#39;#account_password_field&#39;, $(this).is(&#39;:checked&#39;));
		});

		$(&#39;input[name=account_cb]&#39;).on(&#39;click&#39;, function() {
			$(&#39;input[name=createaccount]&#39;).trigger(&#39;click&#39;);
		});
	})(jQuery);

the other functions have been removed, the complete code:


// Move Account password field into billing section
function move_password_field( $checkout_fields ) {
	//bail if not logged in
	if ( is_user_logged_in() ) {
		return $checkout_fields;
	}
	// Move Account Password into Billing if not logged in
	$checkout_fields[&#39;billing&#39;][&#39;account_password&#39;] = $checkout_fields[&#39;account&#39;][&#39;account_password&#39;];
	$checkout_fields[&#39;billing&#39;][&#39;account_password&#39;] = array(
		&#39;label&#39;       =&gt; __( &#39;Password&#39;, &#39;woocommerce&#39; ), // Add custom field label
		&#39;placeholder&#39; =&gt; _x( &#39;Password&#39;, &#39;placeholder&#39;, &#39;woocommerce&#39; ), // Add custom field placeholder
		&#39;clear&#39;       =&gt; false, // add clear or not
		&#39;type&#39;        =&gt; &#39;text&#39;, // add field type
	);
	unset( $checkout_fields[&#39;account&#39;][&#39;account_password&#39;] );
	return $checkout_fields;
} add_filter( &#39;woocommerce_checkout_fields&#39;, &#39;move_password_field&#39;, 999 );

// Add a checkbox to billing section
function move_checkout_create_an_account_checkbox( $fields ) {
	if ( is_user_logged_in() ) {
		return $fields;
	}
	// Make email field on half on left side
	$fields[&#39;billing&#39;][&#39;billing_email&#39;][&#39;class&#39;] = array( &#39;form-row-wide&#39; );
	// Custom checkbox on half right side
	$fields[&#39;billing&#39;][&#39;account_cb&#39;] = array(
		&#39;type&#39;        =&gt; &#39;checkbox&#39;,
		&#39;label&#39;       =&gt; __( &#39;Create an account?&#39;, &#39;woocommerce&#39; ),
		&#39;placeholder&#39; =&gt; _x( &#39;Create an account?&#39;, &#39;placeholder&#39;, &#39;woocommerce&#39; ),
		&#39;class&#39;       =&gt; array( &#39;form-row-wide&#39; ),
	);
	return $fields;
} add_filter( &#39;woocommerce_checkout_fields&#39;, &#39;move_checkout_create_an_account_checkbox&#39; );


// remove &quot;(optional)&quot; from the new checkbox
function remove_checkout_optional_fields_label( $field, $key, $args, $value ) {
	// Only on checkout page
	if ( is_checkout() &amp;&amp; ! is_wc_endpoint_url() &amp;&amp; ( $key === &#39;account_cb&#39; || &#39;account_password&#39; === $key ) ) {
		$optional = &#39;&amp;nbsp;&lt;span class=&quot;optional&quot;&gt;(&#39; . esc_html__( &#39;optional&#39;, &#39;woocommerce&#39; ) . &#39;)&lt;/span&gt;&#39;;
		$field    = str_replace( $optional, &#39;&#39;, $field );
	}
	return $field;
} add_filter( &#39;woocommerce_form_field&#39;, &#39;remove_checkout_optional_fields_label&#39;, 10, 4 );

/**
 * Validate the password field if checkbox is checked on checkout submit
 *
 * @return void
 * @see https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/
 */
function woocomerce_validate_pass($fields, $errors): void {
	if ( isset( $_POST[&#39;account_cb&#39;] ) &amp;&amp; empty( $_POST[&#39;account_password&#39;] ) ) {
$errors-&gt;add( &#39;validation&#39;, &#39;Please enter a password.&#39;);
	//	wc_add_notice( __( &#39;Please enter a password.&#39;, &#39;woocommerce&#39; ), &#39;error&#39; );
	}
} add_action( &#39;woocommerce_after_checkout_validation&#39;, &#39;woocomerce_validate_pass&#39;, 10, 2 );

// The jQuery code
add_action( &#39;wp_footer&#39;, &#39;move_checkout_create_an_account_js&#39; );
function move_checkout_create_an_account_js() {
	if ( ! is_user_logged_in() &amp;&amp; is_checkout() &amp;&amp; ! is_wc_endpoint_url() ) :
		?&gt;
	&lt;script&gt;
	(function($) {
		// re-usable function to play around with the checkout fields if needed in the
		const toggleElmVisibility = (selector = &#39;&#39;, show = true, duration = 200) =&gt; {
			if (show) {
				$(selector).show(duration, () =&gt; {
					$(selector).addClass(&quot;validate-required&quot;);
				});
			} else {
				$(selector).hide(duration, () =&gt; {
					$(selector).removeClass(&quot;validate-required&quot;);
				});
			}
			$(selector).removeClass(&quot;woocommerce-validated&quot;);
			$(selector).removeClass(&quot;woocommerce-invalid woocommerce-invalid-required-field&quot;);
		}

		// hide password fields on page load, unless they have alredy checked the checkbox
		toggleElmVisibility(&#39;#account_password_field&#39;, $(&#39;#account_cb&#39;).is(&#39;:checked&#39;));

		$(&#39;#account_cb&#39;).on(&#39;change&#39;, function() {
			toggleElmVisibility(&#39;#account_password_field&#39;, $(this).is(&#39;:checked&#39;));
		});

		$(&#39;input[name=account_cb]&#39;).on(&#39;click&#39;, function() {
			$(&#39;input[name=createaccount]&#39;).trigger(&#39;click&#39;);
		});
	})(jQuery);
	&lt;/script&gt;
		&lt;?php
	endif;
}

huangapple
  • 本文由 发表于 2023年2月18日 23:52:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/75494513.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定