Magento 2: Knockout JS Dynamic Content Binding Issue

checkoutknockoutknockoutjsmagento2.3

I have created a custom form in checkout page. Everything works fine except one ajax response binding

Here is my code

template.html

 <form id="cust-checkout-form" class="form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
        <fieldset class="fieldset">
            <div class="step-title" data-role="title" data-bind="i18n: 'Post Selection'">Post Selection</div>
            <p>&nbsp;</p>               

            <div style="padding-top: 10px" id="selected_post"></div> 
            <div>Find Post within&nbsp;&nbsp;
                <select name="distance" id="distance" style="width: 8%;" data-bind="event: { change: getDealers }">
                    <option value="5">5</option>
                    <option value="10">10</option>
                    <option value="25">25</option>                       
                </select>&nbsp;&nbsp;miles. Choose below
            </div>
            <input type="hidden" name="licence" id="licence" value="" />

            <div id="dealer-div">
                <ul class="post-div" id="post-div" data-bind="foreach: dealers">
                    <li class="post-item" data-bind="click: function(data,event){$parent.setValue(data,event);},attr: {'class': postcls}">
                        <div class="post-span">
                            <label data-bind="html: name" /><br/>
                            <label data-bind="html: address" /><br/>                        
                        </div>
                    </li>
                </ul>
            </div>
        </fieldset>
    </form>

knockout js

    define([
    'Magento_Ui/js/form/form',
    'ko'
], function(Component,ko) {
    'use strict';

    return Component.extend({

        initialize: function () {
            this._super();
            this.dealers = ko.observableArray([]);
            this.dealers = window.checkoutConfig.dealers;
            return this;
        },            
        setValue: function(data,event) {console.log('hi');
            var licenceVal = data.licence;
            jQuery("#post-licence").val(licenceVal);
            var content = data.name+", "+data.address;
            jQuery("#selected_post").html("<b>"+content+"</b>");              

        },
        getDealers: function () {
            var dist = jQuery("#distance").val();
            jQuery.ajax({
                showLoader: true,
                url: window.checkoutConfig.ajaxUrl,
                data: {'dist':dist},
                type: "POST",
            }).done(function (data) {
                this.dealers = data;
                return this;
            });
        },

    });
});

The content is not changing while selecting the dropdown.

If I pass the response as html, then the setValue function is not working.
Please help me.

Best Answer

You need to rebind knockout events by applyBindings before setting HTML content

getDealers: function () {
    var dist = jQuery("#distance").val();
    jQuery.ajax({
        showLoader: true,
        url: window.checkoutConfig.ajaxUrl,
        data: {'dist':dist},
        type: "POST",
    }).done(function (data) {
        //Rebind knockout events
        ko.cleanNode($('#cust-checkout-form')[0]);
        ko.applyBindings(this, $('#cust-checkout-form')[0]);
        this.dealers = data;
        return this;
    });
},

If current HTML use external knockout js component rather than current js than create new object of js and use new object in applyBindings

define([
    'Vendor_Module/js/mycustom',
], function(mycustom) {

..
..

getDealers: function () {
    var dist = jQuery("#distance").val();
    jQuery.ajax({
       ...
    }).done(function (data) {
        //Rebind knockout events
        ko.cleanNode($('#cust-checkout-form')[0]);
        ko.applyBindings(new mycustom(), $('#cust-checkout-form')[0]);
        ..
    });
},
Related Topic