├── .gitignore ├── LICENSE.md ├── README.md ├── ScrollPager.php ├── assets ├── IASHistoryExtensionAsset.php ├── IASNoneLeftExtensionAsset.php ├── IASPagingExtensionAsset.php ├── IASSpinnerExtensionAsset.php ├── IASTriggerExtensionAsset.php └── InfiniteAjaxScrollAsset.php ├── composer.json ├── composer.lock └── messages ├── cs └── general.php ├── de └── general.php ├── en └── general.php ├── es └── general.php ├── fa-IR └── general.php ├── fr └── general.php ├── it └── general.php ├── nl └── general.php ├── pl └── general.php ├── pt-BR └── general.php ├── ru └── general.php ├── uk └── general.php └── zh-CN └── general.php /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE files 2 | .idea/ 3 | 4 | # Composer dependencies 5 | vendor/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2016 Ivan Koptiev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Yii2 Scroll Pager 2 | ================= 3 | 4 | [Yii2 Scroll Pager (Y2SP)](http://kop.github.io/yii2-scroll-pager) turns your regular paginated page into an 5 | infinite scrolling page using AJAX. 6 | 7 | Y2SP works with a `Pagination` object which specifies the totally number of pages and the current page number. 8 | 9 | Pager is build with help of [JQuery Infinite Ajax Scroll plugin](http://infiniteajaxscroll.com/). 10 | 11 | [![Latest Stable Version](https://poser.pugx.org/kop/yii2-scroll-pager/v/stable.svg)](https://packagist.org/packages/kop/yii2-scroll-pager) 12 | [![Code Climate](https://codeclimate.com/github/kop/yii2-scroll-pager.png)](https://codeclimate.com/github/kop/yii2-scroll-pager) 13 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/kop/yii2-scroll-pager/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/kop/yii2-scroll-pager/?branch=master) 14 | [![Dependency Status](https://gemnasium.com/kop/yii2-scroll-pager.svg)](https://gemnasium.com/kop/yii2-scroll-pager) 15 | [![License](https://poser.pugx.org/kop/yii2-scroll-pager/license.svg)](https://packagist.org/packages/kop/yii2-scroll-pager) 16 | 17 | 18 | 19 | ## Requirements 20 | 21 | - Yii 2.0 22 | - PHP 5.4 23 | 24 | 25 | 26 | ## Installation 27 | 28 | The preferred way to install this extension is through [Composer](http://getcomposer.org/). 29 | 30 | Either run 31 | 32 | ``` php composer.phar require kop/yii2-scroll-pager "dev-master" ``` 33 | 34 | or add 35 | 36 | ``` "kop/yii2-scroll-pager": "dev-master"``` 37 | 38 | to the `require` section of your `composer.json` file. 39 | 40 | 41 | 42 | ## Usage 43 | 44 | Just pass the ScrollPager class name to the ListView `pager` configuration. 45 | Make sure that items in your list have some classes that can be used as JavaScript selectors. 46 | 47 | ### ListView 48 | 49 | ```php 50 | echo ListView::widget([ 51 | 'dataProvider' => $dataProvider, 52 | 'itemOptions' => ['class' => 'item'], 53 | 'itemView' => '_item_view', 54 | 'pager' => ['class' => \kop\y2sp\ScrollPager::className()] 55 | ]); 56 | ``` 57 | 58 | ### ListView (Advanced example) 59 | 60 | Here you can see how you can use variable `{{ias}}` for events. In this example are added the new settings `linkPager`, `linkPagerOptions` and `linkPagerWrapperTemplate`. 61 | ```php 62 | echo ListView::widget([ 63 | 'options' => ['class' => 'list-view'], 64 | 'dataProvider' => $listDataProvider, 65 | 'itemOptions' => ['tag' => false], 66 | 'itemView' => '_list_item', 67 | 'summary' => '', 68 | 'layout' => '{items}{pager}', 69 | 'pager' => [ 70 | 'class' => \kop\y2sp\ScrollPager::className(), 71 | 'item' => 'article', 72 | 'next' => '.next a', 73 | 'paginationSelector' => '.list-view .pagination', 74 | 'triggerText' => Yii::t('app', 'Show more'), 75 | 'triggerTemplate' => '{text}', 76 | 'noneLeftText' => '', 77 | 'noneLeftTemplate' => '', 78 | 'spinnerSrc' => '', 79 | 'spinnerTemplate' => '', 80 | 'linkPager' => [ 81 | 'prevPageCssClass' => 'btn-link prev', 82 | 'nextPageCssClass' => 'btn-link next', 83 | 'prevPageLabel' => 'prev', 84 | 'nextPageLabel' => 'next', 85 | ], 86 | 'linkPagerOptions' => [ 87 | 'class' => 'pagination', 88 | ], 89 | 'linkPagerWrapperTemplate' => '
{pager}
', 90 | 'eventOnPageChange' => 'function() {{{ias}}.hidePagination();}', 91 | 'eventOnReady' => 'function() {{{ias}}.restorePagination();}', 92 | ], 93 | ]); 94 | ``` 95 | 96 | ### GridView 97 | 98 | ```php 99 | echo GridView::widget([ 100 | 'dataProvider' => $dataProvider, 101 | 'pager' => [ 102 | 'class' => \kop\y2sp\ScrollPager::className(), 103 | 'container' => '.grid-view tbody', 104 | 'item' => 'tr', 105 | 'paginationSelector' => '.grid-view .pagination', 106 | 'triggerTemplate' => '{text}', 107 | ], 108 | ]); 109 | ``` 110 | 111 | 112 | ## Configuration 113 | 114 | 115 | ### General Options 116 | 117 | | Option name | Description | Default value | 118 | |--- |--- |--- | 119 | | container | The selector of the element containing your items that you want to paginate. | `.list-view` | 120 | | item | The selector of the element that each item has.
The href attribute of this element will be used to get the items from the next page.
Make sure there is only one(1) element that matches the selector. | `.next a` | 123 | | delay | Minimal number of milliseconds to stay in a loading state. | `600` | 124 | | negativeMargin | By default IAS starts loading new items when you scroll to the latest `.item` element.
The `negativeMargin` will be added to the items offset, giving you the ability to load new items earlier (please note that the margin is always transformed to a negative integer).

*Example:* Setting a negativeMargin of 250 means that IAS will start loading 250 pixel before the last item has scrolled into view. | `10` | 125 | 126 | 127 | ### Extensions 128 | 129 | | Option name | Description | Default value | 130 | |--- |--- |--- | 131 | | enabledExtensions | The list of the enabled plugin extensions. | [
  `ScrollPager::EXTENSION_TRIGGER`,
  `ScrollPager::EXTENSION_SPINNER`,
  `ScrollPager::EXTENSION_NONE_LEFT`,
  `ScrollPager::EXTENSION_PAGING`,
  `ScrollPager::EXTENSION_HISTORY`
] | 132 | 133 | 134 | ### Extension Options 135 | 136 | | Option name | Description | Default value | 137 | |--- |--- |--- | 138 | | triggerText | Text of trigger the link. | `Load more items` | 139 | | triggerTemplate | Allows you to override the trigger html template. | `
{text}
` | 140 | | triggerOffset | The number of pages which should load automatically. After that the trigger is shown for every subsequent page.

*Example:* if you set the offset to 2, the pages 2 and 3 (page 1 is always shown) would load automatically and for every subsequent page the user has to press the trigger to load it. | `0` | 141 | | spinnerSrc | The src attribute of the spinner image. | ![Spinner Image](https://raw.githubusercontent.com/kop/yii2-scroll-pager/v1.0.2/assets/infinite-ajax-scroll/images/loader.gif) | 142 | | spinnerTemplate | Allows you to override the spinner html template. | `
` | 143 | | noneLeftText | Text of the "nothing left" message. | `You reached the end` | 144 | | noneLeftTemplate | Allows you to override the "nothing left" message html template. | `
{text}
` | 145 | | historyPrev | The selector of the link element that links to the previous page.
The href attribute of this element will be used to get the items from the previous page.
Make sure there is only one element that matches the selector. | `.previous` | 146 | | historyPrevText | Text of previous page trigger. | `Load previous items` | 147 | | historyPrevTemplate | Allows you to override the previous trigger html template. | `
{text}
'` | 148 | | overflowContainer | A selector for `div` HTML element to use as an overflow container. | `null` | 149 | 150 | 151 | ### Plugin Events 152 | 153 | | Option name | Description | Default value | 154 | |--- |--- |--- | 155 | | eventOnScroll | Triggered when the visitors scrolls. | `null` | 156 | | eventOnLoad | Triggered when a new url will be loaded from the server. | `null` | 157 | | eventOnLoaded | Triggered after a new page was loaded from the server. | `null` | 158 | | eventOnRender | Triggered before new items will be rendered. | `null` | 159 | | eventOnRendered | Triggered after new items have rendered. | `null` | 160 | | eventOnNoneLeft | Triggered when there are no more pages left. | `null` | 161 | | eventOnNext | Triggered when the next page should be loaded.
Happens before loading of the next page starts. With this event it is possible to cancel the loading of the next page.
You can do this by returning false from your callback. | `null` | 162 | | eventOnReady | Triggered when IAS and all the extensions have been initialized. | `null` | 163 | | eventOnPageChange | Triggered when a used scroll to another page. | `null` | 164 | 165 | 166 | 167 | ## Report 168 | 169 | - Report any issues [on the GitHub](https://github.com/kop/yii2-scroll-pager/issues). 170 | 171 | 172 | 173 | ## License 174 | 175 | **yii2-scroll-pager** is released under the MIT License. See the bundled `LICENSE.md` for details. 176 | 177 | 178 | 179 | ## Resources 180 | 181 | - [Project Page](http://kop.github.io/yii2-scroll-pager) 182 | - [Packagist Package](https://packagist.org/packages/kop/yii2-scroll-pager) 183 | - [Source Code](https://github.com/kop/yii2-scroll-pager) -------------------------------------------------------------------------------- /ScrollPager.php: -------------------------------------------------------------------------------- 1 | 22 | * Example usage: 23 | * 24 | * echo ListView::widget([ 25 | * 'dataProvider' => $dataProvider, 26 | * 'itemOptions' => ['class' => 'item'], 27 | * 'itemView' => '_item_view', 28 | * 'pager' => ['class' => \kop\y2sp\ScrollPager::className()] 29 | * ]); 30 | * 31 | * 32 | * This widget is using {@link http://infiniteajaxscroll.com/ JQuery Infinite Ajax Scroll plugin}. 33 | * 34 | * @link http://kop.github.io/yii2-scroll-pager Y2SP project page. 35 | * @license https://github.com/kop/yii2-scroll-pager/blob/master/LICENSE.md MIT 36 | * 37 | * @author Ivan Koptiev 38 | */ 39 | class ScrollPager extends Widget 40 | { 41 | /** 42 | * @const EXTENSION_TRIGGER IAS Extension "IASTriggerExtension". 43 | */ 44 | const EXTENSION_TRIGGER = 'IASTriggerExtension'; 45 | 46 | /** 47 | * @const EXTENSION_SPINNER IAS Extension "IASSpinnerExtension". 48 | */ 49 | const EXTENSION_SPINNER = 'IASSpinnerExtension'; 50 | 51 | /** 52 | * @const EXTENSION_NONE_LEFT IAS Extension "IASNoneLeftExtension". 53 | */ 54 | const EXTENSION_NONE_LEFT = 'IASNoneLeftExtension'; 55 | 56 | /** 57 | * @const EXTENSION_PAGING IAS Extension "IASPagingExtension". 58 | */ 59 | const EXTENSION_PAGING = 'IASPagingExtension'; 60 | 61 | /** 62 | * @const EXTENSION_HISTORY IAS Extension "IASHistoryExtension". 63 | */ 64 | const EXTENSION_HISTORY = 'IASHistoryExtension'; 65 | 66 | /** 67 | * @var string $container Enter the selector of the element containing your items that you want to paginate. 68 | */ 69 | public $container = '.list-view'; 70 | 71 | /** 72 | * @var string $item Enter the selector of the element that each item has. 73 | * Make sure the elements are inside the container element. 74 | */ 75 | public $item = '.item'; 76 | 77 | /** 78 | * @var string $paginationSelector Enter the selector of the element containing the pagination. 79 | */ 80 | public $paginationSelector = '.list-view .pagination'; 81 | 82 | /** 83 | * @var string $next Enter the selector of the link element that links to the next page. 84 | * The href attribute of this element will be used to get the items from the next page. 85 | * Make sure there is only one(1) element that matches the selector. 86 | */ 87 | public $next = '.next a'; 88 | 89 | /** 90 | * @var int $delay Minimal number of milliseconds to stay in a loading state. 91 | */ 92 | public $delay = 600; 93 | 94 | /** 95 | * @var int $thresholdMargin On default IAS starts loading new items when you scroll to the latest .item element. 96 | * The negativeMargin will be added to the items' offset, giving you the ability to load new items earlier 97 | * (please note that the margin is always transformed to a negative integer). 98 | *

99 | * For example: 100 | *
101 | * Setting a negativeMargin of 250 means that IAS will start loading 250 pixel before the last item has scrolled into view. 102 | */ 103 | public $negativeMargin = 10; 104 | 105 | /** 106 | * @var string $triggerText Text of trigger the link. 107 | * Default: "Load more items". 108 | */ 109 | public $triggerText; 110 | 111 | /** 112 | * @var string $triggerTemplate Allows you to override the trigger html template. 113 | */ 114 | public $triggerTemplate = '
{text}
'; 115 | 116 | /** 117 | * @var int $triggerOffset The number of pages which should load automatically. 118 | * After that the trigger is shown for every subsequent page. 119 | *

120 | * For example: 121 | *
122 | * if you set the offset to 2, the pages 2 and 3 (page 1 is always shown) would load automatically and for every 123 | * subsequent page the user has to press the trigger to load it. 124 | */ 125 | public $triggerOffset = 0; 126 | 127 | /** 128 | * @var string $spinnerSrc The src attribute of the spinner image. 129 | */ 130 | public $spinnerSrc; 131 | 132 | /** 133 | * @var string $spinnerTemplate Allows you to override the spinner html template. 134 | */ 135 | public $spinnerTemplate = '
'; 136 | 137 | /** 138 | * @var string $noneLeftText Text of the "nothing left" message. 139 | * Default: "You reached the end". 140 | */ 141 | public $noneLeftText; 142 | 143 | /** 144 | * @var string $noneLeftTemplate Allows you to override the "nothing left" message html template. 145 | */ 146 | public $noneLeftTemplate = '
{text}
'; 147 | 148 | /** 149 | * @var string $historyPrev Enter the selector of the link element that links to the previous page. 150 | * The href attribute of this element will be used to get the items from the previous page. 151 | * Make sure there is only one element that matches the selector. 152 | */ 153 | public $historyPrev = '.previous'; 154 | 155 | /** 156 | * @var null $historyPrevText Text of the "load previous" message. 157 | * Default: "Load previous items". 158 | */ 159 | public $historyPrevText = null; 160 | 161 | /** 162 | * @var string $historyPrevTemplate Allows you to override the "load previous" message html template. 163 | */ 164 | public $historyPrevTemplate = '
{text}
'; 165 | 166 | /** 167 | * @var string $overflowContainer A selector for "div" HTML element to use as an overflow container. 168 | * @see http://infiniteajaxscroll.com/examples/overflow.html 169 | */ 170 | public $overflowContainer; 171 | 172 | /** 173 | * @var string|JsExpression $eventOnScroll Triggered when the visitors scrolls. 174 | * @see http://infiniteajaxscroll.com/docs/events.html 175 | */ 176 | public $eventOnScroll; 177 | 178 | /** 179 | * @var string|JsExpression $eventOnLoad Triggered when a new url will be loaded from the server. 180 | * @see http://infiniteajaxscroll.com/docs/events.html 181 | */ 182 | public $eventOnLoad; 183 | 184 | /** 185 | * @var string|JsExpression $eventOnLoaded Triggered after a new page was loaded from the server. 186 | * @see http://infiniteajaxscroll.com/docs/events.html 187 | */ 188 | public $eventOnLoaded; 189 | 190 | /** 191 | * @var string|JsExpression $eventOnRender Triggered before new items will be rendered. 192 | * @see http://infiniteajaxscroll.com/docs/events.html 193 | */ 194 | public $eventOnRender; 195 | 196 | /** 197 | * @var string|JsExpression $eventOnRendered Triggered after new items have rendered. 198 | * Note: This event is only fired once. 199 | * @see http://infiniteajaxscroll.com/docs/events.html 200 | */ 201 | public $eventOnRendered; 202 | 203 | /** 204 | * @var string|JsExpression $eventOnNoneLeft Triggered when there are no more pages left. 205 | * @see http://infiniteajaxscroll.com/docs/events.html 206 | */ 207 | public $eventOnNoneLeft; 208 | 209 | /** 210 | * @var string|JsExpression $eventOnNext Triggered when the next page should be loaded. 211 | * Happens before loading of the next page starts. With this event it is possible to cancel the loading of the next page. 212 | * You can do this by returning false from your callback. 213 | * @see http://infiniteajaxscroll.com/docs/events.html 214 | */ 215 | public $eventOnNext; 216 | 217 | /** 218 | * @var string|JsExpression $eventOnReady Triggered when IAS and all the extensions have been initialized. 219 | * @see http://infiniteajaxscroll.com/docs/events.html 220 | */ 221 | public $eventOnReady; 222 | 223 | /** 224 | * @var string|JsExpression $eventOnPageChange Triggered when a used scroll to another page. 225 | * @see http://infiniteajaxscroll.com/docs/extension-paging.html 226 | */ 227 | public $eventOnPageChange; 228 | 229 | /** 230 | * @var array $enabledExtensions The list of the enabled plugin extensions. 231 | */ 232 | public $enabledExtensions = [ 233 | self::EXTENSION_TRIGGER, 234 | self::EXTENSION_SPINNER, 235 | self::EXTENSION_NONE_LEFT, 236 | self::EXTENSION_PAGING, 237 | self::EXTENSION_HISTORY 238 | ]; 239 | 240 | /** 241 | * @var \yii\data\Pagination The pagination object that this pager is associated with. 242 | * You must set this property in order to make ScrollPager work. 243 | */ 244 | public $pagination; 245 | 246 | /** 247 | * @var array The options for yii\widgets\LinkPager. 248 | */ 249 | public $linkPager = []; 250 | public $linkPagerOptions; 251 | 252 | /** 253 | * @var $linkPagerWrapper string Wrapper template for pagination. 254 | */ 255 | public $linkPagerWrapperTemplate = '{pager}'; 256 | 257 | /** 258 | * Initializes the pager. 259 | */ 260 | public function init() 261 | { 262 | parent::init(); 263 | 264 | // Register translations source 265 | Yii::$app->i18n->translations = ArrayHelper::merge(Yii::$app->i18n->translations, [ 266 | 'kop\y2sp' => [ 267 | 'class' => PhpMessageSource::className(), 268 | 'basePath' => '@vendor/kop/yii2-scroll-pager/messages', 269 | 'fileMap' => [ 270 | 'kop\y2sp' => 'general.php' 271 | ] 272 | ] 273 | ]); 274 | 275 | // Register required assets 276 | $this->registerAssets(); 277 | 278 | // Set default trigger text if not set 279 | if ($this->triggerText === null) { 280 | $this->triggerText = Yii::t('kop\y2sp', 'Load more items'); 281 | } 282 | 283 | // Set default "none left" message text if not set 284 | if ($this->noneLeftText === null) { 285 | $this->noneLeftText = Yii::t('kop\y2sp', 'You reached the end'); 286 | } 287 | 288 | // Set default "load previous" message text if not set 289 | if ($this->historyPrevText === null) { 290 | $this->historyPrevText = Yii::t('kop\y2sp', 'Load previous items'); 291 | } 292 | 293 | // Set default class for pagination 294 | if ($this->linkPagerOptions === null) { 295 | $this->linkPagerOptions = ['class' => 'pagination hidden']; 296 | } elseif (!isset($this->linkPagerOptions['class'])) { 297 | $this->linkPagerOptions['class'] = 'pagination hidden'; 298 | } 299 | } 300 | 301 | /** 302 | * Executes the widget. 303 | * 304 | * This overrides the parent implementation by initializing jQuery IAS and displaying the generated page buttons. 305 | * 306 | * @return mixed 307 | * @throws \yii\base\InvalidConfigException 308 | */ 309 | public function run() 310 | { 311 | // Initialize jQuery IAS plugin 312 | $pluginSettings = Json::encode([ 313 | 'container' => $this->container, 314 | 'item' => $this->item, 315 | 'pagination' => $this->paginationSelector, 316 | 'next' => $this->next, 317 | 'delay' => $this->delay, 318 | 'negativeMargin' => $this->negativeMargin 319 | ]); 320 | $initString = empty($this->overflowContainer) 321 | ? "if(typeof window.{$this->id}_ias === 'object') { window.{$this->id}_ias.reinitialize() } 322 | else { window.{$this->id}_ias = jQuery.ias({$pluginSettings}); };" 323 | : "if(typeof window.{$this->id}_ias === 'object') { window.{$this->id}_ias.reinitialize() } 324 | else { window.{$this->id}_ias = jQuery('{$this->overflowContainer}').ias({$pluginSettings}); };"; 325 | $this->view->registerJs($initString, View::POS_READY, "{$this->id}_ias_main"); 326 | 327 | // Register IAS extensions 328 | $this->registerExtensions([ 329 | [ 330 | 'name' => self::EXTENSION_PAGING 331 | ], 332 | [ 333 | 'name' => self::EXTENSION_SPINNER, 334 | 'options' => 335 | !empty($this->spinnerSrc) 336 | ? ['html' => $this->spinnerTemplate, 'src' => $this->spinnerSrc] 337 | : ['html' => $this->spinnerTemplate] 338 | ], 339 | [ 340 | 'name' => self::EXTENSION_TRIGGER, 341 | 'options' => [ 342 | 'text' => $this->triggerText, 343 | 'html' => $this->triggerTemplate, 344 | 'offset' => $this->triggerOffset, 345 | 'textPrev' => $this->historyPrevText, 346 | 'htmlPrev' => $this->historyPrevTemplate, 347 | ] 348 | ], 349 | [ 350 | 'name' => self::EXTENSION_NONE_LEFT, 351 | 'options' => [ 352 | 'text' => $this->noneLeftText, 353 | 'html' => $this->noneLeftTemplate 354 | ] 355 | ], 356 | [ 357 | 'name' => self::EXTENSION_HISTORY, 358 | 'options' => [ 359 | 'prev' => $this->historyPrev 360 | ], 361 | 'depends' => [ 362 | self::EXTENSION_TRIGGER, 363 | self::EXTENSION_PAGING 364 | ] 365 | ] 366 | ]); 367 | 368 | // Register event handlers 369 | $this->registerEventHandlers([ 370 | 'scroll' => [], 371 | 'load' => [], 372 | 'loaded' => [], 373 | 'render' => [], 374 | 'rendered' => [], 375 | 'noneLeft' => [], 376 | 'next' => [], 377 | 'ready' => [], 378 | 'pageChange' => [ 379 | self::EXTENSION_PAGING, 380 | ] 381 | ]); 382 | 383 | // Render pagination links with wrapper 384 | echo str_replace( 385 | '{pager}', 386 | LinkPager::widget([ 387 | 'pagination' => $this->pagination, 388 | 'options' => $this->linkPagerOptions, 389 | ] + $this->linkPager), 390 | $this->linkPagerWrapperTemplate 391 | ); 392 | } 393 | 394 | /** 395 | * Register required asset bundles. 396 | * 397 | * You can override this method in case if you want to use your own JQuery Infinite Ajax Scroll plugin files 398 | * (for example, some forked plugin version). 399 | */ 400 | protected function registerAssets() 401 | { 402 | InfiniteAjaxScrollAsset::register($this->view); 403 | } 404 | 405 | /** 406 | * Register jQuery IAS extensions. 407 | * 408 | * This method takes jQuery IAS extensions definition as a parameter and registers this extensions. 409 | * 410 | * @param array $config jQuery IAS extensions definition. 411 | * @throws \yii\base\InvalidConfigException If extension dependencies are not met. 412 | */ 413 | protected function registerExtensions(array $config) 414 | { 415 | foreach ($config as $entry) { 416 | 417 | // Parse config entry values 418 | $name = ArrayHelper::getValue($entry, 'name', false); 419 | $options = ArrayHelper::getValue($entry, 'options', ''); 420 | $depends = ArrayHelper::getValue($entry, 'depends', []); 421 | 422 | // If extension is enabled 423 | if (in_array($name, $this->enabledExtensions)) { 424 | 425 | // Make sure dependencies are met 426 | if (!$this->checkEnabledExtensions($depends)) { 427 | throw new InvalidConfigException( 428 | "Extension {$name} requires " . implode(', ', $depends) . " extensions to be enabled." 429 | ); 430 | } 431 | $this->view->registerAssetBundle("kop\y2sp\assets\\{$name}Asset"); 432 | 433 | // Register extension 434 | $options = Json::encode($options); 435 | $this->view->registerJs(<<id}_ias.extensions.map(function(item) {return item.constructor.name;}).indexOf('$name')) === -1) { 438 | // prevent duplicate plugin registration 439 | window.{$this->id}_ias.extension(new $name($options)); 440 | }; 441 | } 442 | )(); 443 | JS 444 | , 445 | View::POS_READY, 446 | "{$this->id}_ias_{$name}" 447 | ); 448 | } 449 | } 450 | } 451 | 452 | /** 453 | * Register jQuery IAS event handlers. 454 | * 455 | * This method takes jQuery IAS event handlers definition as a parameter and registers this event handlers. 456 | * 457 | * @param array $config jQuery IAS event handlers definition. 458 | * @throws \yii\base\InvalidConfigException If vent handlers dependencies are not met. 459 | */ 460 | protected function registerEventHandlers(array $config) 461 | { 462 | foreach ($config as $name => $depends) { 463 | 464 | // If event is enabled 465 | $eventName = 'eventOn' . ucfirst($name); 466 | if (!empty($this->$eventName)) { 467 | 468 | // Make sure dependencies are met 469 | if (!$this->checkEnabledExtensions($depends)) { 470 | throw new InvalidConfigException( 471 | "The \"{$name}\" event requires " . implode(', ', $depends) . " extensions to be enabled." 472 | ); 473 | } 474 | 475 | // Replace the variable template 476 | $callback = str_replace('{{ias}}', "{$this->id}_ias", $this->$eventName); 477 | 478 | // Register event 479 | $this->view->registerJs( 480 | "window.{$this->id}_ias.on('{$name}', {$callback});", 481 | View::POS_READY, 482 | "{$this->id}_ias_event_{$eventName}" 483 | ); 484 | } 485 | } 486 | } 487 | 488 | /** 489 | * Check whether the given extensions are enabled. 490 | * 491 | * @param string|array $extensions Single or multiple extensions names. 492 | * @return bool Operation result. 493 | */ 494 | protected function checkEnabledExtensions($extensions) 495 | { 496 | $extensions = (array)$extensions; 497 | if (empty($extensions)) { 498 | return true; 499 | } else { 500 | return (count(array_intersect($this->enabledExtensions, $extensions)) == count($extensions)); 501 | } 502 | } 503 | } 504 | -------------------------------------------------------------------------------- /assets/IASHistoryExtensionAsset.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class InfiniteAjaxScrollAsset extends AssetBundle 18 | { 19 | 20 | public $sourcePath = '@vendor/webcreate/jquery-ias/src'; 21 | 22 | public $js = [ 23 | 'callbacks.js', 24 | 'jquery-ias.js' 25 | ]; 26 | 27 | /** 28 | * @var array List of bundle class names that this bundle depends on. 29 | */ 30 | public $depends = [ 31 | 'yii\web\JqueryAsset', 32 | ]; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kop/yii2-scroll-pager", 3 | "description": "Infinite AJAX scrolling for Yii2 ListView widget", 4 | "homepage": "http://kop.github.io/yii2-scroll-pager/", 5 | "keywords": ["yii", "yii2", "scroll", "scrolling", "pager", "pagination"], 6 | "type": "yii2-extension", 7 | "license": "MIT", 8 | "support": { 9 | "issues": "https://github.com/kop/yii2-scroll-pager/issues", 10 | "source": "https://github.com/kop/yii2-scroll-pager" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Ivan Koptiev", 15 | "email": "ivan.koptiev@codex.systems", 16 | "role": "Developer" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=5.4.0", 21 | "yiisoft/yii2": "*", 22 | "webcreate/jquery-ias": "^2.2.1" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "kop\\y2sp\\": "" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "hash": "ee698be436b713e87919b57ccdb1d5e9", 8 | "content-hash": "f7fd419df60c0e15a6d052af21d142eb", 9 | "packages": [ 10 | { 11 | "name": "bower-asset/jquery", 12 | "version": "2.2.2", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/jquery/jquery-dist.git", 16 | "reference": "086d381cd2f3b4b8b0af85ecb2c9593a61e5b4bd" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/jquery/jquery-dist/zipball/086d381cd2f3b4b8b0af85ecb2c9593a61e5b4bd", 21 | "reference": "086d381cd2f3b4b8b0af85ecb2c9593a61e5b4bd", 22 | "shasum": "" 23 | }, 24 | "type": "bower-asset-library", 25 | "extra": { 26 | "bower-asset-main": "dist/jquery.js", 27 | "bower-asset-ignore": [ 28 | "package.json" 29 | ] 30 | }, 31 | "license": [ 32 | "MIT" 33 | ], 34 | "keywords": [ 35 | "browser", 36 | "javascript", 37 | "jquery", 38 | "library" 39 | ] 40 | }, 41 | { 42 | "name": "bower-asset/jquery.inputmask", 43 | "version": "3.2.7", 44 | "source": { 45 | "type": "git", 46 | "url": "https://github.com/RobinHerbots/jquery.inputmask.git", 47 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38" 48 | }, 49 | "dist": { 50 | "type": "zip", 51 | "url": "https://api.github.com/repos/RobinHerbots/jquery.inputmask/zipball/5a72c563b502b8e05958a524cdfffafe9987be38", 52 | "reference": "5a72c563b502b8e05958a524cdfffafe9987be38", 53 | "shasum": "" 54 | }, 55 | "require": { 56 | "bower-asset/jquery": ">=1.7" 57 | }, 58 | "type": "bower-asset-library", 59 | "extra": { 60 | "bower-asset-main": [ 61 | "./dist/inputmask/inputmask.js" 62 | ], 63 | "bower-asset-ignore": [ 64 | "**/*", 65 | "!dist/*", 66 | "!dist/inputmask/*", 67 | "!dist/min/*", 68 | "!dist/min/inputmask/*", 69 | "!extra/bindings/*", 70 | "!extra/dependencyLibs/*", 71 | "!extra/phone-codes/*" 72 | ] 73 | }, 74 | "license": [ 75 | "http://opensource.org/licenses/mit-license.php" 76 | ], 77 | "description": "jquery.inputmask is a jquery plugin which create an input mask.", 78 | "keywords": [ 79 | "form", 80 | "input", 81 | "inputmask", 82 | "jquery", 83 | "mask", 84 | "plugins" 85 | ] 86 | }, 87 | { 88 | "name": "bower-asset/punycode", 89 | "version": "v1.3.2", 90 | "source": { 91 | "type": "git", 92 | "url": "https://github.com/bestiejs/punycode.js.git", 93 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3" 94 | }, 95 | "dist": { 96 | "type": "zip", 97 | "url": "https://api.github.com/repos/bestiejs/punycode.js/zipball/38c8d3131a82567bfef18da09f7f4db68c84f8a3", 98 | "reference": "38c8d3131a82567bfef18da09f7f4db68c84f8a3", 99 | "shasum": "" 100 | }, 101 | "type": "bower-asset-library", 102 | "extra": { 103 | "bower-asset-main": "punycode.js", 104 | "bower-asset-ignore": [ 105 | "coverage", 106 | "tests", 107 | ".*", 108 | "component.json", 109 | "Gruntfile.js", 110 | "node_modules", 111 | "package.json" 112 | ] 113 | } 114 | }, 115 | { 116 | "name": "bower-asset/yii2-pjax", 117 | "version": "v2.0.6", 118 | "source": { 119 | "type": "git", 120 | "url": "https://github.com/yiisoft/jquery-pjax.git", 121 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978" 122 | }, 123 | "dist": { 124 | "type": "zip", 125 | "url": "https://api.github.com/repos/yiisoft/jquery-pjax/zipball/60728da6ade5879e807a49ce59ef9a72039b8978", 126 | "reference": "60728da6ade5879e807a49ce59ef9a72039b8978", 127 | "shasum": "" 128 | }, 129 | "require": { 130 | "bower-asset/jquery": ">=1.8" 131 | }, 132 | "type": "bower-asset-library", 133 | "extra": { 134 | "bower-asset-main": "./jquery.pjax.js", 135 | "bower-asset-ignore": [ 136 | ".travis.yml", 137 | "Gemfile", 138 | "Gemfile.lock", 139 | "CONTRIBUTING.md", 140 | "vendor/", 141 | "script/", 142 | "test/" 143 | ] 144 | }, 145 | "license": [ 146 | "MIT" 147 | ] 148 | }, 149 | { 150 | "name": "cebe/markdown", 151 | "version": "1.1.0", 152 | "source": { 153 | "type": "git", 154 | "url": "https://github.com/cebe/markdown.git", 155 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2" 156 | }, 157 | "dist": { 158 | "type": "zip", 159 | "url": "https://api.github.com/repos/cebe/markdown/zipball/54a2c49de31cc44e864ebf0500a35ef21d0010b2", 160 | "reference": "54a2c49de31cc44e864ebf0500a35ef21d0010b2", 161 | "shasum": "" 162 | }, 163 | "require": { 164 | "lib-pcre": "*", 165 | "php": ">=5.4.0" 166 | }, 167 | "require-dev": { 168 | "cebe/indent": "*", 169 | "facebook/xhprof": "*@dev", 170 | "phpunit/phpunit": "4.1.*" 171 | }, 172 | "bin": [ 173 | "bin/markdown" 174 | ], 175 | "type": "library", 176 | "extra": { 177 | "branch-alias": { 178 | "dev-master": "1.1.x-dev" 179 | } 180 | }, 181 | "autoload": { 182 | "psr-4": { 183 | "cebe\\markdown\\": "" 184 | } 185 | }, 186 | "notification-url": "https://packagist.org/downloads/", 187 | "license": [ 188 | "MIT" 189 | ], 190 | "authors": [ 191 | { 192 | "name": "Carsten Brandt", 193 | "email": "mail@cebe.cc", 194 | "homepage": "http://cebe.cc/", 195 | "role": "Creator" 196 | } 197 | ], 198 | "description": "A super fast, highly extensible markdown parser for PHP", 199 | "homepage": "https://github.com/cebe/markdown#readme", 200 | "keywords": [ 201 | "extensible", 202 | "fast", 203 | "gfm", 204 | "markdown", 205 | "markdown-extra" 206 | ], 207 | "time": "2015-03-06 05:28:07" 208 | }, 209 | { 210 | "name": "ezyang/htmlpurifier", 211 | "version": "v4.6.0", 212 | "source": { 213 | "type": "git", 214 | "url": "https://github.com/ezyang/htmlpurifier.git", 215 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd" 216 | }, 217 | "dist": { 218 | "type": "zip", 219 | "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/6f389f0f25b90d0b495308efcfa073981177f0fd", 220 | "reference": "6f389f0f25b90d0b495308efcfa073981177f0fd", 221 | "shasum": "" 222 | }, 223 | "require": { 224 | "php": ">=5.2" 225 | }, 226 | "type": "library", 227 | "autoload": { 228 | "psr-0": { 229 | "HTMLPurifier": "library/" 230 | }, 231 | "files": [ 232 | "library/HTMLPurifier.composer.php" 233 | ] 234 | }, 235 | "notification-url": "https://packagist.org/downloads/", 236 | "license": [ 237 | "LGPL" 238 | ], 239 | "authors": [ 240 | { 241 | "name": "Edward Z. Yang", 242 | "email": "admin@htmlpurifier.org", 243 | "homepage": "http://ezyang.com" 244 | } 245 | ], 246 | "description": "Standards compliant HTML filter written in PHP", 247 | "homepage": "http://htmlpurifier.org/", 248 | "keywords": [ 249 | "html" 250 | ], 251 | "time": "2013-11-30 08:25:19" 252 | }, 253 | { 254 | "name": "webcreate/jquery-ias", 255 | "version": "v2.2.1", 256 | "source": { 257 | "type": "git", 258 | "url": "https://github.com/webcreate/infinite-ajax-scroll.git", 259 | "reference": "7380f74fca64180a4c5da18d01065a8aef0494b7" 260 | }, 261 | "dist": { 262 | "type": "zip", 263 | "url": "https://api.github.com/repos/webcreate/infinite-ajax-scroll/zipball/7380f74fca64180a4c5da18d01065a8aef0494b7", 264 | "reference": "7380f74fca64180a4c5da18d01065a8aef0494b7", 265 | "shasum": "" 266 | }, 267 | "type": "library", 268 | "notification-url": "https://packagist.org/downloads/", 269 | "license": [ 270 | "proprietary", 271 | "MIT" 272 | ], 273 | "authors": [ 274 | { 275 | "name": "fieg", 276 | "email": "jeroen@fieg.nl", 277 | "homepage": "http://webcreate.nl" 278 | } 279 | ], 280 | "description": "Infinite AJAX Scroll: A jQuery plugin that turns your server-side pagination into an infinite scrolling one using AJAX", 281 | "homepage": "http://infiniteajaxscroll.com", 282 | "keywords": [ 283 | "ajax", 284 | "ias", 285 | "infinite", 286 | "jquery", 287 | "pagination", 288 | "scroll", 289 | "scrolling" 290 | ], 291 | "time": "2015-05-08 14:58:16" 292 | }, 293 | { 294 | "name": "yiisoft/yii2", 295 | "version": "2.0.7", 296 | "source": { 297 | "type": "git", 298 | "url": "https://github.com/yiisoft/yii2-framework.git", 299 | "reference": "f45651582cb853b4326730d9d187a0f7a44a45a3" 300 | }, 301 | "dist": { 302 | "type": "zip", 303 | "url": "https://api.github.com/repos/yiisoft/yii2-framework/zipball/f45651582cb853b4326730d9d187a0f7a44a45a3", 304 | "reference": "f45651582cb853b4326730d9d187a0f7a44a45a3", 305 | "shasum": "" 306 | }, 307 | "require": { 308 | "bower-asset/jquery": "2.2.*@stable | 2.1.*@stable | 1.11.*@stable", 309 | "bower-asset/jquery.inputmask": "~3.2.2", 310 | "bower-asset/punycode": "1.3.*", 311 | "bower-asset/yii2-pjax": "~2.0.1", 312 | "cebe/markdown": "~1.0.0 | ~1.1.0", 313 | "ext-ctype": "*", 314 | "ext-mbstring": "*", 315 | "ezyang/htmlpurifier": "4.6.*", 316 | "lib-pcre": "*", 317 | "php": ">=5.4.0", 318 | "yiisoft/yii2-composer": "~2.0.4" 319 | }, 320 | "bin": [ 321 | "yii" 322 | ], 323 | "type": "library", 324 | "extra": { 325 | "branch-alias": { 326 | "dev-master": "2.0.x-dev" 327 | } 328 | }, 329 | "autoload": { 330 | "psr-4": { 331 | "yii\\": "" 332 | } 333 | }, 334 | "notification-url": "https://packagist.org/downloads/", 335 | "license": [ 336 | "BSD-3-Clause" 337 | ], 338 | "authors": [ 339 | { 340 | "name": "Qiang Xue", 341 | "email": "qiang.xue@gmail.com", 342 | "homepage": "http://www.yiiframework.com/", 343 | "role": "Founder and project lead" 344 | }, 345 | { 346 | "name": "Alexander Makarov", 347 | "email": "sam@rmcreative.ru", 348 | "homepage": "http://rmcreative.ru/", 349 | "role": "Core framework development" 350 | }, 351 | { 352 | "name": "Maurizio Domba", 353 | "homepage": "http://mdomba.info/", 354 | "role": "Core framework development" 355 | }, 356 | { 357 | "name": "Carsten Brandt", 358 | "email": "mail@cebe.cc", 359 | "homepage": "http://cebe.cc/", 360 | "role": "Core framework development" 361 | }, 362 | { 363 | "name": "Timur Ruziev", 364 | "email": "resurtm@gmail.com", 365 | "homepage": "http://resurtm.com/", 366 | "role": "Core framework development" 367 | }, 368 | { 369 | "name": "Paul Klimov", 370 | "email": "klimov.paul@gmail.com", 371 | "role": "Core framework development" 372 | }, 373 | { 374 | "name": "Dmitry Naumenko", 375 | "email": "d.naumenko.a@gmail.com", 376 | "role": "Core framework development" 377 | } 378 | ], 379 | "description": "Yii PHP Framework Version 2", 380 | "homepage": "http://www.yiiframework.com/", 381 | "keywords": [ 382 | "framework", 383 | "yii2" 384 | ], 385 | "time": "2016-02-14 14:45:55" 386 | }, 387 | { 388 | "name": "yiisoft/yii2-composer", 389 | "version": "2.0.4", 390 | "source": { 391 | "type": "git", 392 | "url": "https://github.com/yiisoft/yii2-composer.git", 393 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464" 394 | }, 395 | "dist": { 396 | "type": "zip", 397 | "url": "https://api.github.com/repos/yiisoft/yii2-composer/zipball/7452fd908a5023b8bb5ea1b123a174ca080de464", 398 | "reference": "7452fd908a5023b8bb5ea1b123a174ca080de464", 399 | "shasum": "" 400 | }, 401 | "require": { 402 | "composer-plugin-api": "^1.0" 403 | }, 404 | "type": "composer-plugin", 405 | "extra": { 406 | "class": "yii\\composer\\Plugin", 407 | "branch-alias": { 408 | "dev-master": "2.0.x-dev" 409 | } 410 | }, 411 | "autoload": { 412 | "psr-4": { 413 | "yii\\composer\\": "" 414 | } 415 | }, 416 | "notification-url": "https://packagist.org/downloads/", 417 | "license": [ 418 | "BSD-3-Clause" 419 | ], 420 | "authors": [ 421 | { 422 | "name": "Qiang Xue", 423 | "email": "qiang.xue@gmail.com" 424 | } 425 | ], 426 | "description": "The composer plugin for Yii extension installer", 427 | "keywords": [ 428 | "composer", 429 | "extension installer", 430 | "yii2" 431 | ], 432 | "time": "2016-02-06 00:49:24" 433 | } 434 | ], 435 | "packages-dev": [], 436 | "aliases": [], 437 | "minimum-stability": "stable", 438 | "stability-flags": [], 439 | "prefer-stable": false, 440 | "prefer-lowest": false, 441 | "platform": { 442 | "php": ">=5.4.0" 443 | }, 444 | "platform-dev": [] 445 | } 446 | -------------------------------------------------------------------------------- /messages/cs/general.php: -------------------------------------------------------------------------------- 1 | 'Načíst další položky', 4 | 'You reached the end' => 'Dostali jste se na konec' 5 | ]; 6 | -------------------------------------------------------------------------------- /messages/de/general.php: -------------------------------------------------------------------------------- 1 | 'Weitere Einträge laden', 5 | 'You reached the end' => 'Keine weiteren Einträge vorhanden' 6 | ]; 7 | -------------------------------------------------------------------------------- /messages/en/general.php: -------------------------------------------------------------------------------- 1 | 'Load more items', 5 | 'You reached the end' => 'You reached the end', 6 | 'Load previous items' => 'Load previous items' 7 | ]; 8 | -------------------------------------------------------------------------------- /messages/es/general.php: -------------------------------------------------------------------------------- 1 | 'Cargar más artículos', 5 | 'You reached the end' => 'Ha llegado el final' 6 | ]; -------------------------------------------------------------------------------- /messages/fa-IR/general.php: -------------------------------------------------------------------------------- 1 | 'بارگذاری آیتم های بیشتر', 5 | 'You reached the end' => 'به پایان رسیدید' 6 | ]; -------------------------------------------------------------------------------- /messages/fr/general.php: -------------------------------------------------------------------------------- 1 | 'Charger plus d\'articles', 5 | 'You reached the end' => 'Vous avez atteint la fin' 6 | ]; -------------------------------------------------------------------------------- /messages/it/general.php: -------------------------------------------------------------------------------- 1 | 'Caricare più articoli', 5 | 'You reached the end' => 'Hai raggiunto la fine' 6 | ]; -------------------------------------------------------------------------------- /messages/nl/general.php: -------------------------------------------------------------------------------- 1 | 'Laad meer items', 5 | 'You reached the end' => 'Je hebt het einde bereikt' 6 | ]; -------------------------------------------------------------------------------- /messages/pl/general.php: -------------------------------------------------------------------------------- 1 | 'Załaduj więcej', 5 | 'You reached the end' => 'Doszedłeś do końca', 6 | 'Load previous items' => 'Załaduj poprzednie' 7 | ]; -------------------------------------------------------------------------------- /messages/pt-BR/general.php: -------------------------------------------------------------------------------- 1 | 'Carregar mais itens', 5 | 'You reached the end' => 'Você chegou ao fim' 6 | ]; -------------------------------------------------------------------------------- /messages/ru/general.php: -------------------------------------------------------------------------------- 1 | 'Загрузить больше записей', 5 | 'You reached the end' => 'Вы достигли конца' 6 | ]; -------------------------------------------------------------------------------- /messages/uk/general.php: -------------------------------------------------------------------------------- 1 | 'Завантажити більше записів', 5 | 'You reached the end' => 'Вы досягли кінця' 6 | ]; -------------------------------------------------------------------------------- /messages/zh-CN/general.php: -------------------------------------------------------------------------------- 1 | '更多', 5 | 'You reached the end' => '没有更多了' 6 | ]; --------------------------------------------------------------------------------