0

how to implement below jQuery code into knockout js, Actually I'm trying to call this function on a button click event using knockout js, but it's not working

HTML code:

<div>
    <ul class="list-group">
       <li>
        <button id="buttonid">click</button>
        Item 1
       </li>
        <li>
        <button id="buttonid">click</button>
        Item 2
       </li>
    </ul>
</div>

jQuery COde:

$('#buttonid').on("click",".list-group-item",function(e){
console.log($(this).text());
console.log(e.target.id);
});

In this code .list-group-item is the class of ul tag. Here I wanna try to get title text of li items.

please guide me to implement above jQuery function in knockout js!

2

Template

  • Removed id's since there shouldn't be more than one element on page with the same id
  • Wrapped list item text with a span since trying to output the text of the li element would also output the button text

With Magento Init Script

<div>
    <ul class="list-group" data-role="item-announcer">
        <li>
            <button data-action="announce-item">click</button>
            <span data-role="item">Item 1</span>
        </li>
        <li>
            <button data-action="announce-item">click</button>
            <span data-role="item">Item 2</span>
        </li>
    </ul>
</div>

<script type="text/x-magento-init">
    {
        "[data-role=item-announcer]": {
            "Magento_Theme/js/item-announcer": {}
        }
    }
</script>

With Data Mage Init Attribute

<div>
    <ul class="list-group" data-mage-init='{"Magento_Theme/js/item-announcer": {}}'>
        <li>
            <button data-action="announce-item">click</button>
            <span data-role="item">Item 1</span>
        </li>
        <li>
            <button data-action="announce-item">click</button>
            <span data-role="item">Item 2</span>
        </li>
    </ul>
</div>

Component

In app/design/frontend/[vendor]/[theme]/Magento_Theme/web/js/item-announcer.js:

define([
    'jquery',
    'domReady!'
], function($) {
    return function(config, element) {
        let actionSelector = '[data-action=announce-item]';
        let itemSelector = '[data-role=item]';

        $(element).on('click', actionSelector, function (e) {
            e.preventDefault();
            let item = $(this).siblings(itemSelector);
            console.log(item.text());
        });
    }
});

With Knockout Component

Template

<?php
/** @var \Magento\Framework\View\Element\Template $block */
$jsId = $block->getJsId();
$items = [
    [
        'name' => 'Item 1'
    ],
    [
        'name' => 'Item 2'
    ]
];
?>

<div data-bind="scope: 'item-announcer-<?= $jsId; ?>'">
    <ul class="list-group" data-bind="visible: isVisible()" style="display: none;">
        <!-- ko foreach: items -->
        <li>
            <button data-bind="click: $parent.announce">click</button>
            <span data-bind="text: name"></span>
        </li>
        <!-- /ko -->
    </ul>
</div>

<script type="text/x-magento-init">
    {
        "*": {
            "Magento_Ui/js/core/app": {
                "components": {
                    "item-announcer-<?= $jsId; ?>": {
                        "component": "Magento_Theme/js/item-announcer",
                        "items": <?= json_encode($items); ?>
                    }
                }
            }
        }
    }
</script>

Component

In app/design/frontend/[vendor]/[theme]/Magento_Theme/web/js/item-announcer.js:

define([
    'uiComponent'
], function(Component) {
    return Component.extend({
        defaults: {
            items: []
        },

        /**
         * @inheritdoc
         */
        initObservable: function () {
            this._super()
                .observe('items');
            return this;
        },

        /**
         * Announce Text
         *
         * @param item
         */
        announce: function (item) {
            console.log(item.name);
        },

        /**
         * Get whether component is visible
         *
         * @returns {boolean}
         */
        isVisible: function () {
            return this.items().length > 0;
        }
    });
});
1
  • Thanks for your effort Man! – Faisal Sheikh Aug 5 '20 at 15:59
1

If you want to implement the jquery click event that you can refer the document as sometime knockout component call after the dom render you can use the below document jquery selector for the click event.

jQuery(document).on('click', '#your_selector', function (event) {
       console.log("element click");
}

Also in the html file you can use the data-bind click event as below and add name of your component js function.

<button data-bind="attr: {title: $t('your title')}, click: function_name" id="selector_id" class="button action primary" type="button">
        <span data-bind="i18n: ButtonText"></span>
</button>
1
  • Thanks brother! I also got some help from your solution. – Faisal Sheikh Aug 7 '20 at 7:32

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.