View source
<?php
namespace Drupal\views_show_more\Plugin\views\pager;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\pager\SqlBase;
class ShowMore extends SqlBase {
public function summaryTitle() {
$initial = !empty($this->options['initial']) ? $this->options['initial'] : $this->options['items_per_page'];
$offset = '';
if (!empty($this->options['offset'])) {
$offset = ', skip ' . $this->options['offset'];
}
return $this
->formatPlural($initial, 'Initial @initial item, ', 'Initial @initial items, ', [
'@initial' => $initial,
]) . $this
->formatPlural($this->options['items_per_page'], 'Per click @count item', 'Per click @count items', [
'@count' => $this->options['items_per_page'],
]) . $offset;
}
protected function defineOptions() {
$options = parent::defineOptions();
$options['result_display_method'] = [
'default' => 'append',
];
$options['initial'] = [
'default' => 0,
];
$options['show_more_text'] = [
'default' => $this
->t('Show more'),
'translatable' => TRUE,
];
$options['show_more_empty_text'] = [
'default' => '',
'translatable' => TRUE,
];
$options['effects'] = [
'contains' => [
'type' => [
'default' => 'none',
],
'speed_type' => [
'default' => '',
],
'speed' => [
'default' => '',
],
'speed_value' => [
'default' => '',
],
'scroll_offset' => [
'default' => '50',
],
],
];
$options['advance'] = [
'contains' => [
'content_selector' => [
'default' => '',
],
'pager_selector' => [
'default' => '',
],
],
];
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$exclude = [
'total_pages',
'expose',
'tags',
];
foreach ($exclude as $ex) {
unset($form[$ex]['#title']);
unset($form[$ex]['#description']);
$form[$ex]['#attributes'] = [
'class' => [
'visually-hidden',
],
];
}
$form['result_display_method'] = [
'#type' => 'select',
'#title' => $this
->t('Result display method'),
'#description' => $this
->t('<strong>Append</strong> result display method append the new content after the existing content on the page in ajax mode and in no-ajax mode replace the content by page refresh. <strong>Replace</strong> result display method replace the content with new content both in ajax and no-ajax mode. In no-ajax mode it refresh the page.'),
'#options' => [
'append' => $this
->t('Append'),
'html' => $this
->t('Replace'),
],
'#default_value' => $this->options['result_display_method'] ? $this->options['result_display_method'] : 'append',
'#weight' => 0,
];
$form['show_more_text'] = [
'#type' => 'textfield',
'#title' => $this
->t('Show more pager link text'),
'#description' => $this
->t('Text for the button which used to load more items. Like "Show More".'),
'#default_value' => $this->options['show_more_text'] ? $this->options['show_more_text'] : $this
->t('Show more'),
'#required' => TRUE,
'#weight' => 1,
];
$form['show_more_empty_text'] = [
'#type' => 'textfield',
'#title' => $this
->t('Show more pager link text when empty'),
'#description' => $this
->t('Empty text when no more items exist to load. Like "No more results".'),
'#default_value' => $this->options['show_more_empty_text'] ? $this->options['show_more_empty_text'] : '',
'#weight' => 2,
];
$form['initial'] = [
'#type' => 'number',
'#title' => $this
->t('Initial items'),
'#description' => $this
->t('The number of items to display initially. Enter 0 for use same as items per page (show more click).'),
'#default_value' => $this->options['initial'] ? $this->options['initial'] : 0,
'#weight' => 3,
'#min' => 0,
];
$form['items_per_page']['#description'] = $this
->t('The number of items to display per show more click.');
$form['items_per_page']['#weight'] = 4;
$form['offset']['#weight'] = 5;
$form['id']['#weight'] = 5;
$form['effects'] = [
'#type' => 'details',
'#open' => FALSE,
'#tree' => TRUE,
'#title' => $this
->t('Animation'),
'#input' => TRUE,
'#weight' => 7,
];
$form['effects']['type'] = [
'#type' => 'select',
'#options' => [
'none' => $this
->t('None'),
'fade' => $this
->t('FadeIn'),
'scroll' => $this
->t('Scroll to New Content'),
'scroll_fade' => $this
->t('Scroll to New Content & FadeIn'),
],
'#default_vaue' => 'none',
'#title' => $this
->t('Animation Type'),
'#default_value' => $this->options['effects']['type'],
];
$form['effects']['speed_type'] = [
'#type' => 'select',
'#options' => [
'slow' => $this
->t('Slow'),
'fast' => $this
->t('Fast'),
'custom' => $this
->t('Custom'),
],
'#states' => [
'invisible' => [
':input[name="pager_options[effects][type]"]' => [
[
'value' => 'none',
],
],
],
],
'#title' => $this
->t('Animation Speed'),
'#default_value' => $this->options['effects']['speed_type'],
];
$form['effects']['speed_value'] = [
'#type' => 'number',
'#title' => $this
->t('Animation speed in ms'),
'#states' => [
'visible' => [
':input[name="pager_options[effects][speed_type]"]' => [
'value' => 'custom',
],
],
],
'#min' => 0,
'#default_value' => $this->options['effects']['speed_value'],
];
$form['effects']['scroll_offset'] = [
'#type' => 'number',
'#title' => t('Scroll Offset'),
'#states' => [
'visible' => [
':input[name="pager_options[effects][type]"]' => [
[
'value' => 'scroll',
],
[
'value' => 'scroll_fade',
],
],
],
],
'#min' => 0,
'#default_value' => $this->options['effects']['scroll_offset'],
];
$form['advance'] = [
'#type' => 'details',
'#open' => FALSE,
'#tree' => TRUE,
'#title' => $this
->t('Advanced Options'),
'#input' => TRUE,
'#weight' => 9,
];
$form['advance']['content_selector'] = [
'#type' => 'textfield',
'#title' => $this
->t('Content jquery selector'),
'#description' => $this
->t('jQuery selector for the rows wrapper, relative to the view container. Use when you override the views markup. Views Show More pager requires a wrapping element for the rows. Default is <strong><code>".view-content"</code></strong>.'),
'#default_value' => $this->options['advance']['content_selector'],
];
$form['advance']['pager_selector'] = [
'#type' => 'textfield',
'#title' => $this
->t('Pager jquery selector'),
'#description' => $this
->t('jQuery selector for the pager, relative to the view container. Use when you override the pager markup. Default is <strong><code>".pager-show-more"</code></strong>.'),
'#default_value' => $this->options['advance']['pager_selector'],
];
}
public function validateOptionsForm(&$form, FormStateInterface $form_state) {
$effect_speed = $form_state
->getValue([
'pager_options',
'effects',
'speed_type',
]);
$effect_speed_val = $form_state
->getValue([
'pager_options',
'effects',
'speed_value',
]);
if ($effect_speed == 'custom') {
if ($effect_speed_val == '') {
$form_state
->setErrorByName('pager_options][effects][speed_value', $this
->t('Animation speed is required.'));
}
else {
$form_state
->setValue([
'pager_options',
'effects',
'speed',
], $effect_speed_val);
}
}
else {
$form_state
->setValue([
'pager_options',
'effects',
'speed',
], $effect_speed);
}
}
public function query() {
parent::query();
$others_page = $this->options['items_per_page'];
$limit = !empty($this->options['initial']) ? $this->options['initial'] : $others_page;
$offset = !empty($this->options['offset']) ? $this->options['offset'] : 0;
if ($this->current_page != 0) {
$offset = $limit + ($this->current_page - 1) * $others_page + $offset;
$limit = $others_page;
}
$this->view->query
->setLimit($limit);
$this->view->query
->setOffset($offset);
}
public function render($input) {
$output = [
'#theme' => $this
->themeFunctions(),
'#element' => $this->options['id'],
'#parameters' => $input,
'#options' => $this->options,
];
if ($this->view->display_handler
->usesAJAX()) {
$output['#attached'] = [
'library' => [
'views_show_more/views_show_more',
],
];
}
return $output;
}
public function getPagerTotal() {
if ($items_per_page = intval($this
->getItemsPerPage())) {
if ($initial_items = intval($this
->getInitial())) {
return 1 + ceil(($this->total_items - $initial_items) / $items_per_page);
}
else {
return ceil($this->total_items / $items_per_page);
}
}
else {
return 1;
}
}
public function executeCountQuery(&$count_query) {
$this->total_items = $count_query
->execute()
->fetchField();
if (!empty($this->options['offset'])) {
$this->total_items -= $this->options['offset'];
}
$this
->updatePageInfo();
return $this->total_items;
}
private function getInitial() {
$items_per_page = intval($this
->getItemsPerPage());
return isset($this->options['initial']) ? $this->options['initial'] : $items_per_page;
}
}