Modulo di pagamento - Come avvolgere più elementi in una classe - Magento 2


14

Come avvolgere due elementi del modulo di checkout all'interno di un div?

Ad esempio, supponiamo che volessi racchiudere questi campi paese e zip / codice postale in un div con la classe di example-class, come farei?

inserisci qui la descrizione dell'immagine

Quello che ho provato

Ho cercato di raggiungere questo obiettivo aggiungendoli come figli di <item name="shippingAddress" xsi:type="array">ma ciò causa solo errori sul frontend. Anche se ho ricevuto un input di testo vuoto senza un'etichetta all'interno, .example-classc'erano errori sul frontend.

L'errore: Cannot read property 'indexedOptions' of undefined

Questo è il mio tentativo veloce:

Magento_Checkout / web / template / trasporto di indirizzo / form.html

<div id="shipping-new-address-form" class="fieldset address">
    <div class="testing">
        <!-- ko foreach: getRegion('example-class') -->
        <!-- ko template: getTemplate() --><!-- /ko -->
        <!--/ko-->
    </div>
    <!-- ko foreach: getRegion('additional-fieldsets') -->
    <!-- ko template: getTemplate() --><!-- /ko -->
    <!--/ko-->
</div>

checkout_index_index.xml

<item name="example-for-adding-class" xsi:type="array">
    <item name="component" xsi:type="string">uiComponent</item>
    <item name="config" xsi:type="array">
        <item name="deps" xsi:type="array">
            <item name="0" xsi:type="string">checkoutProvider</item>
        </item>
    </item>
    <item name="displayArea" xsi:type="string">example-class</item>
    <item name="children" xsi:type="array">
        <!-- The following items override configuration of corresponding address attributes -->
        <item name="region" xsi:type="array">
            <!-- Make region attribute invisible on frontend. Corresponding input element is created by region_id field -->
            <item name="visible" xsi:type="boolean">false</item>
        </item>
        <item name="region_id" xsi:type="array">
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/region</item>
            <item name="config" xsi:type="array">
                <item name="template" xsi:type="string">ui/form/field</item>
                <item name="elementTmpl" xsi:type="string">ui/form/element/select</item>
                <item name="customEntry" xsi:type="string">shippingAddress.region</item>
            </item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="boolean">true</item>
            </item>
            <!-- Value of region_id field is filtered by the value of county_id attribute -->
            <item name="filterBy" xsi:type="array">
                <item name="target" xsi:type="string"><![CDATA[${ $.provider }:${ $.parentScope }.country_id]]></item>
                <item name="field" xsi:type="string">country_id</item>
            </item>
        </item>
        <item name="postcode" xsi:type="array">
            <!-- post-code field has custom UI component -->
            <item name="component" xsi:type="string">Magento_Ui/js/form/element/post-code</item>
            <item name="sortOrder" xsi:type="string">2</item>
            <item name="validation" xsi:type="array">
                <item name="required-entry" xsi:type="string">true</item>
            </item>
        </item>
        <item name="country_id" xsi:type="array">
            <item name="sortOrder" xsi:type="string">1</item>
        </item>
    </item>
</item>

Deve esserci un modo più semplice per farlo, o mi manca qualcosa o questa è la definizione di over-engineering. L'aggiunta di un div su due elementi non dovrebbe mai essere così difficile.

Risposte:


17

Domanda molto interessante. Consentitemi di rispondere all'ultima ipotesi sull'implementazione di Google Checkout. Potrebbe essere un po 'troppo ingegnerizzato poiché devi aggiungere più di una sola modifica in 1 file.

L'approccio non richiede l'esecuzione di modifiche nei moduli principali di Magento 2.

Per raggiungere il tuo obiettivo e racchiudere i campi dell'indirizzo di spedizione di checkout in un elemento personalizzato, devi aggiungere i seguenti elementi:

  1. File checkout_index_index.xml personalizzato con la nuova definizione del componente UI
  2. Nuovo modello HTML con elemento personalizzato
  3. Plugin del processore di layout
  4. La dichiarazione di.xml per il nuovo plugin

Il file Custom_Checkout \ view \ frontend \ layout \ checkout_index_index.xml :

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
    <referenceBlock name="checkout.root">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="checkout" xsi:type="array">
                        <item name="children" xsi:type="array">
                            <item name="steps" xsi:type="array">
                                <item name="children" xsi:type="array">
                                    <item name="shipping-step" xsi:type="array">
                                        <item name="children" xsi:type="array">
                                            <item name="shippingAddress" xsi:type="array">
                                                <item name="children" xsi:type="array">
                                                    <item name="shipping-address-fieldset" xsi:type="array">
                                                        <item name="children" xsi:type="array">
                                                            <item name="custom-field-group" xsi:type="array">
                                                                <item name="component" xsi:type="string">uiComponent</item>
                                                                <item name="sortOrder" xsi:type="string">0</item>
                                                                <item name="template" xsi:type="string">Custom_Checkout/checkout/field-group</item>
                                                                <item name="children" xsi:type="array">
                                                                    <item name="field-group" xsi:type="array">
                                                                        <item name="component" xsi:type="string">uiComponent</item>
                                                                        <item name="displayArea" xsi:type="string">field-group</item>
                                                                    </item>
                                                                </item>
                                                            </item>
                                                        </item>
                                                    </item>
                                                </item>
                                            </item>
                                        </item>
                                    </item>
                                </item>
                            </item>
                        </item>
                    </item>
                </item>
            </argument>
        </arguments>
    </referenceBlock>
</body>

Nel layout, dovremmo aggiungere un nuovo componente UI del gruppo di campi personalizzato . Il componente ha il suo modello Custom_Checkout \ view \ web \ template \ checkout \ field-group.html in cui vengono visualizzati tutti i campi. Inoltre, il componente gruppo di campi personalizzati ha un valore "0" per il nodo sortOrder . Consente il rendering del componente prima di tutti i campi dichiarati come parte del componente shipping-address-fieldset .

Inoltre, esiste un componente dell'interfaccia utente del gruppo di campi con la propria impostazione displayArea .

Il file modello Custom_Checkout \ view \ web \ template \ checkout \ field-group.html :

<div class="custom">
<!-- ko foreach: getRegion('field-group') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
</div>

Il modello consente il rendering di tutti i componenti aggiunti nell'area del gruppo di campi (noto anche come displayArea ).

Il file di classe Custom \ Checkout \ Plugin \ AddressLayoutProcessor :

namespace Custom\Checkout\Plugin;

use Magento\Checkout\Block\Checkout\LayoutProcessor;

/**
 * Class AddressLayoutProcessor
 */
class AddressLayoutProcessor
{
    /**
     * @param LayoutProcessor $subject
     * @param array $jsLayout
     * @return array
     */
    public function afterProcess(LayoutProcessor $subject, array $jsLayout)
    {
        $fieldGroup = &$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
            ['children']['shippingAddress']['children']['shipping-address-fieldset']
            ['children']['custom-field-group']['children']['field-group']['children'];

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

        $fieldGroup['country_id'] = $shippingAddressFields['country_id'];
        $fieldGroup['postcode'] = $shippingAddressFields['postcode'];

        $shippingAddressFields['country_id']['visible'] = false;
        $shippingAddressFields['postcode']['visible'] = false;

        return $jsLayout;
    }
}

La classe è responsabile della copia di entrambi country_id configurazioni dei campi e del codice postale nel componente del gruppo di campi personalizzato appena creato .

I campi, una volta assegnati a di campi personalizzati devono essere contrassegnati come nascosti (visibile = vero) per evitare duplicazioni durante il rendering. Il componentDisabled non deve essere utilizzato per la disattivazione country_id e codice postale a causa di altre dipendenze (ad esempio region.js file) e meccanismo di elaborazione indirizzo di spedizione.

Il personalizzato \ Checkout \ etc \ frontend \ di.xml :

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="customFieldGroupPlugin" type="Custom\Checkout\Plugin\AddressLayoutProcessor"/>
    </type>
</config>

L'approccio del plugin utilizzato per i campi cambia perché i campi devono essere copiati con la configurazione completa. Nel caso in cui il Processore di layout sia dichiarato in un modulo personalizzato, il plug-in prenderà le modifiche.

Di conseguenza, sia i campi country_id che i codici postali vengono visualizzati nel modulo dell'indirizzo di spedizione e inseriti nell'elemento personalizzato come indicato di seguito (ho aggiunto alcuni stili affinché la classe CSS personalizzata si distingua nel modulo):

inserisci qui la descrizione dell'immagine

Se desideri anche apportare modifiche a un modulo di indirizzo di fatturazione, il necessario aggiornare la classe Custom \ Checkout \ Plugin \ AddressLayoutProcessor . Tutto quello che devi fare è eseguire le stesse manipolazioni con l'indirizzo di fatturazione per il metodo di pagamento specifico che abbiamo per i campi dell'indirizzo di spedizione.

Felice di aiutare!


Incredibile, grazie! Non lo avrei mai gestito, interessante il modo in cui richiede un lavoro di back-end. Lo stavo affrontando da un punto di vista puramente FE. Se nessuno troverà una soluzione più semplice in pochi giorni (poiché penso che alcune persone lo stiano attualmente guardando), lo segnerò come accettato. Grazie ancora.
Ben Crook,

Ottima risposta :)
Keyur Shah,

Fantastico, grazie mille. Per me funziona.
Pratik Mehta,

Se voglio la stessa modifica si applica al nuovo indirizzo di fatturazione, allora?
Pratik Mehta,

1
Se si desidera anche apportare modifiche a un modulo di indirizzo di fatturazione, è necessario aggiornare la classe Custom \ Checkout \ Plugin \ AddressLayoutProcessor. Tutto quello che devi fare è eseguire le stesse manipolazioni con l'indirizzo di fatturazione per il metodo di pagamento specifico che abbiamo per i campi dell'indirizzo di spedizione.
Max Pronko il

2

Questo non è un modo consigliato, è semplice ma non elegante:

app / code / Venditore / modulo / view / frontend / layout / checkout_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="checkout" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
          <block class="Vendor\Salesman\Block\Checkout\Index" name="custom_checkout" before="-" template="Vendor_Module::checkout/index.phtml"/>
        </referenceContainer>
    </body>
</page>

app / code / Calce / Commesso / vedere / frontend / templates / cassa / index.phtml

<script>
  require([
      'jquery',
      'mage/mage'
  ], function($){
      $(document).ready(function () {
         //detect if the shipping form container loaded
         var existCondition = setInterval(function() {
            if ($('#shipping').length) {
              moveElement();
            }
         }, 100);

         function moveElement(){
             //get The field postcode and country
             var postcodeField = $("div[name='shippingAddress.postcode']");
             var countryField = $("div[name='shippingAddress.country_id']");
             // insert the wrapeer
             $( '<div class="wrapper"></div>' ).insertBefore( postcodeField);
             // move the fields to wrapper
             $(".wrapper").append(postcodeField);
             $(".wrapper").append(countryField);
         }
      });
    }
  });
</script>

Ho votato perché sono sicuro che funzionerebbe, ma sono d'accordo che non è molto pulito, non lo userei se non ci fosse un metodo più pulito. Grazie.
Ben Crook,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.