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 Answers 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
I hope it will helpful for you.
-
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– pixartN2020年02月13日 10:17:13 +00:00Commented Feb 13, 2020 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?Mahesh Dave– Mahesh Dave2020年02月13日 10:28:48 +00:00Commented Feb 13, 2020 at 10:28
-
Thank you, the reason was in the browserpixartN– pixartN2020年02月15日 16:58:40 +00:00Commented Feb 15, 2020 at 16:58
-
Hello @pixartn, Please check my another answer, hope it'll helpful for you.Mahesh Dave– Mahesh Dave2020年02月18日 06:28:09 +00:00Commented Feb 18, 2020 at 6:28
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.
-
It already works, but when I update the page, what I added is missingpixartN– pixartN2020年02月18日 15:02:24 +00:00Commented Feb 18, 2020 at 15:02
-
You mean, you want to display all records which are available in Database will display on page every time right?Mahesh Dave– Mahesh Dave2020年02月19日 04:25:45 +00:00Commented Feb 19, 2020 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– pixartN2020年02月19日 07:47:29 +00:00Commented Feb 19, 2020 at 7:47