重新排列Woocommerce结账字段

14

我正在尝试重新排列结账页面的账单字段,但到目前为止,我尝试过的所有方法都没有起作用。

这是我目前正在尝试的片段:

add_filter("woocommerce_checkout_fields", "order_fields");

function order_fields($fields) {
  $order = array(
    "billing_first_name", 
    "billing_last_name", 
    "billing_country", 
    "billing_state", 
    "billing_address_1", 
    "billing_address_2", 
    "billing_email", 
    "billing_phone"
  );

  foreach($order as $field) {
    $ordered_fields[$field] = $fields["billing"][$field];
  }

  $fields["billing"] = $ordered_fields;
  return $fields;
}

这段代码是否被其他东西覆盖了?因为它以前对我有用。

6个回答

39

你正在使用的方法已不再适用(自WooCommerce 3.0.4更新以来-链接到github问题在此处)。这不完全是一个错误,而是规格的变更。

要解决这个问题,你只需要调整每个字段的优先级,以适应你想要的顺序即可。

add_filter("woocommerce_checkout_fields", "custom_override_checkout_fields", 1);
function custom_override_checkout_fields($fields) {
    $fields['billing']['billing_first_name']['priority'] = 1;
    $fields['billing']['billing_last_name']['priority'] = 2;
    $fields['billing']['billing_company']['priority'] = 3;
    $fields['billing']['billing_country']['priority'] = 4;
    $fields['billing']['billing_state']['priority'] = 5;
    $fields['billing']['billing_address_1']['priority'] = 6;
    $fields['billing']['billing_address_2']['priority'] = 7;
    $fields['billing']['billing_city']['priority'] = 8;
    $fields['billing']['billing_postcode']['priority'] = 9;
    $fields['billing']['billing_email']['priority'] = 10;
    $fields['billing']['billing_phone']['priority'] = 11;
    return $fields;
}

add_filter( 'woocommerce_default_address_fields', 'custom_override_default_locale_fields' );
function custom_override_default_locale_fields( $fields ) {
    $fields['state']['priority'] = 5;
    $fields['address_1']['priority'] = 6;
    $fields['address_2']['priority'] = 7;
    return $fields;
}
请注意,调整顺序的不是代码中的行,而是分配给字段的优先级。在这种情况下,我将['billing_state']的优先级更改为5,这是在['billing_country']之后,在['billing_address_1']之前(在本例中)。

编辑:

根据评论,由于某些原因,此方法未能生效(在我第一次测试WooCommerce安装时可以正常工作,但在更改商店位置后失败了)。

经过一番探索,我发现默认语言环境设置会叠加到覆盖上面(不确定如何解释,但请耐心等待)。

我成功运行了一个未能使用上述代码的安装程序,并通过添加以下代码进行修复:

add_filter( 'woocommerce_default_address_fields', 'custom_override_default_locale_fields' );
function custom_override_default_locale_fields( $fields ) {
    $fields['state']['priority'] = 5;
    $fields['address_1']['priority'] = 6;
    $fields['address_2']['priority'] = 7;
    return $fields;
}

我已经在第一个代码块中添加了额外的片段,以验证整个代码块。


$fields['billing']['billing_first_name']['priority'] = 1; $fields['billing']['billing_last_name']['priority'] = 2; $fields['billing']['billing_country']['priority'] = 3; $fields['billing']['billing_state']['priority'] = 4; $fields['billing']['billing_address_1']['priority'] = 5; $fields['billing']['billing_address_2']['priority'] = 6; $fields['billing']['billing_phone']['priority'] = 7; $fields['billing']['billing_email']['priority'] = 8; --这将按照以下顺序显示字段:名字,姓氏,国家,电话,邮件,地址1,地址2,州。 - Yahya Hussein
@YahyaHussein 可能有另一个函数执行相同的操作(可能在您的主题文件或其他插件中)。我的建议是将过滤器的优先级调整为类似于 add_filter("woocommerce_checkout_fields", "custom_override_checkout_fields", 999); 这样的值,以便它在任何潜在的重复函数之后运行。 - Frits
1
@YahyaHussein,我终于成功地复制了你的问题,并编辑了我的答案以包含一个额外的片段来帮助解决。看一下并告诉我 :) - Frits
它起作用了,谢谢你。 如果您能对原因和如何解决问题提供更多说明,那就太好了。 - Yahya Hussein

3
正如@Byeongin在他的答案中正确提到的,除了后端排序之外(@Frits的答案涵盖了此部分),当用户从下拉菜单中选择特定国家时,前端还会通过JavaScript进行排序。
如果您也想阻止这种前端重新排序发生,则目前我遇到的最好解决方案是钩入“woocommerce_get_country_locale”过滤器并删除其中添加的优先级覆盖。像以下代码一样即可解决问题(已使用WooCommerce v3.5.4进行测试):
add_filter( 'woocommerce_get_country_locale', function( $locale ) {
    foreach ( $locale as $country_code => $locale_fields ) {
        foreach ( $locale_fields as $field_key => $field_options ) {
            if ( isset( $field_options['priority'] ) ) {
                unset( $field_options['priority'] );
            }

            $locale[ $country_code ][ $field_key ] = $field_options;
        }
    }

    return $locale;
} );


只有当您的商店仅向一个国家运送货物时,才应执行此操作。当用户选择不同的国家时,WooCommerce会更改地址字段的顺序,以匹配用户对于语言环境的期望,因为每个国家的地址都是不同的。JavaScript(address-i18n.js / country.js)按其特定于国家的优先级对字段进行排序。 - sun
@sun 我同意你的观点 - 在销售给多个国家时,重新排列地址字段可能会引起结账过程中的用户体验问题。我上面发布的解决方案应该只在您了解其与用户体验相关的回退并且确定自己知道自己在做什么时使用。感谢您提出这个问题。 - psymeons
我已经寻找这个很久了,谢谢!这太烦人了,为什么让我覆盖订单,然后在前端撤销它?太令人沮丧了... - Xriuk

3

排序(sorting)是在address-i18n.min.js中工作,而不是在php代码中。

enter image description here

在我的情况下,我在我的js代码上做错了什么。因此,排序没有正常工作(javascript停在那里)。

请检查开发控制台和js错误。

这是只更改优先级的php代码。

function rpf_edit_default_address_fields($fields) {

  /* ------ reordering ------ */
  $fields['country']['priority'] = 10;
  $fields['first_name']['priority'] = 20;
  $fields['last_name']['priority'] = 30;
  $fields['address_1']['priority'] = 40;
  $fields['address_2']['priority'] = 50;
  $fields['city']['priority'] = 60;
  $fields['state']['priority'] = 70;
  $fields['postcode']['priority'] = 80;

  return $fields;
}
add_filter( 'woocommerce_default_address_fields', 'rpf_edit_default_address_fields', 100, 1 );

Good Luck!


3
为了更改woocommerce结账字段,您需要根据显示更改字段顺序和所需类。您可以在functions.php中添加以下代码并使其生效。
add_filter("woocommerce_checkout_fields", "woocommerce_reorder_checkout_fields", 9999);

if ( ! function_exists( 'woocommerce_reorder_checkout_fields' ) ) {
    function woocommerce_reorder_checkout_fields( $fields ) {

        /* To reorder state field you need to add this array. */
        $order = array(
        "billing_first_name", 
        "billing_last_name", 
        "billing_country", 
        "billing_state", 
        "billing_address_1", 
        "billing_address_2", 
        "billing_email", 
        "billing_phone"
        );

        foreach($order as $field) {
        $ordered_fields[$field] = $fields["billing"][$field];
        }

        $fields["billing"] = $ordered_fields;

        /* To change email and phone number you have to add only class no need to add priority. */

        $fields['billing']['billing_email']['class'][0] = 'form-row-first';
        $fields['billing']['billing_phone']['class'][0] = 'form-row-last';

    return $fields;
    }
}

请查看附图:enter image description here 更多信息请参考此链接。涉及IT技术相关内容。

他们使用类和优先级解决的问题是样式!而不是顺序! - Yahya Hussein
是的,使用优先级可以更改显示顺序,因此我会更新我的答案。 - Mukesh Panchal
请问您能否发送您的实时网址? - Mukesh Panchal
请在以下网址中选择任意产品并进行结账:http://bazarplay.com/%D8%A7%D9%84%D9%85%D8%AA%D8%AC%D8%B1/ --我希望在结账时,账单州(billing_state)位于账单地址1(billing_address1)之前。 - Yahya Hussein
@YahyaHussein 当你说没有改变时,你是否彻底测试过?我已经测试过了,可以确认它是有效的... - Reigel Gallarde
@Reigel 对不起回复晚了,是的我测试过了,对我没有用。 - Yahya Hussein

1

对于 WooCommerce > 4.0 版本,您需要拥有一个优先级密钥,因为在打印数组之前会使用 asort 对其进行排序。

您可以这样做:

function order_fields( $fields ) {
    $i = 0;

    $order = array(
        "billing_email",
        "billing_customfield", <- this is your custom field
        "billing_company",
        "billing_cvr",
        "billing_ean",
        "billing_first_name",
        "billing_last_name",
        "billing_address_1",
        "billing_address_2",
        "billing_country",
        "billing_postcode",
        "billing_city",
        "billing_phone"
    );

    foreach ( $order as $field ) {
        $ordered_fields[ $field ] = $fields["billing"][ $field ];
        $ordered_fields[ $field ][ "priority" ] = ++$i;
    }

    $fields["billing"] = $ordered_fields;

    return $fields;

}

add_filter( "woocommerce_checkout_fields", "order_fields" );

这是一个可用的代码。谢谢! - B.M. Rafiul Alam

0

更改本地的 WooCommerce 类 这种方法对我有效。 实际上,WooCommerce 使用一个类:form-row-first(CSS:float left)和 form-row-last:float right。 如果您将优先级从2更改为1,但ccs类是form-row-last,则该字段仍将位于右侧。

add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields',1 );
function custom_override_checkout_fields( $fields ) {
    $fields['billing']['billing_email']['priority'] = 3;
    $fields['billing']['billing_email']['label'] = mb_strtoupper("adresse email");
    $fields['billing']['billing_email']['class'] = array('form-left');
    $fields['billing']['billing_company']['priority'] = 5;
    $fields['billing']['billing_company']['label'] = mb_strtoupper("entreprise");
    $fields['billing']['billing_company']['required'] = false;
    $fields['billing']['billing_company']['class'] = array('form-left');
    $fields['billing']['billing_phone']['priority'] = 6;
    $fields['billing']['billing_phone']['label'] = mb_strtoupper("téléphone");
    $fields['billing']['billing_phone']['required'] = false;
    $fields['billing']['billing_phone']['class'] = array('form-right');
    $fields['billing']['billing_phone']['validate'] = array('phone');
    $fields['shipping']['shipping_company']['priority'] = 3;
    $fields['shipping']['shipping_company']['label'] = mb_strtoupper("entreprise");
    $fields['shipping']['shipping_company']['required'] = false;
    $fields['shipping']['shipping_company']['class'] = array('form-left');

    return $fields;
}

其他字段如first_name,last_name,address_1,address-2,post_code,city,country,state必须放置在此过滤器中。

add_filter( 'woocommerce_default_address_fields','custom_override_default_locale_fields');
function custom_override_default_locale_fields( $fields ) {
    $fields['last_name']['priority'] = 1;
    $fields['last_name']['label'] = mb_strtoupper("nom");
    $fields['last_name']['class'] = array('form-left');
    $fields['first_name']['priority'] = 2;
    $fields['first_name']['label'] = mb_strtoupper("prénom");
    $fields['first_name']['class'] = array('form-right');
    $fields['address_1']['priority'] = 110;
    $fields['address_1']['label'] = mb_strtoupper("adresse 1");
    $fields['address_2']['priority'] = 120;
    $fields['address_2']['label'] = mb_strtoupper("adresse 2");
    $fields['postcode']['label'] = mb_strtoupper("code postal");
    $fields['postcode']['priority'] = 130;
    $fields['postcode']['class'] = array('form-left-small');
    $fields['city']['label'] = mb_strtoupper("ville");
    $fields['city']['priority'] = 140;
    $fields['city']['class'] = array('form-right-big');
    $fields['country']['priority'] = 4;
    $fields['country']['label'] = mb_strtoupper("pays");
    $fields['country']['required'] = true;
    $fields['country']['class'] = array('form-right','address-field','update_totals_on_change');
    $fields['state']['priority'] = 120;
    $fields['state']['label'] = mb_strtoupper("téléphone");
    $fields['state']['required'] = true;
    $fields['state']['class'] = array('form-right');
return $fields;
    return $fields;
}

以及CSS

.woocommerce form .form-right,
.woocommerce form .form-left,
.woocommerce form .form-left-small,
.woocommerce form .form-right-big {
    display: inline-block;
}
.woocommerce form .form-right,
.woocommerce form .form-left {
    width: 48%
}
.woocommerce form .form-right,
.woocommerce form .form-big-right {
    margin-left: 2% !important;
}
.woocommerce form .form-left,
.woocommerce form .form-left-small {
    margin-right: 2% !important;
}
.woocommerce form .form-big-right {
    width: 63%;
}
.woocommerce form .form-left-small {
    width: 33%;
}
.woocommerce form .woocommerce-input-wrapper strong {
    height: 38px;
    line-height: 38px;
}

结果:

enter image description here


仅提供代码答案通常可以通过添加解释它们如何以及为什么工作来改进。 - Jason Aller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接