am working on custom module. How can i use default magento pagination use ajax with my custom collection and also set custom limits on that?
2 Answers
Try This Code
app/code/VendoreName/ModuleName
registration.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'VendoreName_ModuleName',
__DIR__
);
app/code/VendoreName/ModuleName/etc
module.xml
<?xml version="1.0" ?>
<!--
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="VendoreName_ModuleName" setup_version="1.0.0" >
<sequence>
<module name="Magento_Backend"/>
</sequence>
</module>
</config>
app/code/VendoreName/ModuleName/etc
db_schema.xml
<?xml version="1.0"?>
<!--
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
-->
<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd">
<table name="custom_data" resource="default" engine="innodb" comment="Custom Data">
<column xsi:type="smallint" name="id" padding="6" unsigned="false" nullable="false" identity="true" comment="ID"/>
<column xsi:type="varchar" name="name" nullable="false" length="25" comment="Name"/>
<column xsi:type="varchar" name="email" nullable="false" length="25" comment="Email"/>
<column xsi:type="varchar" name="description" nullable="false" length="255" comment="Descrition"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="id"/>
</constraint>
</table>
</schema>
app/code/VendoreName/ModuleName/etc/frontend
routes.xml
<?xml version="1.0" ?>
<!--
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="custom" frontName="custom">
<module name="VendoreName_ModuleName"/>
</route>
</router>
</config>
app/code/VendoreName/ModuleName/Model
CustomData.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Model;
use Magento\Framework\Model\AbstractModel;
use VendoreName\ModuleName\Model\ResourceModel\CustomData as CustomDataResourceModel;
class CustomData extends AbstractModel
{
/**
* @inheritdoc
*/
protected function _construct()
{
$this->_init(CustomDataResourceModel::class);
}
}
app/code/VendoreName/ModuleName/Model/ResourceModel
CustomData.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Model\ResourceModel;
use Magento\Framework\Model\ResourceModel\Db\AbstractDb;
class CustomData extends AbstractDb
{
/**
* @inheritdoc
*/
protected function _construct()
{
$this->_init('custom_data', 'id');
}
}
app/code/VendoreName/ModuleName/Model/ResourceModel/CustomData
Collection.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Model\ResourceModel\CustomData;
use Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection;
use VendoreName\ModuleName\Model\CustomData as CustomDataModel;
use VendoreName\ModuleName\Model\ResourceModel\CustomData as CustomDataResourceModel;
class Collection extends AbstractCollection
{
/**
* @inheritdoc
*/
protected function _construct()
{
$this->_init(
CustomDataModel::class,
CustomDataResourceModel::class
);
}
}
app/code/VendoreName/ModuleName/Controller/Index
Index.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Controller\Index;
use Magento\Framework\App\Action\Action;
class Index extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
/**
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* @inheritdoc
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->getConfig()->getTitle()->set(__('Custom Pagination'));
return $resultPage;
}
}
app/code/VendoreName/ModuleName/view/frontend/layout
custom_index_index.xml
<?xml version="1.0"?>
<!--
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<update handle="customer_account"/>
<head>
<script src="VendoreName_ModuleName::js/ajax_pagination.js" />
</head>
<body>
<referenceContainer name="content">
<block class="VendoreName\ModuleName\Block\Pager" name="custom.ajax.pagination" template="VendoreName_ModuleName::pager.phtml" cacheable="false" />
</referenceContainer>
</body>
</page>
app/code/VendoreName/ModuleName/Block
Pager.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Block;
use Magento\Framework\View\Element\Template;
class Pager extends Template
{
/**
* @var \VendoreName\ModuleName\Model\CustomData
*/
protected $customFactory;
/**
* @var \VendoreName\ModuleName\Model\ResourceModel\CustomData\CollectionFactory
*/
protected $customdataCollection;
/**
* @param Template\Context $context
* @param \VendoreName\ModuleName\Model\CustomData $customFactory
* @param \VendoreName\ModuleName\Model\ResourceModel\CustomData\CollectionFactory $customdataCollection
* @param array $data
*/
public function __construct(
Template\Context $context,
\VendoreName\ModuleName\Model\CustomData $customFactory,
\VendoreName\ModuleName\Model\ResourceModel\CustomData\CollectionFactory $customdataCollection,
array $data = []
) {
parent::__construct($context, $data);
$this->customFactory = $customFactory;
$this->customdataCollection = $customdataCollection;
}
/**
* @inheritdoc
*/
protected function _prepareLayout()
{
$this->pageConfig->getTitle()->set(__('My Custom Pagination'));
parent::_prepareLayout();
$page_size = $this->getPagerCount();
$page_data = $this->getCustomData();
if ($this->getCustomData()) {
$pager = $this->getLayout()->createBlock(
\VendoreName\ModuleName\Block\CustomPager::class,
'custom.pager'
)
->setAvailableLimit($page_size)
->setShowPerPage(true)
->setCollection($page_data);
$this->setChild('pager', $pager);
$this->getCustomData()->load();
}
return $this;
}
/**
* Get pager HTML
*
* @return \VendoreName\ModuleName\Block\CustomPager
*/
public function getPagerHtml()
{
return $this->getChildHtml('pager');
}
/**
* Get custom data collection
*
* @return \VendoreName\ModuleName\Model\CustomData
*/
public function getCustomData()
{
$page = ($this->getRequest()->getParam('p')) ? $this->getRequest()->getParam('p') : 1;
$pageSize = ($this->getRequest()->getParam('limit')) ? $this->getRequest()->getParam('limit') : 5;
$collection = $this->customFactory->getCollection();
$collection->setPageSize($pageSize);
$collection->setCurPage($page);
return $collection;
}
/**
* Get custom data collection
*
* @return array
*/
public function getPagerCount()
{
$minimum_show = 5; // set minimum records
$page_array = [];
$list_data = $this->customdataCollection->create();
$list_count = ceil(count($list_data->getData()));
$show_count = $minimum_show + 1;
if (count($list_data->getData()) >= $show_count) {
$list_count = $list_count / $minimum_show;
$page_nu = $total = $minimum_show;
$page_array[$minimum_show] = $minimum_show;
for ($x = 0; $x <= $list_count; $x++) {
$total = $total + $page_nu;
$page_array[$total] = $total;
}
} else {
$page_array[$minimum_show] = $minimum_show;
$minimum_show = $minimum_show + $minimum_show;
$page_array[$minimum_show] = $minimum_show;
}
return $page_array;
}
}
app/code/VendoreName/ModuleName/view/frontend/templates
pager.phtml
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
?>
<?php $custom_data = $block->getCustomData();?>
<?php if(!$block->getData('ajax_data')): ?>
<div class="custom-ajax-data">
<?php endif; ?>
<fieldset class="fieldset">
<?php if(count($custom_data)): ?>
<div class="table-wrapper custom-data ">
<table class="data table table-data-items ">
<caption class="table-caption"><?= $block->escapeHtml('Custom Pagination') ?></caption>
<thead>
<tr>
<th scope="col" class="col name"><?= $block->escapeHtml('Name') ?></th>
<th scope="col" class="col orders"><?= $block->escapeHtml('Email') ?></th>
<th scope="col" class="col orderitem"><?= $block->escapeHtml('Description') ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($custom_data as $item): ?>
<tr>
<td data-th="Name" class="col name">
<span><?= $block->escapeHtml($item->getName()) ?></span>
</td>
<td data-th="Orders" class="col orders">
<span><?= $block->escapeHtml($item->getEmail()) ?></span>
</td>
<td data-th="Items" class="col orderitem">
<span><?= $block->escapeHtml($item->getDescription()) ?></span>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
<?php if ($block->getPagerHtml()): ?>
<div class="order-products-toolbar toolbar bottom">
<?= $block->getPagerHtml() ?>
</div>
<?php endif ?>
<?php else: ?>
<div class="message info empty">
<span><?= $block->escapeHtml('You have no data in table.') ?></span>
</div>
<?php endif; ?>
</fieldset>
<?php if(!$block->getData('ajax_data')): ?>
</div>
<?php endif; ?>
app/code/VendoreName/ModuleName/Block
CustomPager.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Block;
class CustomPager extends \Magento\Theme\Block\Html\Pager
{
/**
* Current template name
*
* @var string
*/
protected $_template = 'VendoreName_ModuleName::html/custompager.phtml';
/**
* Return page limit params
*
* @param int $limit
* @return array
*/
private function getPageLimitParams(int $limit): array
{
$data = [$this->getLimitVarName() => $limit];
$currentPage = $this->getCurrentPage();
$availableCount = (int) ceil($this->getTotalNum() / $limit);
if ($currentPage !== 1 && $availableCount < $currentPage) {
$data = array_merge($data, [$this->getPageVarName() => $availableCount === 1 ? null : $availableCount]);
}
return $data;
}
/**
* Retrieve page URL by defined parameters
*
* @param array $params
*
* @return string
*/
public function getPagerUrl($params = [])
{
$urlParams = [];
$urlParams['_current'] = true;
$urlParams['_escape'] = true;
$urlParams['_fragment'] = $this->getFragment();
$urlParams['_query'] = $params;
return $this->getUrl($this->getPath(), $urlParams);
}
/**
* Get path
*
* @return string
*/
protected function getPath()
{
return "custom/index/ajaxdata";
}
}
app/code/VendoreName/ModuleName/view/frontend/templates/html
custompager.phtml
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
/**
* Pager template
*
* @see \VendoreName\ModuleName\Block\CustomPager
*/
?>
<?php if ($block->getCollection()->getSize()): ?>
<?php if ($block->getUseContainer()): ?>
<div class="pager">
<?php endif ?>
<?php if ($block->getShowAmounts()): ?>
<p class="toolbar-amount">
<span class="toolbar-number">
<?php if ($block->getLastPageNum()>1): ?>
<?= $block->escapeHtml(
__('Items %1 to %2 of %3 total', $block->getFirstNum(), $block->getLastNum(), $block->getTotalNum())
) ?>
<?php elseif ($block->getTotalNum() == 1): ?>
<?= $block->escapeHtml(__('%1 Item', $block->getTotalNum())) ?>
<?php else: ?>
<?= $block->escapeHtml(__('%1 Item(s)', $block->getTotalNum())) ?>
<?php endif; ?>
</span>
</p>
<?php endif ?>
<?php if ($block->getLastPageNum()>1): ?>
<div class="pages">
<strong class="label pages-label" id="paging-label"><?= $block->escapeHtml(__('Page')) ?></strong>
<ul class="items pages-items" aria-labelledby="paging-label">
<?php if (!$block->isFirstPage()): ?>
<li class="item pages-item-previous">
<?php $text = $block->getAnchorTextForPrevious() ? $block->getAnchorTextForPrevious() : '';?>
<a class="<?= $block->escapeHtmlAttr($text ? 'link ' : 'action ') ?> previous ajax-page"
href="<?= $block->escapeUrl($block->getPreviousPageUrl()) ?>"
title="<?= $block->escapeHtmlAttr($text ? $text : __('Previous')) ?>">
<span class="label"><?= $block->escapeHtml(__('Page')) ?></span>
<span><?= $block->escapeHtml($text ? $text : __('Previous')) ?></span>
</a>
</li>
<?php endif;?>
<?php if ($block->canShowFirst()): ?>
<li class="item">
<a class="page first ajax-page" href="<?= $block->escapeUrl($block->getFirstPageUrl()) ?>">
<span class="label"><?= $block->escapeHtml(__('Page')) ?></span>
<span>1</span>
</a>
</li>
<?php endif;?>
<?php if ($block->canShowPreviousJump()): ?>
<li class="item">
<a class="page previous jump ajax-page"
title=""
href="<?= $block->escapeUrl($block->getPreviousJumpUrl()) ?>">
<span>...</span>
</a>
</li>
<?php endif;?>
<?php foreach ($block->getFramePages() as $_page): ?>
<?php if ($block->isPageCurrent($_page)): ?>
<li class="item current">
<strong class="page">
<span class="label"><?= $block->escapeHtml(__('You\'re currently reading page')) ?></span>
<span><?= $block->escapeHtml($_page) ?></span>
</strong>
</li>
<?php else: ?>
<li class="item">
<a href="<?= $block->escapeUrl($block->getPageUrl($_page)) ?>" class="ajax-page">
<span class="label"><?= $block->escapeHtml(__('Page')) ?></span>
<span><?= $block->escapeHtml($_page) ?></span>
</a>
</li>
<?php endif;?>
<?php endforeach;?>
<?php if ($block->canShowNextJump()): ?>
<li class="item">
<a class="page next jump ajax-page" title="" href="<?= $block->escapeUrl($block->getNextJumpUrl()) ?>">
<span>...</span>
</a>
</li>
<?php endif;?>
<?php if ($block->canShowLast()): ?>
<li class="item">
<a class="page last ajax-page" href="<?= $block->escapeUrl($block->getLastPageUrl()) ?>">
<span class="label"><?= $block->escapeHtml(__('Page')) ?></span>
<span><?= $block->escapeHtml($block->getLastPageNum()) ?></span>
</a>
</li>
<?php endif;?>
<?php if (!$block->isLastPage()): ?>
<li class="item pages-item-next">
<?php $text = $block->getAnchorTextForNext() ? $block->getAnchorTextForNext() : '';?>
<a class="<?= /* @noEscape */ $text ? 'link ' : 'action ' ?> next ajax-page"
href="<?= $block->escapeUrl($block->getNextPageUrl()) ?>"
title="<?= $block->escapeHtmlAttr($text ? $text : __('Next')) ?>">
<span class="label"><?= $block->escapeHtml(__('Page')) ?></span>
<span><?= $block->escapeHtml($text ? $text : __('Next')) ?></span>
</a>
</li>
<?php endif;?>
</ul>
</div>
<?php endif; ?>
<?php if ($block->isShowPerPage()): ?>
<div class="limiter">
<strong class="limiter-label"><?= $block->escapeHtml(__('Show')) ?></strong>
<?php /*<select id="limiter" data-mage-init='{"redirectUrl": {"event":"change"}}' class="limiter-options"> */ ?>
<select id="limiter" class="limiter-options ajax-limiter-options">
<?php foreach ($block->getAvailableLimit() as $_key => $_limit): ?>
<option value="<?= $block->escapeUrl($block->getLimitUrl($_key)) ?>"
<?php if ($block->isLimitCurrent($_key)): ?>
selected="selected"<?php endif ?>>
<?= $block->escapeHtml($_limit) ?>
</option>
<?php endforeach; ?>
</select>
<span class="limiter-text"><?= $block->escapeHtml(__('per page')) ?></span>
</div>
<?php endif ?>
<?php if ($block->getUseContainer()): ?>
</div>
<?php endif ?>
<?php endif ?>
app/code/VendoreName/ModuleName/Controller/Index
AjaxData.php
<?php
/**
* @category VendoreName ModuleName
* @package VendoreName_ModuleName
* @author Mahesh Makwana <[email protected]>
*/
namespace VendoreName\ModuleName\Controller\Index;
use Magento\Framework\App\Action\Action;
use Magento\Framework\Controller\ResultFactory;
class AjaxData extends \Magento\Framework\App\Action\Action
{
/**
* @var \Magento\Framework\View\Result\PageFactory
*/
protected $resultPageFactory;
/**
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* @inheritdoc
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$block = $resultPage->getLayout()
->createBlock(\VendoreName\ModuleName\Block\Pager::class)
->setData('ajax_data', true)
->setTemplate("VendoreName_ModuleName::pager.phtml");
$resultJson = $this->resultFactory->create(ResultFactory::TYPE_JSON);
$data = ['content' => $block->toHtml()];
$resultJson->setData($data);
return $resultJson;
}
}
app/code/VendoreName/ModuleName/view/frontend/web/js
ajax_pagination.js
require(
["jquery"],
function($){
$(document).on('click', 'a.ajax-page', function(event){
event.preventDefault();
$.ajax({
url: $(this).attr('href'),
type: 'POST',
showLoader: true,
success: function(response){
$('.custom-ajax-data').html(response.content);
}
});
});
$(document).on('change', 'select.limiter-options.ajax-limiter-options', function(event){
$.ajax({
url: this.value,
type: 'POST',
showLoader: true,
success: function(response){
$('.custom-ajax-data').html(response.content);
}
});
});
})
I Hope This Helps You.
You can try to pass the page number in your Ajax request like below :
function uploaddata() {
new Ajax.Request("<?php echo $this->getUrl('*/*/ajaxtry'); ?>"+'page/'+page_number, {
method: "post",
onSuccess: function(transport) {
var json = transport.responseText.evalJSON();
if(json.NextPageToFetch !== 'undefined' && (page_number == json.NextPageToFetch)) {
id++;
page_number = 1;
} else if (json.NextPageToFetch !== 'undefined' && (page_number != json.NextPageToFetch)) {
page_number = json.NextPageToFetch;
} else {
page_number = 1;
}
if (id < totalPages) {
uploaddata();
}
}
}
Then in ajax controller you can retrieve data from collection by using pagination like this :
$page = $this->getRequest()->getParam('page', 1);
$collection->setPageSize(50)
->setCurPage($page)
->setOrder('id','DESC');
-
Please check this link magento.stackexchange.com/a/358189/82670– MsquareCommented Jul 25, 2022 at 9:55