Skip to content

Lazy resource count ​

This example counts matching resources after its placeholder becomes visible. The initial page does not run the resource query.

Use the installation setup and the ResourcesTable and schema from search and pagination. Save the files at the paths in their docblocks.

php
<?php
declare(strict_types=1);

namespace App\Island;

use Cake\ORM\Locator\LocatorAwareTrait;
use Interact\Attribute\Prop;
use Interact\Island;

/**
 * Counts matching resources when the island is rendered, including after a deferred mount.
 *
 * Save as src/Island/ResourceCountIsland.php. The named finder belongs to ResourcesTable.
 */
class ResourceCountIsland extends Island
{
    use LocatorAwareTrait;

    #[Prop]
    public string $search = '';

    /**
     * Keep query execution on the server and outside the initial placeholder render.
     *
     * @return array<string, mixed> Computed values for the native element.
     */
    public function viewData(): array
    {
        return ['total' => $this->fetchTable('Resources')->find('matching', search: $this->search)->count()];
    }
}
php
<?php
declare(strict_types=1);

/**
 * templates/island/resource_count.php
 *
 * @var \Interact\View\TemplateView $this
 * @var int $total
 */
?>
<section aria-label="Resource count">
    <p><?= $total ?> matching resources</p>
    <?= $this->Form->button('Refresh count', [
        'type' => 'button',
        '@click' => '$server.sync()',
        ':disabled' => '$server.busy',
    ]) ?>
</section>
php
<?= $this->Interact->render('ResourceCount', loading: 'lazy') ?>

Load on demand ​

For a custom placeholder with a load button, use manual:

php
<?php
declare(strict_types=1);
use function Cake\Core\h;

/**
 * templates/element/Loading/resource_count.php
 *
 * @var \Interact\View\TemplateView $this
 * @var string $search
 */
?>
<section aria-label="Resource count placeholder">
    <p>Count resources matching “<?= (string)h($search) ?>”.</p>
    <?= $this->Form->button('Load count', [
        'type' => 'button',
        '@click' => '$server.sync()',
        ':disabled' => '$server.busy',
    ]) ?>
    <p role="alert" x-text="$server.error ? $server.error.message : ''"></p>
</section>
php
<?= $this->Interact->render(
    'ResourceCount',
    props: ['search' => 'Resource 01'],
    loading: 'manual',
    placeholder: 'Loading/resource_count',
) ?>

The placeholder receives $search from the declared prop. Its button initializes the island; the loaded template's button refreshes the count normally. See lazy loading for modes, authorization, and recovery. The larger demo at /loading also demonstrates independent reports, hidden panels, parent refreshes, and removal while loading.