2

Suppose I have a custom table and some fields like entity_id, code, title, description and image_path. And I require that I want to show a drop-down (key=>value) on the custom page where some options will be shown and based on that selected option I want to show the records using knockout. whenever the user changes the value from the dropdown then the records from the database will be shown below. The dropdown key will match with the table code column, which will be used to filter records. If there are any questions, feel free to ask in the comments. Any Idea Thanks.

2 Answers 2

1

Create a block and call your model inside your block. Here is example :

app/code/Vendor/Module/Block/CustomData.php

namespace Vendor\Module\Block;

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

class CustomData 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();
    }
}

Then create your knockoutjs component file and call html template in your js

app/code/Vendor/Module/view/frontend/web/js/view/custom-component.js

define([
    'uiComponent',
    'ko',
    'jquery'
], function (Component, ko, $) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/custom-component'
        },
        initialize: function () {
            this._super();
            this.customData = ko.observableArray([]);
            this.loadCustomData();
        },
        loadCustomData: function () {
            var self = this;
            $.ajax({
                url: '/rest/V1/custommodule/customdata',
                type: 'GET',
                success: function (data) {
                    self.customData(data);
                }
            });
        }
    });
});

Now Create a template for your KnockoutJS component:

app/code/Vendor/Module/view/frontend/web/template/custom-component.html

<div data-bind="foreach: customData">
    <div>
        <h2 data-bind="text: name"></h2>
        <p data-bind="text: description"></p>
    </div>
</div>

Create layout XML to include your KnockoutJS component

app/code/Vendor/Module/view/frontend/layout/default.xml

<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Vendor\Module\Block\CustomData" name="custom_data_block">
                <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-component</item>
                            </item>
                        </item>
                    </argument>
                </arguments>
            </block>
        </referenceContainer>
    </body>
</page>
1

follow these steps:

1. Create a Custom Table

Create your custom table with fields: entity_id, code, title, description, and image_path.

2. Create a Model and Resource Model

Define a model and resource model for your custom table.

Model: app/code/Vendor/Module/Model/CustomTable.php

<?php
namespace Vendor\Module\Model;

use Magento\Framework\Model\AbstractModel;

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

Resource Model: app/code/Vendor/Module/Model/ResourceModel/CustomTable.php

 <?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');
    }
}

3. Create a Collection

Collection: app/code/Vendor/Module/Model/ResourceModel/CustomTable/Collection.php

 <?php
namespace Vendor\Module\Model\ResourceModel\CustomTable;

use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;

class Collection extends AbstractCollection
{
    protected $_idFieldName = 'entity_id';
    protected $_eventPrefix = 'custom_table_collection';
    protected $_eventObject = 'custom_table_collection';

    protected function _construct()
    {
        $this->_init('Vendor\Module\Model\CustomTable', 'Vendor\Module\Model\ResourceModel\CustomTable');
    }
}

4. Create a Block

Create a block to fetch data from the custom table and pass it to the template.

Block: app/code/Vendor/Module/Block/Custom.php

 <?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 getCustomTableData()
    {
        $collection = $this->collectionFactory->create();
        return $collection->getItems();
    }
}

5. Create a Template

Create a template to display the dropdown and data.

Template: app/code/Vendor/Module/view/frontend/templates/custom.phtml

    <div id="custom-table-data" data-bind="with: customTableDataViewModel">
    <select data-bind="options: options, value: selectedOption"></select>
    <div data-bind="foreach: filteredItems">
        <div>
            <p data-bind="text: title"></p>
            <p data-bind="text: description"></p>
            <img data-bind="attr: { src: image_path }" />
        </div>
    </div>
</div>

6. Create a ViewModel

ViewModel: app/code/Vendor/Module/view/frontend/web/js/view/custom-table-data.js

    define([
    'ko',
    'jquery',
    'uiComponent'
], function (ko, $, Component) {
    'use strict';

    return Component.extend({
        defaults: {
            template: 'Vendor_Module/custom-table-data'
        },
        initialize: function () {
            this._super();
            var self = this;

            self.options = ko.observableArray([]);
            self.selectedOption = ko.observable();
            self.items = ko.observableArray([]);
            self.filteredItems = ko.computed(function () {
                return ko.utils.arrayFilter(self.items(), function (item) {
                    return item.code === self.selectedOption();
                });
            });

            $.ajax({
                url: 'path_to_your_controller',
                type: 'GET',
                success: function (data) {
                    self.items(data);
                    var codes = data.map(function (item) { return item.code; });
                    self.options(codes);
                }
            });
        }
    });
});

7. Update Layout

Layout: app/code/Vendor/Module/view/frontend/layout/default.xml

    <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <body>
        <referenceContainer name="content">
            <block class="Vendor\Module\Block\Custom" name="custom_table_data" template="Vendor_Module::custom.phtml" />
        </referenceContainer>
    </body>
</page>

8. Create a Controller

Controller: app/code/Vendor/Module/Controller/Index/Custom.php

 <?php
namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\Action;
use Magento\Framework\App\Action\Context;
use Vendor\Module\Model\ResourceModel\CustomTable\CollectionFactory;
use Magento\Framework\Controller\Result\JsonFactory;

class Custom extends Action
{
    protected $collectionFactory;
    protected $resultJsonFactory;

    public function __construct(
        Context $context,
        CollectionFactory $collectionFactory,
        JsonFactory $resultJsonFactory
    ) {
        $this->collectionFactory = $collectionFactory;
        $this->resultJsonFactory = $resultJsonFactory;
        parent::__construct($context);
    }

    public function execute()
    {
        $collection = $this->collectionFactory->create();
        $items = [];
        foreach ($collection as $item) {
            $items[] = $item->getData();
        }

        $result = $this->resultJsonFactory->create();
        return $result->setData($items);
    }
}

9. Run Setup Upgrade

Run the following commands:

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

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.