Lister

class Atk4\Ui\Lister

Lister can be used to output unstructured data with your own HTML template. If you wish to output data in a table, see Table. Lister is also the fastest way to render large amount of output and will probably give you most flexibility.

Basic Usage

The most common use is when you need to implement a certain HTML and if that HTML contains list of items. If your HTML looks like this:

<div class="ui header">Top 20 countries (alphabetically)</div>
    <div class="ui icon label"><i class="ae flag"></i> Andorra</div>
    <div class="ui icon label"><i class="cm flag"></i> Camerroon</div>
    <div class="ui icon label"><i class="ca flag"></i> Canada</div>
</div>

you should put that into file myview.html then use it with a view:

$view = View::addTo($app, ['template' => 'myview.html']);

Now your application should contain list of 3 sample countries as you have specified in HTML, but next we need to add some tags into your template:

<div class="ui header">Top {limit}20{/limit} countries (alphabetically)</div>
    {Countries}
    {rows}
    {row}
    <div class="ui icon label"><i class="ae flag"></i> Andorra</div>
    {/row}
    <div class="ui icon label"><i class="cm flag"></i> Camerroon</div>
    <div class="ui icon label"><i class="ca flag"></i> Canada</div>
    {/rows}
    {/Countries}
</div>

Here the {Countries} region will be replaced with the lister, but the contents of this region will be re-used as the list template. Refresh your page and your output should not be affected at all, because View clears out all extra template tags.

Next I’ll add Lister:

Lister::addTo($view, [], ['Countries'])
    ->setModel(new Country($db))
    ->setLimit(20);

While most other objects in Agile UI come with their own templates, lister will prefer to use template inside your region. It will look for “row” and “rows” tag:

  1. Create clone of {row} tag
  2. Delete contents of {rows} tag
  3. For each model row, populate values into {row}
  4. Render {row} and append into {rows}

If you refresh your page now, you should see “Andorra” duplicated 20 times. This is because the {row} did not contain any field tags. Lets set them up:

{row}
<div class="ui icon label"><i class="{iso}ae{/} flag"></i> {name}Andorra{/name}</div>
{/row}

Refresh your page and you should see list of countries as expected. The flags are not showing yet, but I’ll deal with in next section. For now, lets clean up the template by removing unnecessary tag content:

<div class="ui header">Top {limit}20{/limit} countries (alphabetically)</div>
    {Countries}
    {rows}
    {row}
    <div class="ui icon label"><i class="{$iso} flag"></i> {$name}</div>
    {/row}
    {/rows}
    {/Countries}
</div>

Finally, Lister permits you not to use {rows} and {row} tags if entire region can be considered as a row:

<div class="ui header">Top {limit}20{/limit} countries (alphabetically)</div>
    {Countries}
    <div class="ui icon label"><i class="{$iso} flag"></i> {$name}</div>
    {/Countries}
</div>

Tweaking the output

Output is formatted using the standard uiPersistence routine, but you can also fine-tune the content of your tags like this:

$lister->onHook(\Atk4\Ui\Lister::HOOK_BEFORE_ROW, function (\Atk4\Ui\Lister $lister) {
    $lister->currentRow->set('iso', mb_strtolower($lister->currentRow->get('iso')));
});

Model vs Static Source

Since Lister is non-interactive, you can also set a static source for your lister to avoid hassle:

$lister->setSource([
    ['flag' => 'ca', 'name' => 'Canada'],
    ['flag' => 'uk', 'name' => 'UK'],
]);

Special template tags

Your {row} template may contain few special tags:

  • {$_id} - will be set to ID of the record (regardless of how your id_field is called)
  • {$_title} - will be set to the title of your record (see $model->$titleField)
  • {$_href} - will point to current page but with ?id=123 extra GET argument.

Load page content dynamically when scrolling

You can make lister load page content dynamically when user is scrolling down page.

$lister->addJsPaginator(20, $options = [], $container = null, $scrollRegion = null);

The first parameter is the number of item you wish to load per page. The second parameter is options you want to pass to respective JS widget. The third parameter is the $container view holding the lister and where scrolling is applicable. And last parameter is CSS selector of element in which you want to do scrolling.

Using without Template

Agile UI comes with a one sample template for your lister, although it’s not set by default, you can specify it explicitly:

Lister::addTo($app, ['defaultTemplate' => 'lister.html']);

This should display a list nicely formatted by Fomantic-UI, with header, links, icons and description area.