0

I already have a form and controller action, that send data without using ajax.How to do it with AJAX? I would appreciate your help!

view/frontend/templates/reviews.phtml

<form action="<?php echo $block->getBaseUrl().'reviews/index/save'; ?>"  
 method="post">
                <label class="label" for="nickname"><span>Nickname</span></label>
                <input name="nickname" id="nickname" title="nickname" value="" class="nickname" type="text">
                <label class="label" for="textreview"><span>Text Review</span></label>
                <input name="textreview" id="textreview" title="textreview" value="" class="textreview" type="text">

                    <button type="submit" title="Submit" class="actionSubmitPrimary">
                        <span>Submit Review</span>
                    </button>
    </form>
    <script>
        $(document).ready(function () {
            $('button.actionSubmitPrimary').on('click', function (){
                var nickname = $('input.nickname').val();
                var textreview = $('input.textreview').val();
                $.ajax({
                    method:"POST",
                    url:"<?php echo $block->getBaseUrl().'reviews/index/save'; ?>",
                    data:{nickname:nickname, textreview:textreview}
                })
                .done(function (msg) {
                    alert("OK" +msg);
                });
            })
        })
    </script>

Controller/Index/Save.php

<?php

namespace Training\Reviews\Controller\Index;
use Magento\Framework\App\Action\Context;
use Training\Reviews\Model\ReviewsFactory;

class Save extends \Magento\Framework\App\Action\Action
{

protected $_test;

public function __construct(
   Context $context,
ReviewsFactory $test
 ) {
$this->_test = $test;
parent::__construct($context);
 }
 public function execute()
{

$data = $this->getRequest()->getParams();
$test = $this->_test->create();
$test->setData($data);
if($test->save()){
    $this->messageManager->addSuccessMessage(__('You saved 
  review'));
  }else{
    $this->messageManager->addErrorMessage(__('Review was not 
saved.'));
}
$resultRedirect = $this->resultRedirectFactory->create();
$resultRedirect->setPath('reviews/index/index');
return $resultRedirect;
}
}

Controller/Index/Index.php

<?php

namespace Training\Reviews\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
public function execute()
{
$this->_view->loadLayout();
$this->_view->getLayout()->initMessages();
$this->_view->renderLayout();
  }
}   
2

You can save custom form data in your database using following way:

/app/code/Vendor/Module/registration.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Module',
    __DIR__
);

/app/code/Vendor/Module/etc/module.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
    <module name="Vendor_Module" setup_version="2.0.0"></module>
</config>

/app/code/Vendor/Module/etc/frontend/routes.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
    <router id="standard">
        <route id="reviews" frontName="reviews">
            <module name="Vendor_Module"/>
        </route>
    </router>
</config>

/app/code/Vendor/Module/Setup/InstallSchema.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Setup;

use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\InstallSchemaInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\SchemaSetupInterface;

class InstallSchema implements InstallSchemaInterface
{

    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)
    {
        $installer = $setup;
        $installer->startSetup();
        if (!$installer->tableExists('reviews')) {
            $tableName = $installer->getTable('reviews');
            $table = $installer->getConnection()
                ->newTable($tableName)
                ->addColumn(
                    'id',
                    Table::TYPE_INTEGER,
                    10,
                    [
                        'identity' => true,
                        'unsigned' => true,
                        'nullable' => false,
                        'primary' => true,
                    ],
                    'Id'
                )
                ->addColumn(
                    'nickname',
                    Table::TYPE_TEXT,
                    255,
                    [
                        'nullable' => true,
                        'default' => null,
                    ],
                    'Nick Name'
                )
                ->addColumn(
                    'textreview',
                    Table::TYPE_TEXT,
                    255,
                    [
                        'nullable' => true,
                        'default' => null,
                    ],
                    'Text Review'
                )
                ->setComment('Reviews')
                ->setOption('type', 'InnoDB')
                ->setOption('charset', 'utf8');
            $installer->getConnection()->createTable($table);
        }
        $installer->endSetup();
    }
}

/app/code/Vendor/Module/Model/Reviews.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model;

class Reviews extends \Magento\Framework\Model\AbstractModel
{

    public function _construct()
    {
        $this->_init('Vendor\Module\Model\ResourceModel\Reviews');
    }
}

/app/code/Vendor/Module/Model/ResourceModel/Reviews.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model\ResourceModel;

class Reviews extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
    public function _construct()
    {
        $this->_init('reviews', 'id');
    }
}

/app/code/Vendor/Module/Model/ResourceModel/Reviews/Collection.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model\ResourceModel\Reviews;

class Collection extends \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
{
    protected function _construct()
    {
        $this->_init('Vendor\Module\Model\Reviews', 'Vendor\Module\Model\ResourceModel\Reviews');
    }
}

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

<?xml version="1.0"?>
<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd" layout="1column">
    <body>
        <referenceContainer name="content">
            <block class="Magento\Framework\View\Element\Template" name="custom_view" template="Vendor_Module::view.phtml"></block>
        </referenceContainer>
    </body>
</page>

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

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Controller\Index;

class Index extends \Magento\Framework\App\Action\Action
{
    /**
     * [execute description]
     * @return [type] [description]
     */
    public function execute()
    {
        $this->_view->loadLayout();
        $this->_view->renderLayout();
    }
}

/app/code/Vendor/Module/Controller/Index/Save.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\Context;
use Vendor\Module\Model\ReviewsFactory;

class Save extends \Magento\Framework\App\Action\Action
{

    protected $reviews;

    public function __construct(
        Context $context,
        ReviewsFactory $reviews
    ) {
        $this->reviews = $reviews;
        parent::__construct($context);
    }
    public function execute()
    {
        $data = $this->getRequest()->getParams();
        $reviews = $this->reviews->create();
        $reviews->setData($data);
        if ($reviews->save()) {
            $this->messageManager->addSuccessMessage(__('You saved review'));
        } else {
            $this->messageManager->addErrorMessage(__('Review was not saved.'));
        }
        $resultRedirect = $this->resultRedirectFactory->create();
        $resultRedirect->setPath('reviews/index/index');
        return $resultRedirect;
    }
}

/app/code/Vendor/Module/view/frontend/templates/view.phtml

<form method="POST" name="custom_view">
    <label class="label" for="nickname"><span>Nickname</span></label>
    <input name="nickname" id="nickname" title="nickname" class="nickname" type="text">
    <label class="label" for="textreview"><span>Text Review</span></label>
    <input name="textreview" id="textreview" title="textreview" class="textreview" type="text">

    <button type="submit" title="Submit" class="actionSubmitPrimary" id="submit_data">
        <span>Submit Review</span>
    </button>
</form>
<script>
    require(['jquery'],function($){
        $('#submit_data').on('click', function (){
            var nickName = $("input[name='nickname']").val();
            var textReview = $("input[name='textreview']").val();
            var url = "<?php echo $block->getUrl('reviews/index/save') ?>";
              jQuery.ajax({
                url: url,
                type: "POST",
                data: {nickname:nickName,textreview:textReview},
                showLoader: true,
            });
        });
    });
</script>

Output

enter image description here

I hope it will helpful for you.

| improve this answer | |
  • The data is being added to the database (I had it) but I want it to work in the background with Ajax (used your code, didn't help) – pixartN Feb 13 at 10:17
  • I have tested above code, it's working fine for me, and data added using AJAX, can you please tell me what issue have you faced with above code? – Rohit Feb 13 at 10:28
  • Thank you, the reason was in the browser – pixartN Feb 15 at 16:58
  • Hello @pixartn, Please check my another answer, hope it'll helpful for you. – Rohit Feb 18 at 6:28
0

You can save and display information with Ajax using Magento's default way, for that you need change/replace /app/code/Vendor/Module/Controller/Index/Save.php & /app/code/Vendor/Module/view/frontend/templates/view.phtml files.

/app/code/Vendor/Module/Controller/Index/Save.php

<?php

namespace Vendor\Module\Controller\Index;

use Magento\Framework\App\Action\Context;
use Vendor\Module\Model\ReviewsFactory;

class Save extends \Magento\Framework\App\Action\Action
{

    /**
     * @var ReviewsFactory
     */
    protected $reviews;
    /**
     * [__construct description]
     * @param Context        $context [description]
     * @param ReviewsFactory $reviews [description]
     */
    public function __construct(
        Context $context,
        ReviewsFactory $reviews
    ) {
        $this->reviews = $reviews;
        parent::__construct($context);
    }
    public function execute()
    {
        $data = $this->getRequest()->getParams();
        $reviews = $this->reviews->create();
        $reviews->setData($data);
        $reviews->save();
        $response = $this->resultFactory
            ->create(\Magento\Framework\Controller\ResultFactory::TYPE_JSON)
            ->setData($reviews->getData());
        return $response;
    }
}

/app/code/Vendor/Module/view/frontend/templates/view.phtml

<form method="POST" name="review_form" id="review_form">
    <span>Nick Name:<input name="nickname" id="nickname" title="nickname" class="nickname" type="text"></span>
    <span>Text Review:<input name="textreview" id="textreview" title="textreview" class="textreview" type="text"><br></span>
    <br><button id="submit_demo_data">Submit Review</button>
</form>
<table id='display_data'>
    <tr>
        <th>Id</th><th>Nick Name</th><th>Text Review</th>
    </tr>
</table>

<script type="text/javascript">
    require([
        "jquery",
        "mage/mage"
    ],function($) {
        $(document).ready(function() {
            $('#review_form').mage(
                'validation',
                {
                    submitHandler: function(form) {
                        var customurl = "<?php echo $this->getUrl().'reviews/index/save'?>";
                        $.ajax({
                            url: customurl,
                            data: $('#review_form').serialize(),
                            type: 'POST',
                            dataType: 'json',
                            showLoader: true,
                            cache: false,
                            success: function(data, status, xhr) {
                                $('#display_data').append("<tr><td>" + data.id + "</td><td>" + data.nickname + "</td><td>" + data.textreview + "</td></tr>");
                                $("#review_form").trigger('reset');
                            },
                            error: function (xhr, status, errorThrown) {
                                console.log('Error happens. Try again.');
                                console.log(errorThrown);
                            }
                        });
                    }
                }
            );
        });
    });
</script>

Output

enter image description here

I hope it will helpful for you.

| improve this answer | |
  • It already works, but when I update the page, what I added is missing – pixartN Feb 18 at 15:02
  • You mean, you want to display all records which are available in Database will display on page every time right? – Rohit Feb 19 at 4:25
  • Yes, I have it implemented but without AJAX, now I want it to work with AJAX, I found the "Fetch" method but I don't know how to implement it. – pixartN Feb 19 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.