Reading list Switch to dark mode

    Update Ui dynamically using knockout Js in Magento 2

    Updated 22 February 2024

    Here we learn how to update ui dynamically using Knockout Js in Magento 2 in custom phtml.

    How to update ui dynamically using Knockout Js in Magento 2

    If you haven’t learnt how to implement Knockout Js on our custom template please click
    How To Use Knockout JS On Custom Template In Magento2

    we are going save data using ajax request and updated customer list automatically on our custom template.

    1. In our previous blog, i have create Webkul/Knockout/view/frontend/web/template/knockout-test.html file.

    Let’s open it again and create a simple form.

    Searching for an experienced
    Magento 2 Company ?
    Find out More
    <div class="customcomponent-wrapper" data-block="customcomponent">
        <div class="block-content">
            <form data-role="save"
                  data-bind="submit:save"
                  method="post">
                <div class="fieldset"
                          data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">
                    <div class="field field-email required">
                        <label class="label" for="save-email"><span data-bind="i18n: 'Email Address'"></span></label>
                        <div class="control">
                            <input type="email"
                                   class="input-text"
                                   id="save-email"
                                   name="email"
                                   data-validate="{required:true}" />
                        </div>
                    </div>
                    <div class="field field-name required">
                        <label for="login-name" class="label"><span data-bind="i18n: 'Customer Name'"></span></label>
                        <div class="control">
                            <input type="text"
                                   class="input-text"
                                   id="login-name"
                                   name="name"
                                   data-validate="{required:true}"
                                   autocomplete="off"/>
                        </div>
                    </div>
                </div>
                <div class="actions-toolbar">
                    <input name="context" type="hidden" value="checkout" />
                    <div class="primary">
                        <button type="submit" class="action action-save secondary"><span data-bind="i18n: 'Save Record'"></span></button>
                    </div>
                </div>
            </form>
        </div>
        <table>
            <thead>
                <th data-bind="i18n: 'Customer Name'"></th>
                <th data-bind="i18n: 'Customer Email'"></th>
            </thead>
            <tbody data-bind="foreach: getTotalCustomer()">
                <tr>
                    <td data-bind="text: name"></td>
                    <td data-bind="text: email"></td>
                </tr>
            </tbody>
        </table>
    </div>

    2. We also created Webkul/Knockout/view/web/js/custom-component.js file, open it and update.

    define([
        'jquery',
        'uiComponent',
        'mage/validation',
        'ko',
        'Webkul_Knockout/js/action/save-customer',
        ], function ($, Component, validation, ko, saveAction) {
            'use strict';
            var totalCustomer= ko.observableArray([]);
            return Component.extend({
                defaults: {
                    template: 'Webkul_Knockout/knockout-test'
                },
    
                initialize: function () {
                    this._super();
                },
                save: function (saveForm) {
                    var self = this;
                    var saveData = {},
                        formDataArray = $(saveForm).serializeArray();
    
                    formDataArray.forEach(function (entry) {
                        saveData[entry.name] = entry.value;
                    });
    
                    if($(saveForm).validation()
                        && $(saveForm).validation('isValid')
                    ) {
                        saveAction(saveData, totalCustomer).always(function() {
                            console.log(totalCustomer());
                        });
                    }
                },
                getTotalCustomer: function () {
                    return totalCustomer;
                }
            });
        }
    );

    In this file we have defined ‘Webkul_Knockout/js/action/save-customer’ which is responsible for making ajax request to server.

    I have created save function here, which is validating form and sending the form
    data to Webkul_Knockout/js/action/save-customer action using saveAction().

    3. Now lets create this action js file.

    /*global define,alert*/
    define(
        [
            'ko',
            'jquery',
            'mage/storage',
            'mage/translate',
        ],
        function (
            ko,
            $,
            storage,
            $t
        ) {
            'use strict';
            return function (customerData, totalCustomer) {
                return storage.post(
                    'knockout/ajax/save',
                    JSON.stringify(customerData),
                    false
                ).done(
                    function (response) {
                        if (response) {
                            totalCustomer([]);
                            $.each(response, function (i, v) {
                                totalCustomer.push(v);
                            });
                        }
                    }
                ).fail(
                    function (response) {
                    }
                );
            };
        }
    );

    In this file we have made a ajax request to server, but what is storage here.
    storage is nothing but a another jQuery model which already have defined some ajax request methods itself.

    open pub/static/frontend/Magento/luma/en_US/mage/storage.js you will find some methods here: get, post, put,delete

    When ajax request to server it returns data, and saved in totalCustomer Observable Array.

    totalCustomer is defined in Webkul/Knockout/view/frontend/web/js/custom-component.js file which is passes as param.

    Finally, create Controller.

    4. Webkul/Knockout/Controller/Ajax/Save.php

    <?php
    namespace Webkul\Knockout\Controller\Ajax;
    
    use Magento\Customer\Api\AccountManagementInterface;
    use Magento\Framework\App\ObjectManager;
    use Magento\Framework\Exception\LocalizedException;
    
    class Save extends \Magento\Framework\App\Action\Action
    {
    
        /**
         * @var \Magento\Framework\Json\Helper\Data $helper
         */
        protected $helper;
    
        /**
         * @var \Magento\Framework\Controller\Result\JsonFactory
         */
        protected $resultJsonFactory;
    
        /**
         * @var \Magento\Framework\Controller\Result\RawFactory
         */
        protected $resultRawFactory;
    
    
        /**
         * Initialize Login controller
         *
         * @param \Magento\Framework\App\Action\Context $context
         * @param \Magento\Customer\Model\Session $customerSession
         * @param \Magento\Framework\Json\Helper\Data $helper
         * @param AccountManagementInterface $customerAccountManagement
         * @param \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
         * @param \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
         */
        public function __construct(
            \Magento\Framework\App\Action\Context $context,
            \Magento\Framework\Json\Helper\Data $helper,
            \Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory,
            \Magento\Framework\Controller\Result\RawFactory $resultRawFactory
        ) {
            parent::__construct($context);
            $this->helper = $helper;
            $this->resultJsonFactory = $resultJsonFactory;
            $this->resultRawFactory = $resultRawFactory;
        }
        public function execute()
        {
            $model = $this->_objectManager->create('Webkul\Knockout\Model\CustomerData');
            $credentials = $this->helper->jsonDecode($this->getRequest()->getContent());
            $model->setData($credentials)->save();
            
            $collection = $model->getCollection();
            foreach ($collection as $data) {
               $response[] = ['name' => $data->getName(), 'email' => $data->getEmail()];
            }
            /** @var \Magento\Framework\Controller\Result\Json $resultJson */
            $resultJson = $this->resultJsonFactory->create();
            return $resultJson->setData($response);
        }
    }

    We can see that i have created simple controller which is only saving data, and collecting all from the database table that is showing below:

    image-92

    When this response comes on action js file save-customer.js its assign the whole data to totalCustomer observableArray.

    Now see in Webkul/Knockout/view/frontend/web/js/custom-component.js there is method getTotalCustomer
    which is called in Webkul/Knockout/view/frontend/web/template/knockout-test.html file.

    Now run php/magento setup:static-content:deploy command.

    When you open your custom phtml file, you will see a form.

    Knockout Js

    Thanks for reading.

    . . .

    Leave a Comment

    Your email address will not be published. Required fields are marked*


    4 comments

  • Krishna2 kumar
    • Mahesh Singh (Moderator)
  • mani
    • Mahesh Singh (Moderator)
  • Back to Top

    Message Sent!

    If you have more details or questions, you can reply to the received confirmation email.

    Back to Home