0

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?

1

2 Answers 2

1

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);
            }
        });
    });
})

Click Here to Download

I Hope This Helps You.

0

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');
1

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.