Pregunta

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();
  }
}   
¿Fue útil?

Solución

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.

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top