kartik-v / yii2-date-range

A Date Range Picker for Bootstrap useful for reports and filtering.
http://demos.krajee.com/date-range
Other
93 stars 81 forks source link

Asset registration order issue using in GridView #45

Closed TimNZ closed 9 years ago

TimNZ commented 9 years ago

Hi, I'm finding the JS assets are rendered in the wrong order when using FILTER_DATE_RANGE column in your GridView - can't see why this is happening after a good look at the code and comparing to DatePicker code flow for asset registration

Latest version of everything. CustomGridView extends Kartik GridView

class CustomGridView extends \kartik\grid\GridView{

    public function init()
    {

        parent::init();
        $this->export = false;
    }

    public function run(){
        return parent::run();
    }

    public function registerAssets()
    {
        parent::registerAssets();
    }

}

View filter snippet

    <?php \yii\widgets\Pjax::begin(['linkSelector' => '[data-sort],[data-page]']); ?>
    <?= CustomGridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel, 'showHeader' => $showHeader,
        'filterPosition' => $filterPosition,
        'formatter' => ['class' => 'yii\i18n\Formatter', 'nullDisplay' => ''],
        'columns' => $columns
    ]); ?>
    <?php \yii\widgets\Pjax::end(); ?>

columns snippet:

            [
                'filterType'=>CustomGridView::FILTER_DATE_RANGE,
                'attribute' => 'search_date',
                'label' => 'Date',
                'headerOptions' => ['class' => 'pager-date-column'],
                'format' => 'date',
                'filterWidgetOptions'=>[
                    'pluginOptions' => [
                    ]
                ]
            ],

Rendered page JS, yii.gridView.js is included before jquery.js, no yii.js

<script src="/assets/b90ee649/yii.gridView.js?v=1431288587"></script>
<script src="/assets/84597792/js/daterangepicker.js?v=1435631484"></script>
<script src="/assets/7329f298/jquery.pjax.js?v=1432264189"></script>
<script src="/assets/65a6fa36/jquery.js?v=1430236984"></script>
<script src="/assets/cf374a95/jquery-ui.js?v=1432264189"></script>
<script src="/assets/e97f2b3/js/bootstrap.js?v=1434471202"></script>
<script src="/assets/768646cf/jquery.slimscroll.js?v=1432264189"></script>
<script src="/assets/57a98a69/js/app.js?v=1432264194"></script>
<script src="/assets/3ae58f8a/dist/html5shiv.min.js?v=1432264189"></script>
<script src="/assets/89aab66e/fuelux/js/fuelux.min.js?v=1432264193"></script>
<script src="http://men.dev//js/lodash.min.js?v=1432264186"></script>
<script src="http://men.dev//js/moment.min.js?v=1432264186"></script>
<script src="http://men.dev//js/bootbox.min.js?v=1432264186"></script>
<script src="http://men.dev//js/app.js?v=1436432407"></script>
<script src="http://men.dev//js/plugins.js?v=1435692606"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.2.0/q.min.js"></script>
<script src="/assets/ca468c97/subscription_dashboard.js?v=1433899806"></script>
<script src="/assets/9a1b013d/admin.js?v=1435875900"></script>
<script type="text/javascript">window.App.currentUser ={ id: 1  };</script>
<script type="text/javascript">jQuery(document).ready(function () {
jQuery('#w1').yiiGridView({"filterUrl":"\/admin\/user\/2\/subscriptions\/1\/transactions","filterSelector":"#w1-filters input, #w1-filters select"});
jQuery("#subscriptiontransactionsearch-search_date").daterangepicker(daterangepicker_2bc54c98);

Works fine for FILTER_DATE

            [
                'filterType'=>CustomGridView::FILTER_DATE,
                'attribute' => 'search_date',
                'label' => 'Date',
                'headerOptions' => ['class' => 'pager-date-column'],
                'format' => 'date',
                'filterWidgetOptions'=>[
                    'pluginOptions' => [
                    ]
                ]
            ],

Correct JS order

</script><script src="/assets/65a6fa36/jquery.js?v=1430236984"></script>
<script src="/assets/b90ee649/yii.js?v=1431288587"></script>
<script src="/assets/b90ee649/yii.gridView.js?v=1431288587"></script>
<script src="/assets/4b3889f0/js/bootstrap-datepicker.js?v=1435632223"></script>
<script src="/assets/4b3889f0/js/datepicker-kv.js?v=1435632223"></script>
<script src="/assets/7329f298/jquery.pjax.js?v=1432264189"></script>
<script src="/assets/cf374a95/jquery-ui.js?v=1432264189"></script>
<script src="/assets/e97f2b3/js/bootstrap.js?v=1434471202"></script>
<script src="/assets/768646cf/jquery.slimscroll.js?v=1432264189"></script>
<script src="/assets/57a98a69/js/app.js?v=1432264194"></script>
<script src="/assets/3ae58f8a/dist/html5shiv.min.js?v=1432264189"></script>
<script src="/assets/89aab66e/fuelux/js/fuelux.min.js?v=1432264193"></script>
<script src="http://men.dev//js/lodash.min.js?v=1432264186"></script>
<script src="http://men.dev//js/moment.min.js?v=1432264186"></script>
<script src="http://men.dev//js/bootbox.min.js?v=1432264186"></script>
<script src="http://men.dev//js/app.js?v=1436432407"></script>
<script src="http://men.dev//js/plugins.js?v=1435692606"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/q.js/1.2.0/q.min.js"></script>
<script src="/assets/ca468c97/subscription_dashboard.js?v=1433899806"></script>
<script src="/assets/9a1b013d/admin.js?v=1435875900"></script>
<script type="text/javascript">window.App.currentUser ={ id: 1  };</script>
<script type="text/javascript">jQuery(document).ready(function () {
jQuery('#w1').yiiGridView({"filterUrl":"\/admin\/user\/2\/subscriptions\/1\/transactions","filterSelector":"#w1-filters input, #w1-filters select"});
jQuery('#subscriptiontransactionsearch-search_date').parent().kvDatepicker(kvDatepicker_00000000);
TimNZ commented 9 years ago

The absolute simplest example, same result

<?php

use common\components\modules\subscriptions\models\search\SubscriptionTransactionSearch;
use kartik\grid\GridView;

$searchModel = new SubscriptionTransactionSearch();
$dataProvider = $searchModel->search([]);

?>

<?=

GridView::widget([
    'export' => false,
    'dataProvider' => $dataProvider, 'filterModel' => $searchModel,
    'formatter' => ['class' => 'yii\i18n\Formatter', 'nullDisplay' => ''],
    'columns' => [ ['filterType' => GridView::FILTER_DATE_RANGE, 'attribute' => 'search_date']]
]); ?>
TimNZ commented 9 years ago

I've tracked this down to the jsOptions property in MomentAsset.php

public $jsOptions = ['position' => \yii\web\View::POS_HEAD];

As a result of this, there is duplication of jquery.js, in the as well as end of the page.

<head> snippet

<script src="/assets/65a6fa36/jquery.js?v=1430236984"></script>
<script src="/assets/b90ee649/yii.js?v=1431288587"></script>
<script src="/assets/84597792/js/moment.js?v=1435631484"></script>
<script type="text/javascript">var daterangepicker_e795653c = {"format":"DD\/MM\/YYYY","separator":" A ","ranges":{"Today":[moment().startOf('day'),moment()],"Yesterday":[moment().startOf('day').subtract(1,'days'),moment().endOf('day').subtract(1,'days')],"Last 7 Days":[moment().startOf('day').subtract(6, 'days'),moment()],"Last 30 Days":[moment().startOf('day').subtract(29, 'days'),moment()],"This Month":[moment().startOf('month'),moment().endOf('month')],"Last Month":[moment().subtract(1, 'month').startOf('month'),moment().subtract(1, 'month').endOf('month')]}};
</script>

If I change MomentAsset to extend from yii\base\AssetBundle, it works fine.

class MomentAsset extends AssetBundle
{
    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];

    public $js = ['js/moment.js'];
    /**
     * @inheritdoc
     */
    public function init()
    {
        $this->sourcePath = __DIR__ . '/assets';
        // $this->setupAssets('js', ['js/moment']);
        parent::init();
    }

}
kartik-v commented 9 years ago

Not sure what you are doing is correct or can be reproduced. Since you are using your own custom grid view cannot help much. Try doing this with the extension's inbuilt classes and check. For anything you are extending, you need to ensure and check your asset bundle dependencies.

MomentAsset does not depend on other assets or jquery asset. So it should not be causing any problem unless you are overriding the classes and assets differently. All asset bundles in Krajee are made to work with kartik\krajee\AssetBundle. By altering the asset bundles it will break other extension code and not recommended.

Seems to be some javascript asset conflict or javascript error. if you are using third party themes or javascript code DISABLE THEM. I would recommend you to remove all other third party extensions in your code - and test just yii2-date-range widget first to see if it works. Then slowly add yii2-grid and see if it works and proceed from there. Do a test with a stock installed yii2-app-basic app for example without any third party assets or themes.