Magento – How to send data from html template to controller magento 2

dataformsknockoutjsmagento2request

My controller is calling but how to send data and retrieve data?

My template:

<!-- ko -->
<tr class="totals fee excl">
    <th class="mark" colspan="1" scope="row" data-bind="text: title"></th>
    <td class="amount">
        <form data-role="save" data-bind="submit:save" method="post">
            <input type="text" name="spendpoints" id="spendpoints"
                   data-bind="text: getValue()" value="20"/>
            <input type="submit" class="submit"/>
        </form>
    </td>
</tr>
<!-- /ko -->

My js:

define(
    [
        'Company_Module/js/view/checkout/summary/fee',
        'mage/storage',
        'jquery'
    ],
    function (Component, storage) {
        'use strict';
        return Component.extend({
            /** Your function for ajax call */
            save: function (data) {

                // fullScreenLoader.startLoader();
                storage.post(
                    'custom/spendpoints/index',
                    JSON.stringify(data),
                    true
                ).done(
                    function (response) {
                        /** Do your code here */
                        alert('Success--' + data);

                        // fullScreenLoader.stopLoader();
                    }
                ).fail(
                    function (response) {
                        // fullScreenLoader.stopLoader();
                    }
                );
                // return data;
            },
            /**
             * @override
             */
            isDisplayed: function () {
                return true;
            }
        });
    }
);

My controller:

<?php 
namespace Company\Module\Controller\Spendpoints; 
class Index extends \Magento\Framework\App\Action\Action {
protected $_pageFactory;
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $pageFactory,
\Magento\Framework\Controller\Result\JsonFactory $resultJsonFactory
)
{
$this->_pageFactory = $pageFactory;
$this->resultJsonFactory = $resultJsonFactory; 
return parent::__construct($context);
}

public function execute() {
$result = $this->resultJsonFactory->create();
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/spendpoints.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$request = $this->getRequest()->getPostValue();

$logger->info('spendpointsdata'.print_r($request));

$this->_view->loadLayout();
$this->_view->getPage()->getConfig()->getTitle()->set(__(' My Reward Points '));
$this->_view->renderLayout();
} 
}

PS: I followed this link – https://magento.stackexchange.com/a/175850/55981

Best Answer

You can look at the Magento\Customer module to see an example of how this works.

\vendor\magento\module-checkout\view\frontend\web\template\authentication.html is the knockout template.

The form submit handler is in \vendor\magento\module-checkout\view\frontend\web\js\view\authentication.js and look like this:

/**
 * Provide login action.
 *
 * @param {HTMLElement} loginForm
 */
login: function (loginForm) {
    var loginData = {},
        formDataArray = $(loginForm).serializeArray();

    formDataArray.forEach(function (entry) {
        loginData[entry.name] = entry.value;
    });

    if ($(loginForm).validation() &&
        $(loginForm).validation('isValid')
    ) {
        fullScreenLoader.startLoader();
        loginAction(loginData, checkoutConfig.checkoutUrl, undefined, messageContainer).always(function () {
            fullScreenLoader.stopLoader();
        });
    }
}

The loginAction function is contained in: \vendor\magento\module-customer\view\frontend\web\js\action\login.js. Here it is:

/**
 * @param {Object} loginData
 * @param {String} redirectUrl
 * @param {*} isGlobal
 * @param {Object} messageContainer
 */
action = function (loginData, redirectUrl, isGlobal, messageContainer) {
    messageContainer = messageContainer || globalMessageList;

    return storage.post(
        'customer/ajax/login',
        JSON.stringify(loginData),
        isGlobal
    ).done(function (response) {
        if (response.errors) {
            messageContainer.addErrorMessage(response);
            callbacks.forEach(function (callback) {
                callback(loginData);
            });
        } else {
            callbacks.forEach(function (callback) {
                callback(loginData);
            });
            customerData.invalidate(['customer']);

            if (redirectUrl) {
                window.location.href = redirectUrl;
            } else if (response.redirectUrl) {
                window.location.href = response.redirectUrl;
            } else {
                location.reload();
            }
        }
    }).fail(function () {
        messageContainer.addErrorMessage({
            'message': 'Could not authenticate. Please try again later'
        });
        callbacks.forEach(function (callback) {
            callback(loginData);
        });
    });
};

And the controller that receives the data is this: \vendor\magento\module-customer\Controller\Ajax\Login.php:

public function execute()
{
    $credentials = null;
    $httpBadRequestCode = 400;

    /** @var \Magento\Framework\Controller\Result\Raw $resultRaw */
    $resultRaw = $this->resultRawFactory->create();
    try {
        $credentials = $this->helper->jsonDecode($this->getRequest()->getContent());
    } catch (\Exception $e) {
        return $resultRaw->setHttpResponseCode($httpBadRequestCode);
    }
    if (!$credentials || $this->getRequest()->getMethod() !== 'POST' || !$this->getRequest()->isXmlHttpRequest()) {
        return $resultRaw->setHttpResponseCode($httpBadRequestCode);
    }

    $response = [
        'errors' => false,
        'message' => __('Login successful.')
    ];
    try {
        $customer = $this->customerAccountManagement->authenticate(
            $credentials['username'],
            $credentials['password']
        );
        $this->customerSession->setCustomerDataAsLoggedIn($customer);
        $this->customerSession->regenerateId();
        $redirectRoute = $this->getAccountRedirect()->getRedirectCookie();
        if (!$this->getScopeConfig()->getValue('customer/startup/redirect_dashboard') && $redirectRoute) {
            $response['redirectUrl'] = $this->_redirect->success($redirectRoute);
            $this->getAccountRedirect()->clearRedirectCookie();
        }
    } catch (EmailNotConfirmedException $e) {
        $response = [
            'errors' => true,
            'message' => $e->getMessage()
        ];
    } catch (InvalidEmailOrPasswordException $e) {
        $response = [
            'errors' => true,
            'message' => $e->getMessage()
        ];
    } catch (LocalizedException $e) {
        $response = [
            'errors' => true,
            'message' => $e->getMessage()
        ];
    } catch (\Exception $e) {
        $response = [
            'errors' => true,
            'message' => __('Invalid login or password.')
        ];
    }
    /** @var \Magento\Framework\Controller\Result\Json $resultJson */
    $resultJson = $this->resultJsonFactory->create();
    return $resultJson->setData($response);
}

Looking at this controller, we can see that it uses $credentials = $this->helper->jsonDecode($this->getRequest()->getContent()); to get the request data, so I suggest you try that.