15

Can anyone explain me how I can create a simple form on Magento-2 page to send data using Ajax? I already have a form and controller action, that send data without using ajax.

3
  • I think this link will help you click here Feb 7, 2017 at 11:32
  • look at my answer, it could help more then the accepted one
    – LucScu
    Jan 20, 2018 at 9:48
  • Showing error to response > Undefined property: > namespace\modulename\Controller\Index\Index\Interceptor::$_jsonHelper Please share to improve the answer Jan 22, 2019 at 9:57

3 Answers 3

21

You can just set below code in your phtml file to use ajax, You have to change your customurl in below code,

<script type="text/javascript">
    require(["jquery"],function($) {
        $(document).ready(function() {
            var customurl = "<?php echo $this->getUrl().'frontname/index/index'?>";
            $.ajax({
                url: customurl,
                type: 'POST',
                dataType: 'json',
                data: {
                    customdata1: 'test1',
                    customdata2: 'test2',
                },
            complete: function(response) {             
                country = response.responseJSON.default_country;
                state = response.responseJSON.state;         
                console.log(state+' '+country);   
                },
                error: function (xhr, status, errorThrown) {
                    console.log('Error happens. Try again.');
                }
            });
        });
    });
</script>

inside your controller file execute() method,

<?php
 use Magento\Framework\Controller\ResultFactory;
 public function execute()
    {
        $resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);

        $response = $this->resultFactory->create(ResultFactory::TYPE_RAW);
        $response->setHeader('Content-type', 'text/plain');
        $country = 'india';
        $state = 'gujarat';
        $response->setContents(
            $this->_jsonHelper->jsonEncode(
                [
                    'default_country' => $country,
                    'state' => $state,
                ]
            )
        );
        return $response;
    } 
10
  • 4
    you can get data in controller using $this->getRequest()->getParam('customdata1'); Feb 7, 2017 at 11:59
  • 1
    response is getting in script response. Feb 7, 2017 at 12:40
  • 2
    complete: function(response) here you have got response. Feb 7, 2017 at 12:40
  • 1
    you have to set response in above $this->_jsonHelper->jsonEncode( [ 'default_country' => $country, 'state' => $state, ] ) code in controller Feb 7, 2017 at 12:47
  • 1
    in above case default_country and state are return from response Feb 7, 2017 at 12:47
19

Accepted answer is good, but i think could be useful take advantage of the js validation that magento core offers. So, try to use below js script:

<script type="text/javascript">
require([
    "jquery",
    "mage/mage"
],function($) {
    $(document).ready(function() {
        $('#form_id').mage(
            'validation',
            { 
                submitHandler: function(form) {
                    $.ajax({
                        url: "url to module/controller/action",
                        data: $('#form_id').serialize(),
                        type: 'POST',
                        dataType: 'json',
                        beforeSend: function() {
                            // show some loading icon
                        },
                        success: function(data, status, xhr) {
                            // data contains your controller response
                        },
                        error: function (xhr, status, errorThrown) {
                            console.log('Error happens. Try again.');
                            console.log(errorThrown);
                        }
                    });
                }
            }
        );
    });
});
</script>

Don't forget that controller has to return JSON response like:

$response = $this->resultFactory
    ->create(\Magento\Framework\Controller\ResultFactory::TYPE_JSON)
    ->setData([
        'status'  => "ok",
        'message' => "form submitted correctly"
    ]);

return $response;
1
  • 1
    Way better solution than the accepted answer. Thanks man
    – medina
    May 22, 2019 at 2:45
0

Using PrototypeJS

<?php
/**
 * @var $block \Company\Module\Block\System\Config\Form\GenerateData
 */
?>
<script>
    require([
        'jquery',
        'prototype',
    ], function ($) {
        function generateData() {
            let params = {};
            new Ajax.Request('<?php echo $block->getAjaxUrl() ?>', {
                parameters: params,
                loaderArea: true,
                asynchronous: true,
                onSuccess: function (transport) {
                    let response = JSON.parse(transport.responseText);
                    $('#messages .message-success span.message-text').text("<?= __('Data generated successfully!') ?>");
                    $('#messages .message-success').show();
                    $('#messages .message-success').delay(8000).fadeOut();
                },
                onFailure: function() {
                    $('#messages .message-error span.message-text').text("<?= __('Something went wrong while generating the data.') ?>");
                    $('#messages .message-error').show();
                    $('#messages .message-error').delay(8000).fadeOut();
                    return false;
                }
            });
        }
        $('#generate_data').click(function () {
            generateData();
        });
    });
</script>

<div class="pp-buttons-container">
    <button id="<?= $block->getId() ?>">
        <span><span><span><?= $block->escapeHtml($block->getButtonLabel()) ?></span></span></span>
    </button>
</div>
<div id="messages" >
    <div class="messages">
        <div class="message message-success success" style="display: none;">
            <div data-ui-id="messages-message-success">
                <span class="message-text"></span>
            </div>
        </div>
        <div class="message message-error error" style="display: none;">
            <div data-ui-id="messages-message-error">
                <span class="message-text"></span>
            </div>
        </div>
    </div>
</div>

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.