Magento – Binding Events On Dynamically Generated DOM Elements Knockout + Magento 2

knockoutjsmagento2

I am working on a module where i have generated few DOM elements dynamically. But when i am trying to call certain function on some events then its not getting called. Here is the code sample. Here you can see i am calling getData method on "change" event but its not being called

getData: function() {
            var data = this._super();
            data.additional_data.bank_type = $('input[name="payment\\[bank_type\\]"]:checked').val();
            data.additional_data.emi       = $('input[name="payment\\[emi\\]"]:checked').val();
            data.additional_data.email     = this.getEmail();
            console.log($('input[name="payment\\[emi\\]"]:checked').val());
            return data;
        },

        getEmi: function (emiCount) {
            var total = priceUtils.formatPrice(quote.totals().grand_total, quote.getPriceFormat());
            var rowTotal = quote.totals().grand_total;
            var item = '';
            var html = '';
            var i;
            for (i=1; i<=emiCount; i++ ) {
                if (i==1) {
                    item = "<li>" +
                        "<input type='radio' name='payment[emi_type]' data-bind='event: { change: getData}' id='emi" + i + "' value='" + i + "'>" +
                        "<label class='label' for='emi" + i + "'>Tek Ödeme, Toplam: "+total+"</label>" +
                        "</li>";
                } else {
                    rowTotal = parseInt(rowTotal)/i;
                    item = "<li>" +
                        "<input type='radio' name='payment[emi_type]' data-bind='event: { change: getData}' id='emi" + i + "' value='" + i + "'>" +
                        "<label class='label' for='emi" + i + "'>"+i+" Taksit, Aylık Taksit: "+priceUtils.formatPrice(rowTotal, quote.getPriceFormat())+" Toplam: "+total+"</label>" +
                        "</li>";
                }
                html = html+item;
            }

            console.log(html);
            $('.emi-list').html(html);
        },

Best Answer

I used js code like.

/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
/*jshint browser:true jquery:true*/
/*global alert*/
define([
    "jquery",
    'ko',
    'uiComponent',
    'Magento_Ui/js/modal/alert',
    "jquery/ui",
    "mage/translate",
    "mage/mage",
    "mage/validation"
], function ($, ko, Component, alert, mage) {
    "use strict";
    var totalCustomer= ko.observableArray([]);
    var results= ko.observableArray([]);
    function feedShow(name, email) {
        var self = this;
        self.name = name;
        self.email = email;
    }
    return Component.extend({
        productList: ko.observableArray([]),
        initialize: function() {
            this._super();
        },
        /** Initialize observable properties */
        initObservable: function () {
            this._super()
                    .observe('msgSaved')
                    ;
                    this.uname = ko.observable('');
                    this.email = ko.observable('');
                    this.phone = ko.observable('');
                    this.msg = ko.observable('');
            return this;
        },
        /**
         * Validate feedback form
         */
        validateForm: function () {
            var form = '#feedback-form';
            return $(form).validation() && $(form).validation('isValid');
        },
        submitFeedback: function () {
            /* $.ajax(this.getFeedbackUrl).done(
             function() {
             this.msgSaved(true)
             }.bind(this)
             );*/
            if (!this.validateForm()) {
             return;
             }
            var data = {'name':this.uname(),'email':this.email(),'phone':this.phone(),'message':this.msg(),'status':0};
           // if(this.validateForm()){

           // }
           // console.log(data);
            $.ajax({
                url: this.getFeedbackUrl,
                data: data,
                type: 'post',
                dataType: 'json',
                context: this,
                beforeSend: this._ajaxBeforeSend,
                success: function (response) {
                    this.msgSaved(true);
                    this.uname('testing');
                    alert({
                        content: $.mage.__('Thanks for Submitting.')
                    });
                },
                complete: this._ajaxComplete
            });
        },
        totalfeeds:function(){
            console.log('test');
          $.ajax({
                url:'http://magento2.local/feedback/entry/show',
                type: 'post', 
                dataType: 'json',
                contentType: 'application/json',
                context: this,
                showLoader:true,
                beforeSend: this._ajaxBeforeSend,
                success: function (response) {
                    var jsonTempStringified = JSON.stringify(response);
                    var jsonTempStringifiedParsed = JSON.parse(jsonTempStringified);
                    this.productList(jsonTempStringifiedParsed);
                    // results(jsonTempStringifiedParsed);
                },
                complete: this._ajaxComplete
            });

        },
        deleteFeeds:function(parent,data){
            alert({
                content: 'Are you sure want to delete record!'
            });
            var jsonTempStringified = JSON.stringify(data);
            var jsonTempStringifiedParsed = JSON.parse(jsonTempStringified);
            var fid = jsonTempStringifiedParsed.fid;
            var data = {'fid':fid};
            $.ajax({
                url:'http://magento2.local/feedback/entry/delete',
                data: data,
                type: 'post',
                dataType: 'json',
                context: this,
                beforeSend: this._ajaxBeforeSend,
                success: function (response) {
                    this.totalfeeds();
                },
                complete: this._ajaxComplete
            });
        },
        defaults: {
            msgSaved: false,
            template: 'Smart_Feedback/feedback',
        }
    });
}
);

Binding template .html file.

<!--
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<div>
    <!-- ko ifnot: msgSaved -->
    <form method="post" class="feedback" id="feedback-form" data-role="feedback-form" data-bind="submit: submitFeedback">
        <fieldset class="fieldset">
            <legend class="legend"><span><p data-bind="i18n: 'You can post your feedback here.'"></p></span></legend><br>
            <div class="field name required">
                <label for="name" class="label"><span>Name</span></label>
                <div class="control">
                    <input type="text" data-validate="{required:true}" 
                           class="input-text" title="Name" 
                           id="user_name" aria-required="true" 
                           data-bind="value:uname,attr: {'data-validate': JSON.stringify({required:true})},
                                        ">
                </div>
            </div>
            <div class="field email required">
                <label for="email" class="label"><span>Email</span></label>
                <div class="control">
                    <input type="email" data-validate="{required:true}" data-bind="value:email,attr: {'data-validate': JSON.stringify({required:true,'validate-email':true})},
                                        " class="input-text" title="Email" id="email" aria-required="true" >
                </div>
            </div>
            <div class="field telephone">
                <label for="telephone" class="label"><span>Phone Number</span></label>
                <div class="control">
                    <input type="text" class="input-text" value="" title="Phone Number" id="telephone" data-bind="value:phone">
                </div>
            </div>
            <div class="field comment required">
                <label for="comment" class="label"><span>Feedback message</span></label>
                <div class="control">
                    <textarea data-validate="{required:true}" rows="3" cols="5" class="input-text" title="What’s on your mind?" id="comment" name="comment" aria-required="true"
                              data-bind="value:msg"></textarea>
                </div>
            </div>
        </fieldset>
        <div class="actions-toolbar">
            <div class="primary">
                <input type="hidden" value="" id="hideit" name="hideit">
                <input type="submit" class="action primary" data-bind="value: $t('Submit Feedback')" />
                <button data-bind="attr: {title: $t('totalfeeds')}, click: totalfeeds" class="action primary">Total Feeds</button>
                <button data-bind="click: totalfeeds">click me</button>
                <li><input type='radio' name='emi_type' data-bind='event: { change: totalfeeds}' id='emi' value="">
                    <label class='label' for='emi'>Test</label>
                </li>
            </div>
        </div>
    </form>
    <table>
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Email</th> 
                <th>Action</th>  
            </tr>
        </thead>
        <tbody data-bind="foreach: productList">
            <tr>
                <td data-bind="text: fid"></td>
                <td data-bind="text: name"></td>
                <td data-bind="text: email"></td>
                <td><a href="#" data-bind="click: function(data,event){$parent.deleteFeeds($parent,data);}">Remove</a></td>
            </tr>
        </tbody>
    </table>


    <!-- /ko -->

    <!-- ko if: msgSaved -->
    <p data-bind="i18n: 'Feedback message posted for review.'"></p>
    <!-- /ko -->
</div>

Please check above radio element with change event with Test Label.

Related Topic