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();
 }
} 
asked Feb 12, 2020 at 16:00

2 Answers 2

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.

answered Feb 13, 2020 at 6:24
4
  • 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) Commented 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? Commented Feb 13, 2020 at 10:28
  • Thank you, the reason was in the browser Commented Feb 15, 2020 at 16:58
  • Hello @pixartn, Please check my another answer, hope it'll helpful for you. Commented Feb 18, 2020 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.

answered Feb 18, 2020 at 6:28
3
  • It already works, but when I update the page, what I added is missing Commented 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? Commented 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. Commented Feb 19, 2020 at 7:47

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.