Here we learn how to update ui dynamically using Knockout Js in Adobe Commerce (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 Adobe Commerce (Magento 2)
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.
<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:
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.
For any technical support, please reach out to us at [email protected]. Additionally, discover various solutions to upgrade your online store’s functionality by visiting the Adobe Commerce modules page.
If you need expert consultation or wish to develop bespoke features, Hire Adobe Commerce Developers for your project.
Thanks for reading.
‘knockout/ajax/save’,
JSON.stringify(customerData),
false
)
where the knockout comes from in the second line of code