kartik-v / yii2-widget-select2

Enhanced Yii2 wrapper for the Select2 jQuery plugin (sub repo split from yii2-widgets).
http://demos.krajee.com/widget-details/select2
Other
323 stars 145 forks source link

Ajax Load More Problem when using limit lower than 6 #287

Closed buttflattery closed 5 years ago

buttflattery commented 5 years ago

Prerequisites

Steps to reproduce the issue

1.Install Widget 2.Configure the widget with the Ajax Load More options 3.Set the limit 5 in you query on the server side code, to display only 5 records at a time.

Expected behavior and actual behavior

When scroll down i expect that the remaining pages/records will be displayed.

When I follow those steps, I see...

No more pages are shown if try to scroll down although the label displays loading more results

image

The reason being that the scroll bar isnt enabled if i set only 5 records to be displayed in the select2, and unless a scrollbar is enabled inside the select2 it wont trigger the next call to the url to fetch the next 5 records.

If is set my limit to 6 in my server side code where i am sending the response to the select2 then everything starts working correctly.

I am not sure if this bug or issue relates to the core plugin or not i didnt tested it.

Environment

Browsers

Operating System

Libraries

Isolating the problem

kartik-v commented 5 years ago

I am not sure of how you are configuring the plugin. But it seems whatever you are trying for ajax results loading is an inherent behavior of the select2 plugin ajax call settings. It will automatically load more results in batches. You may want to cross check the plugin documentation to understand and debug your code output to see if there are limitations or errors in your ajax calls. Cross check the ajax templates demo where everything works fine.

buttflattery commented 5 years ago

@kartik-v i can add the sample code tomorrow if you want it, but its the default settings and there are only 2 fields on the page where i am using one is Select2(single select) and select2(multi select), and the link you provided is broken?

kartik-v commented 5 years ago

The link is updated.

buttflattery commented 5 years ago

@kartik-v I dont think the mentioned link uses a page size of 5 i am pretty sure you will get the same results if you configure your server-side query to display only 5 records at a time.

See the below code i am using for the setup of the select2 and the server-side code, there are only 2 selcts on the page (although i am adding only one of them below) no other 3rd parth plugin being used on the page and there arent any errors on the console when i try the Previously mentioned Steps.

If it would have been some kind of result formatting or any other problem, atleast the ajax call should be triggered when you scroll down but as i said with 5 records the scroll bar isnt populated and hence does not trigger the ajax call.

Before adding this comment i repeated the same steps and to be sure that what i am saying is correct i changed the max-height:200px; in the class .select2-container--bootstrap .select2-results > .select2-results__options at line to 150px; and it did what i thought it starts working correctly because the scroll bar is enabled again.

Hope i am making sense now


<div class="row clearfix">
    <div class="col-sm-6">
        <?php
            echo
            $form->field(
                $model,
                'id',
                [
                    'template' => '{input}{error}',
                ]
            )->widget(
                Select2::class,
                [
                    'options' => [
                        'placeholder' => 'Select Campaign',
                        'class' => 'form-control',
                        'id' => 'campaigns',
                    ],
                    'theme' => Select2::THEME_BOOTSTRAP,
                    'pluginOptions' => [
                        'minimumInputLength' => 3,
                        'allowClear' => true,
                        'ajax' => [
                            'url' => Url::to(['/user/campaign/campaign-listing']),
                            'method' => 'POST',
                            'dataType' => 'json',
                            'data' => new JsExpression(
                                'function(params){
                                    let request_params= {
                                        q:params.term,
                                        page:params.page || 1
                                    };
                                    request_params[yii.getCsrfParam()]=yii.getCsrfToken();
                                    return request_params;
                                }'
                            ),
                        ],
                    ],
                    'pluginEvents' => [
                        'select2:select' => 'function(e){
                            selected(e.params.data.id);
                            $("#subscribers").prop("disabled", false);
                        }',
                        'select2:unselect' => 'function(e){
                            clearMultiSelect();
                            $.fn.select2.defaults.reset();
                            $("#subscribers").prop("disabled", true);
                        }',
                    ],
                ]
            )->label(false);
        ?>
    </div>
</div>

The following code is used to return the result required by the select2


/**
     * Return the json list of the camapigns matching the keyword
     *
     * @return json campaigns
     */
    public function actionCampaignListing()
    {
        Yii::$app->response->format = Response::FORMAT_JSON;
        $response = ['results' => ['id' => '', 'text' => '']];

        if (Yii::$app->request->isPost) {
            $page = Yii::$app->request->post('page');
            $keyword = Yii::$app->request->post('q', null);

            $limit = 5;
            $offset = ($page - 1) * $limit;

            //default query condition uesd in the query
            $queryCondition = [
                'AND',
                ['=', 'c.user_id', Yii::$app->user->id],
                ['like', 'c.name', $keyword],
            ];

            //sub query for the total count
            $totalQuery = new Query();
            $count = $totalQuery
                ->select([new Expression('COUNT(c.id) as total')])
                ->from(Campaign::tableName() . ' c')
                ->where($queryCondition)
                ->limit(1)
                ->one();

            //campaign list to be displayed according to the page size
            $query = new Query();
            $data = $query
                ->select(
                    [
                        'c.id',
                        'c.name as text',
                    ]
                )->from(Campaign::tableName() . ' c')
                ->where($queryCondition)
                ->limit($limit)
                ->offset($offset)
                ->all();

            $response['results'] = array_values($data);
            $response['pagination'] = [
                'more' => $count['total'] > $offset ? true : false,
            ];
            return $response;

        }
    }