AJAX IN MAGENTO2.HOW TO ADD information from form IN DATABASE?
-
08-04-2021 - |
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();
}
}
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
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
I hope it will helpful for you.