Magento 2-カスタムフィールドをチェックアウトに追加して送信する方法


49

すべてのチュートリアルはフィールドの追加のみを扱っていますが、このフィールドの値の保存はスキップされます#mindblown。理由はわかりませんが、フィールドやフォームを追加する最も重要な部分です。

Magentoのドキュメントをフォローしようとしましたが......

テストの目的で、別のフィールドを配送先住所に追加して、カスタムスコープ、カスタムデータセット、カスタムデータプロバイダー、その他のドキュメント化されていないものを無視します。

そのフォームが「静的」または「動的」であることの意味がわかりません。私にとって、すべてのチェックアウトフォームはKnockoutJSテンプレートの上に動的に構築されますが、...「静的」な方法を試してみると、ここに入力を追加できます(静的フォームかどうか)。

最初に、Knockoutオブザーバブルがデータの解析および送信中に自分のフィールドを無視する理由をデバッグしようとします。フィールドに空のnameパラメーターがあることがわかりましたが、この問題を修正する方法を管理できません。IMOは、などのinputName他のオプションと同じようにdisabled、パラメーターを介してUIコンポーネントレンダラーに渡される必要がありますplaceholder(他のパラメーターは正常に機能し、XMLから生成された構成をチェックしてモジュールの初期化をチェックし、見栄えがよくなります)

第二に、プラグインを作成しLayoutProcessor、まったく同じデータを渡す「動的」な方法を使用しようとしました...そして、names を持つフィールドがありますが、送信はまだまったく機能しません。

JSを掘り下げた後、このリクエストの準備はmodule-checkout/view/frontend/web/js/model/shipping-save-processor/default.jsファイルで維持されていることがわかりました。これはmodule-checkout/view/frontend/web/js/model/quote.js、Knockoutオブザーバブルが定義/作成される場所によって異なります。

どういうわけか、module-checkout/view/frontend/web/js/model/address-converter.jsこのオブザーバブルを更新しmodule-checkout/view/frontend/web/js/model/new-customer-address.js、に依存して、最終的にいくつかの興味深い構成オプションを見つけました-すべてのアドレスフィールドのリスト

ここにフィールドを追加すると、スクリプトが解析と送信を開始し、OFC 500を取得します、b / cバックエンドはそれらを認識しません...(質問しないでください、私はバックエンド開発者ではありません)

だからここに私の質問が来ます:

  • このタイプのカスタマイズを処理する正しい方法ですか?(b / cは私にとって奇妙に見える)
  • 新しいアドレスに関連しないフィールドの値を送信する方法は?同様の構成はどこにも見られませんでした。私の場合、注文のコメント(textarea)と請求書のリクエスト(checkbox)を送りたいです。両方をアドレスとして保存しないでください。一部のユーザーは、将来の使用のためにこのアドレスを保存したい場合があります。
  • 「静的」および「動的」フォームまたはいくつかの例/比較に関するドキュメントはありますか?このように考える価値はありますか?

追加の実存的な質問:

  • なぜこれがそれほど一貫していないのですか?MagentoがXML / PHPファイルで大量のパラメーターを定義する必要があるのに、Magentoは入力のみをレンダリングできるのに、すべてを自分で処理する必要があるのはなぜですか?

3
Magento Devdocsは最近、UIコンポーネントの使用に関するいくつかの新しいドキュメントを追加しました。私たちは実際にまったく新しいガイドを書いている最中ですが、まだ方法があります。devdocs.magento.com/guides/v2.1/ui_comp_guide/bk-ui_comps.htmlをご覧ください。残念ながら、データソースに関するトピックはまだ完了していません。これは、あなたが最も必要としているように思えます。UIコンポーネントを使用した構成フローに関するトピックがあり、役立つ場合があります。私はもっ​​と答えを見つけることに取り組みます。
タンベリー

なぜチェックアウトに単純なフィールドを追加するのが悪夢である必要があるのですか?分かりません。そしてほとんどすべてが難しい
-slayerbleast

@slayerbleast Worldは変化し続けており、サーバーサイドのレンダリングは死にかけています。だからそれは違う、理由もなく難しくはない。
イグロチェク

回答:


55

私はあなたの質問に答えようとします。

  1. いいえ。これは、配送先住所フォームにカスタム属性を追加する正しい方法ではありません。編集する必要はありませんnew-customer-address.js。実際、このJSファイルはすべての事前定義されたアドレス属性をリストし、対応するバックエンドインターフェイスと一致します\Magento\Quote\Api\Data\AddressInterfaceが、Magentoはバックエンド/フロントエンドコンポーネントを変更せずにカスタム属性をバックエンドに渡す機能を提供します。

    上記のJSコンポーネントにはcustomAttributesプロパティがあります。カスタム属性$dataScopePrefixが「shippindAddress.custom_attributes」の場合、カスタム属性は自動的に処理されます。

  2. 質問を正しく理解できた場合、顧客の住所の一部ではないデータがありますが、バックエンドにも送信する必要があります。この質問に対する答えは次のとおりです。

    それは依存します。たとえば、次のアプローチを選択できます。すべての追加フィールドを含むカスタムフォームをチェックアウトページ (like comment, invoice request etc)に追加し、イベントに基づいてこのフォームを処理するJSロジックを追加し、フロントエンドおよびストアからデータを受信するカスタムサービスを提供します将来の使用のためにどこかにそれ。

  3. チェックアウトに関連するすべての公式ドキュメントは、http://devdocs.magento.com/guides/v2.1/howdoi/checkout/checkout_overview.htmlにあります静的という用語は、すべてのフィールドが既知/事前定義されているフォームを指し(たとえば、フォームには常に事前定義されたラベルを持つ2つのテキストフィールドがあります)、バックエンドの一部の設定に基づいて変更できません。

    そのようなフォームはを使用して宣言できますlayout XML configuration。一方、動的という用語は、フィールドセットを変更できるフォーム指します(たとえば、チェックアウトフォームは、構成設定に基づいてより多く/より少ないフィールドを持つことができます)。

    この場合、そのようなフォームを宣言する唯一の方法はLayoutProcessorプラグインを使用することです。

  4. :) Magentoは、Magentoの使用/カスタマイズ中に商人にとって重要となる可能性のあるユースケースを可能な限りカバーしようとします。これにより、いくつかの単純なユースケースがより複雑になる場合があります。

お役に立てれば。

================================================== =======================

OK ...いくつかのコードを書きましょう;)

  1. LayoutProcessorに追加フィールドを挿入するPHPコード

=========

/**
 * @author aakimov
 */
$customAttributeCode = 'custom_field';
$customField = [
    'component' => 'Magento_Ui/js/form/element/abstract',
    'config' => [
        // customScope is used to group elements within a single form (e.g. they can be validated separately)
        'customScope' => 'shippingAddress.custom_attributes',
        'customEntry' => null,
        'template' => 'ui/form/field',
        'elementTmpl' => 'ui/form/element/input',
        'tooltip' => [
            'description' => 'Yes, this works. I tested it. Sacrificed my lunch break but verified this approach.',
        ],
    ],
    'dataScope' => 'shippingAddress.custom_attributes' . '.' . $customAttributeCode,
    'label' => 'Custom Attribute',
    'provider' => 'checkoutProvider',
    'sortOrder' => 0,
    'validation' => [
       'required-entry' => true
    ],
    'options' => [],
    'filterBy' => null,
    'customEntry' => null,
    'visible' => true,
];

$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']['shippingAddress']['children']['shipping-address-fieldset']['children'][$customAttributeCode] = $customField;

return $jsLayout;

すでに述べたように、これcustomAttributesによりJSアドレスオブジェクトのプロパティにフィールドが追加されます。このプロパティは、カスタムEAVアドレス属性を含むように設計されており、\Magento\Quote\Model\Quote\Address\CustomAttributeListInterface::getAttributesメソッドに関連しています。

上記のコードは、フロントエンドでローカルストレージの永続性を自動的に処理します。checkoutData.getShippingAddressFromData()checkoutDataMagento_Checkout/js/checkout-data)を使用して、ローカルストレージからフィールド値を取得できます。

  1. mixinを追加して、 'Magento_Checkout / js / action / set-shipping-information'の動作を変更します(このコンポーネントは、出荷と請求チェックアウト手順の間のデータ送信を担当します)

=========

2.1。作成するyour_module_name/view/frontend/requirejs-config.js


/**
 * @author aakimov
 */
var config = {
    config: {
        mixins: {
            'Magento_Checkout/js/action/set-shipping-information': {
                '<your_module_name>/js/action/set-shipping-information-mixin': true
            }
        }
    }
};

2.2。your_module_name / view / frontend / web / js / action / set-shipping-information-mixin.jsを作成します


/**
 * @author aakimov
 */
/*jshint browser:true jquery:true*/
/*global alert*/
define([
    'jquery',
    'mage/utils/wrapper',
    'Magento_Checkout/js/model/quote'
], function ($, wrapper, quote) {
    'use strict';

    return function (setShippingInformationAction) {

        return wrapper.wrap(setShippingInformationAction, function (originalAction) {
            var shippingAddress = quote.shippingAddress();
            if (shippingAddress['extension_attributes'] === undefined) {
                shippingAddress['extension_attributes'] = {};
            }

            // you can extract value of extension attribute from any place (in this example I use customAttributes approach)
            shippingAddress['extension_attributes']['custom_field'] = shippingAddress.customAttributes['custom_field'];
            // pass execution to original action ('Magento_Checkout/js/action/set-shipping-information')
            return originalAction();
        });
    };
});
  1. your_module_name / etc / extension_attributes.xmlを作成します

=========

<?xml version="1.0"?>
<!--
/**
 * @author aakimov
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Api/etc/extension_attributes.xsd">
    <extension_attributes for="Magento\Quote\Api\Data\AddressInterface">
        <attribute code="custom_field" type="string" />
    </extension_attributes>
</config>

これにより、バックエンド側のアドレスモデルに拡張属性が追加されます。拡張属性は、Magentoが提供する拡張ポイントの1つです。バックエンドでデータにアクセスするには、次を使用できます。

// Magento will generate interface that includes your custom attribute
$value = $address->getExtensionAttributes()->getCustomField();

これが役立って、公式文書に追加されることを願っています。


アレックスに答えてくれてありがとう!試しましたcustom_attributesが、うまくいきません。これは、LayoutProcessor.php`の一部がどのように見えるかです-gist.github.com/Igloczek/eaf4d2d7a0a04bd950110296ec3f7727しかし、shipping-info またはlocalStorageにもcheckout-dataこのデータが含まれていません。
イグロチェク

上記の更新された回答をご覧ください;)
aakimov

4
このトピックに関する公式ドキュメントはすでに利用可能です!devdocs.magento.com/guides/v2.1/howdoi/checkout/…–
アレックス

1
注文に対して値を保存するために追加のステップが必要ですか?
アレックスハドリー

私はあなたが静的なフォームを持っている場合、それはこの例のようにXMLを介しLayoutProcessorにフィールドを挿入する方が良いだと思う:devdocs.magento.com/guides/v2.1/howdoi/checkout/...
cjohansson

-1

私の経験では、m2はxmlを使用してフィールドなどのコンポーネントを定義します。これは、データのインタラクティブなデバッグを容易にするのに役立ちます。フロントエンダーのフィールドでは、チェックアウトテンプレートをオーバーライドして、そこに独自のカスタムフィールドを追加する必要があります。KOを使用すると、フロントエンドとバックエンドからのデータを処理およびバインドすることができます


4
これは間違ったアドバイスです。b/ cチェックアウトテンプレートには含まれず、手動で追加された入力フィールドを含めるべきではありません。選択した領域でテンプレートをレンダリングするためにKOを使用する必要があります(すべてがUIコンポーネントを使用して構築されます)
igloczek

フロントエンドでカスタムフィールドUIコンポーネントを追加する例を共有できますか?
mrtuvn

@igloczekが言うように、チェックアウトテンプレートには手動で追加された入力フィールドを含めるべきではないため、これは間違ったアドバイスです。
-diazwatson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.