0

I have a component with for a "quantity changer", comprising of an input field and plus/minus buttons. The input and buttons are connected via data-binding on a KO observable. This works as expected.

<div class="qty-changer"
    data-bind="scope: 'qty_product_id'"
    data-mage-init='{
        "Magento_Ui/js/core/app": {
            "components": {
                "qty_product_id": {
                    "component": "qtyChange",
                    "defaultQty": 1,
                    "minQty": 1,
                    "maxQty": 999
                }
            }
        }
    }'>
    <span class="product__qty-wrapper">
        <span class="minus"
              title="-1"
              data-bind="click: decreaseQty">-</span>
        <input id="qty_product_id"
               name="qty_product_id"
               data-bind="value: qty"
               value="1"
               type="number"
               size="4"
               class="input-text input-qty"
               maxlength="12" />
        <span class="plus"
              title="+1"
              data-bind="click: increaseQty">+</span>
    </span>
</div>
define([
    'jquery',
    'ko',
    'uiComponent'
], function ($, ko, Component) {
    'use strict';

    return Component.extend({

        defaultQty: 0,
        minQty: 0,
        maxQty: 999999,

        initialize: function () {
            //initialize parent Component
            this._super();
            this.qty = ko.observable(this.defaultQty);
            this.qty.subscribe(this.qtyOnChange, this);
        },

        decreaseQty: function() {
            var newQty = parseInt(this.qty()) - 1;
            if (newQty < this.minQty) {
                newQty = this.minQty;
            }
            this.qty(newQty);
        },

        increaseQty: function() {
            var newQty = parseInt(this.qty()) + 1;
            if (newQty > this.maxQty) {
                newQty = this.maxQty;
            }
            this.qty(newQty);
        },

        qtyOnChange: function (newValue) {
            if (newValue < this.minQty) {
                this.qty(this.minQty);
            }
            if (newValue > this.maxQty) {
                this.qty(this.maxQty);
            }
        }
    });
});

Now I need to react to changes in the value in a completely other part of the site. I tried to listen to change events on the input via jQuery:

require(['jquery'], function($) {
    $(document).ready(function(){
        $('.input-qty').on('change', function(e) {
            alert('test');
        });
    });
});

However, the event handler is never executed. In the debugger, I can see that the event is attached, but all events are removed when the KO binding gets active.

My question: Is there a way to add event listeners to an input, that has a data-binding? Or is there a way to directly bind to the qty observable via jQuery?

1 Answer 1

0

Ok, after not getting a good solution, I fixed it by sending a custom event:

qtyOnChange: function (newValue) {
    if (newValue < this.minQty) {
        this.qty(this.minQty);
    }
    if (newValue > this.maxQty) {
        this.qty(this.maxQty);
    }
    $(document).trigger('qtyChange', [this.elem, this.qty()]);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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