Winter CMS resources and help articles

Simple and to the point. Optimized by the community.

Display Next & Previous record buttons in a form

1
by LukeTowers, last modified on October 5th, 2021

If you would like to display "Previous" and "Next" buttons in the backend forms of your Winter CMS project you can do the following. This trick assumes you are implementing the FormController and ListController behaviors.

In your Controller, override the action method you would like to see the buttons in to include the following:

public function preview($id)
    {
        $record = $this->formFindModelObject($id);

        // Initialize the ListController
        $this->makeLists();

        // Get the position of the current record within the current list set
        $listQuery = $this->listGetWidget()->prepareQuery();
        $totalRecords = $listQuery->count();
        \DB::statement(\DB::raw('set @row_num=0'));
        $listQuery->selectRaw('@row_num:= @row_num + 1 as `record_position`');

        $previousId = 0;
        $nextId = 0;
        $currentIndex = null;
                // Note, if you have few records overall but massive sizes per record you can use
                // $listQuery->cursor() to make one DB query per record instead of loading them all at once
        foreach ($listQuery->get() as $listRecord) {
            if ($listRecord->getKey() === $record->getKey()) {
                $currentIndex = $listRecord->record_position;
                continue;
            } elseif ($currentIndex) {
                $nextId = $listRecord->getKey();
                break;
            } else {
                $previousId = $listRecord->getKey();
            }
        }

        $this->vars = array_merge($this->vars, [
            'previousUrl'  => $previousId ? Backend::url('myauthor/myplugin/mycontroller/preview/' . $previousId) : '',
            'nextUrl'      => $nextId ? Backend::url('myauthor/myplugin/mycontroller/' . $nextId) : '',
            'currentIndex' => $currentIndex,
            'totalRecords' => $totalRecords,
        ]);

        if (!$record->is_read) {
            $record->markRead();
        }

        return $this->asExtension('FormController')->preview($id);
    }

And then in your action view file (i.e. preview.htm), you can include the following:

        <p>
            Record <strong><?= e($currentIndex); ?></strong> of <strong><?= e($totalRecords); ?></strong>. <a href="<?= \Backend::url('myauthor/myplugin/mycontroller/'); ?>">View all</a>
        </p>
        <p>
            <button
                type="button"
                class="btn btn-primary wn-icon-chevron-left"
                onClick="window.location.assign('<?= e($previousUrl); ?>');"
                <?php if (!$previousUrl) : ?>disabled="disabled"<?php endif; ?>
            >Previous</button>
            <button
                type="button"
                class="btn btn-primary wn-icon-chevron-right"
                onClick="window.location.assign('<?= e($nextUrl); ?>');"
                <?php if (!$nextUrl) : ?>disabled="disabled"<?php endif; ?>
            >Next</button>
        </p>

This will take into account the currently applied column orders and list filters present on the index page for your controller.

Discussion

0 comments

We use cookies to measure the performance of this website. Do you want to accept these cookies?