How to Show Custom Table Data Using KnockoutJS in Magento 2.4

Table of Contents

  1. Introduction
  2. Understanding Magento's Data Management
  3. Conclusion
  4. FAQ

Introduction

In the rapidly-evolving world of e-commerce, understanding how to efficiently manage and display data is essential. Magento 2.4, a robust and flexible e-commerce platform, allows for extensive customization, and one way to enhance your user interface is by using KnockoutJS for dynamic data binding. In this blog post, we'll explore how to display custom table data using KnockoutJS in Magento 2.4. By the end of this piece, you'll be equipped with the knowledge to create a dynamic dropdown that filters and displays data based on user selection.

Understanding Magento's Data Management

Data management in Magento involves using models, resource models, collections, and blocks to handle and display data. Here, we will integrate these elements with KnockoutJS to facilitate a seamless data-binding process.

Creating a Custom Table

First, you'll need a custom table to store the data you want to display. For this example, let's say our table includes the following fields: entity_id, code, title, description, and image_path. This table can be created using an install script in your custom module.

Defining Your Model and Resource Model

The next step involves defining a model and its corresponding resource model for your custom table.

// app/code/Vendor/Module/Model/CustomTable.php
namespace Vendor\Module\Model;

use Magento\Framework\Model\AbstractModel;

class CustomTable extends AbstractModel
{
    protected function _construct()
    {
        $this->_init(\Vendor\Module\Model\ResourceModel\CustomTable::class);
    }
}

// app/code/Vendor/Module/Model/ResourceModel/CustomTable.php
namespace Vendor\Module\Model\ResourceModel;

use Magento\Framework\Model\ResourceModel\Db\AbstractDb;

class CustomTable extends AbstractDb
{
    protected function _construct()
    {
        $this->_init('custom_table', 'entity_id');
    }
}

Creating the Collection Class

A collection class will allow you to fetch multiple records from your custom table.

// app/code/Vendor/Module/Model/ResourceModel/CustomTable/Collection.php
namespace Vendor\Module\Model\ResourceModel\CustomTable;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use Vendor\Module\Model\CustomTable as Model;
use Vendor\Module\Model\ResourceModel\CustomTable as ResourceModel;

class Collection extends AbstractCollection
{
    protected function _construct()
    {
        $this->_init(Model::class, ResourceModel::class);
    }
}

Creating the Block

Blocks in Magento act as a bridge between data and templates. Create a block to fetch data from the custom table and pass it to the template.

// app/code/Vendor/Module/Block/Custom.php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Vendor\Module\Model\ResourceModel\CustomTable\CollectionFactory;

class Custom extends Template
{
    protected $collectionFactory;

    public function __construct(
        Template\Context $context,
        CollectionFactory $collectionFactory,
        array $data = []
    ) {
        $this->collectionFactory = $collectionFactory;
        parent::__construct($context, $data);
    }

    public function getCustomData()
    {
        $collection = $this->collectionFactory->create();
        return $collection->getItems();
    }
}

Creating the Template

Now, create a template to display the dropdown and necessary data.

<!-- app/code/Vendor/Module/view/frontend/templates/custom.phtml -->
<div id="custom-dropdown" data-bind="with: customTableData">
    <select data-bind="options: options, value: selectedOption, optionsText: 'title'"></select>
    <div data-bind="foreach: filteredData">
        <p data-bind="text: title"></p>
        <p data-bind="text: description"></p>
        <img data-bind="attr: { src: image_path }" alt="" />
    </div>
</div>

Creating the ViewModel using KnockoutJS

For data binding and UI updates, you'll create a ViewModel.

// app/code/Vendor/Module/view/frontend/web/js/view/custom-table-data.js
define(['uiComponent', 'ko'], function(Component, ko) {
    return Component.extend({
        defaults: {
            template: 'Vendor_Module/custom-component'
        },
        customTableData: ko.observableArray([]),
        selectedOption: ko.observable(),

        initialize: function() {
            this._super();
            this.selectedOption.subscribe(this.filterData, this);
            this.getCustomData();
        },

        getCustomData: function() {
            // Fetch your custom data via AJAX or REST API
            var self = this;
            fetch('/path/to/your/api')
                .then(response => response.json())
                .then(data => self.customTableData(data));
        },

        filterData: function() {
            var selected = this.selectedOption();
            var filtered = this.customTableData().filter(function(item) {
                return item.code === selected;
            });
            this.customTableData(filtered);
        }
    });
});

Updating the Layout XML

To include the KnockoutJS component in your layout, update the layout XML.

<!-- app/code/Vendor/Module/view/frontend/layout/default.xml -->
<referenceContainer name="content">
    <block class="Vendor\Module\Block\Custom" name="custom_block" template="Vendor_Module::custom.phtml">
        <arguments>
            <argument name="jsLayout" xsi:type="array">
                <item name="components" xsi:type="array">
                    <item name="customComponent" xsi:type="array">
                        <item name="component" xsi:type="string">Vendor_Module/js/view/custom-table-data</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </block>
</referenceContainer>

Running Setup Upgrade

Finally, make sure to run the necessary commands to install your module and update the database.

php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento setup:static-content:deploy

Conclusion

Integrating KnockoutJS with Magento 2.4 allows for dynamic and interactive front-end experiences. By following these steps, you can create a custom table, display data using KnockoutJS, and ensure that your e-commerce site is both functional and appealing to users.

FAQ

Q: What are the primary benefits of using KnockoutJS in Magento 2.4? A: KnockoutJS provides dynamic data binding, which simplifies the process of creating interactive user interfaces by automatically updating the UI whenever the underlying data changes.

Q: How can I fetch data asynchronously in KnockoutJS? A: You can fetch data asynchronously using AJAX calls or REST APIs. In the provided example, data is fetched using the Fetch API inside the getCustomData method.

Q: Why is the layout XML necessary? A: The layout XML is crucial because it integrates your custom KnockoutJS component into the Magento page layout, ensuring that your component loads correctly within the specified scope.