0

1) I'm trying to filter the customer addresses in the checkout according to their postal code. The address blocks are displayed using the following knockoutjs code:

vendor/magento/module-checkout/view/frontend/web/template/shipping-address/list.html

<!-- ko if: (visible)-->
<div class="field addresses">
    <div class="control">
        <div class="shipping-address-items">
            <!-- ko foreach: { data: elems, as: 'element' } -->
                <!-- ko template: element.getTemplate() --><!-- /ko -->
            <!-- /ko -->
        </div>
    </div>
</div>
<!-- /ko -->

First thing, I'm struggling to understand where the elems variable comes from. Where should I be looking for its declaration?

2) Then I've been able to retrieve the postcode from the element object, and add a comparison to a hardcoded value. The following code works, only displaying the addresses whose postal code is 12345:

<!-- ko foreach: { data: elems, as: 'element' } -->
    <!-- ko if: (element.address().postcode === "12345") -->
        <!-- ko template: element.getTemplate() --><!-- /ko -->
    <!-- /ko -->
<!-- /ko -->

But how can I pass a value from php or jQuery (or a knockoutjs selector?) to use as my comparison instead of the hardcoded string?

  • 2
    Welcome to hell (the Magento 2 checkout), you must have been a bad person to get here. – Ben Crook Jun 7 '18 at 14:43
  • @BenCrook, Caught right one !! – Vivek Jun 8 '18 at 12:14
0

I've made some progress here, for some reason I expected the list.html to work with the list.js, but within the foreach tag I needed to use address-renderer/default.js

vendor/magento/module-checkout/view/frontend/web/js/view/shipping-address/address-renderer/default.js

In this file I've been able to declare a function returning the postal code I needed from the known quote object. In the list.html I've simply called this function in my condition, and it works (both files copied in my local theme).

<!-- ko foreach: { data: elems, as: 'element' } -->
    <!-- ko if: (element.address().postcode === getPostalcode()) -->
        <!-- ko template: element.getTemplate() --><!-- /ko -->
    <!-- /ko -->
<!-- /ko -->

So I still don't know where the elems variable comes from, but at least I've been able to retrieve my value from existing js objects!

0

Taken from https://devdocs.magento.com/guides/v2.1/ui_comp_guide/concepts/ui_comp_uicollection_concept.html

elems is the observable property that contains the collection of child UI components.

console.log(this.elems());

// [
//   %uiComponentInstance 1 %,
//   %uiComponentInstance 2 %,
//   %uiComponentInstance 3 %,
//   %uiComponentInstance 4 %
// ]

If you search for elems inside vendor/magento/module-ui/view/base/web/js/lib/core/collection.js you will find a few functions that can populate this collection. Such as:

  • _insert - Inserts provided component into 'elems' array at a specified position.
  • _updateCollection - Synchronizes multiple elements arrays with a core '_elems' container.
  • insertChild - Requests specified components to insert them into 'elems' array starting from provided position.

I've also answered a similar question here that has a bit more info - Magento 2: What Populates "elems" in a UI Component

To pass data through to this I believe you'd need to extend and edit vendor/magento/module-checkout/view/frontend/layout/checkout_index_index.xml:160

<item name="address-list" xsi:type="array">
    <item name="component" xsi:type="string">Magento_Checkout/js/view/shipping-address/list</item>
    <item name="displayArea" xsi:type="string">address-list</item>
</item>

I haven't ever passed data in this way so I can't help much more here sorry. Hopefully this helps slightly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.