Yii2 全日历事件过滤不起作用

2022-01-07 00:00:00 jquery php yii2 yii2-basic-app fullcalendar

我在 Yii2 框架中使用 Philipp Frenzel FullCalendar 并且它工作得很好.我想根据选项选择在日历上实现基本过滤器事件,但我的代码仍然无法正常工作.非常感谢您的帮助.

这是在 EventController 中:

['类' =>VerbFilter::className(),'动作' =>['删除' =>['邮政'],],],];}/*** 列出所有事件模型.* @return 混合*/公共函数 actionIndex(){/*$searchModel = new EventSearch();$dataProvider = $searchModel->search(Yii::$app->request->queryParams);*/$events = Event::find()->all();$tasks = [];foreach ($events 作为 $eve){$event = new yii2fullcalendarmodelsEvent();$event->id = $eve->id;$event->backgroundColor = '绿色';$event->title = $eve->title;$event->start = $eve->created_date;$tasks[] = $event;}返回 $this->render('index', [//'searchModel' =>$搜索模型,'事件' =>$任务,]);}/*** 显示单个事件模型.* @param 整数 $id* @return 混合* @throws NotFoundHttpException 如果找不到模型*/公共函数 actionView($id){返回 $this->render('view', ['模型' =>$this->findModel($id),]);}/*** 创建一个新的事件模型.* 如果创建成功,浏览器将被重定向到查看"页面.* @return 混合*/公共函数 actionCreate($date){$model = new Event();$model->created_date = $date;if ($model->load(Yii::$app->request->post()) && $model->save()) {返回 $this->redirect(['index']);}别的{return $this->renderAjax('create', ['模型' =>$模型,]);}}/*** 更新现有的事件模型.* 如果更新成功,浏览器将被重定向到查看"页面.* @param 整数 $id* @return 混合* @throws NotFoundHttpException 如果找不到模型*/公共函数 actionUpdate($id){$model = $this->findModel($id);if ($model->load(Yii::$app->request->post()) && $model->save()) {返回 $this->redirect(['view', 'id' => $model->id]);} 别的 {return $this->renderAjax('update', ['模型' =>$模型,]);}}/*** 删除现有的事件模型.* 如果删除成功,浏览器将被重定向到索引"页面.* @param 整数 $id* @return 混合* @throws NotFoundHttpException 如果找不到模型*/公共函数 actionDelete($id){$this->findModel($id)->delete();返回 $this->redirect(['index']);}/*** 根据主键值查找事件模型.* 如果找不到模型,会抛出 404 HTTP 异常.* @param 整数 $id* @return 事件加载的模型* @throws NotFoundHttpException 如果找不到模型*/受保护的函数 findModel($id){if (($model = Event::findOne($id)) !== null) {返回 $model;}throw new NotFoundHttpException('请求的页面不存在');}/**** @param type $choice* @返回类型*/公共函数 actionFilterEvents($choice = null) {Yii::$app->reponse->format = yiiwebResponse::FORMAT_JSON;$query = modelsEvent::find();if( is_null($choice) || $choice=='all'){//该函数应该返回你之前加载的相同事件$dbEvents = $query->all();$events = $this->loadEvents($dbEvents);} 别的{//这里需要查数据库//针对您选择的相关事件$dbEvents = $query->where(['=', 'column_name', ':choice'])->params([':choice' => $choice])->asArray()-> 全部();$events = $this->loadEvents($dbEvents);}返回 $events;}/**** @param type $dbEvents* @return yii2fullcalendarmodelsEvent*/私有函数 loadEvents($dbEvents) {foreach( $dbEvents AS $event ){//测试$Event = new yii2fullcalendarmodelsEvent();$Event->id = $event->id;$Event->title = $event->categoryAsString;$Event->description = $event->description;$Event->start = date('Y-m-dTH:i:s', strtotime($event->created_date .' ' . $event->created_date));$Event->end = date('Y-m-dTH:i:s', strtotime($event->time_out .' ' . $event->time_out));$Event->status = $event->status;$Event->remarks = $event->remarks;$事件[] = $事件;}返回 $events;}}

这是事件索引:

title = 'Roster Bul Hanine Project';$this->params['breadcrumbs'][] = $this->title;$js=<<<JSvar eventSource=['/event/filter-events'];$("#select_name").on('change',function() {//获取我们过滤器的当前状态到 eventSourceNewvar eventSourceNew=['/event/filter-events?choice=' + $(this).val()];//删除旧的事件源$('#event').fullCalendar('removeEventSource', eventSource[0]);//附加新的事件源$('#event').fullCalendar('addEventSource', eventSourceNew[0]);$('#event').fullCalendar('refetchEvents');//复制到当前源eventSource = eventSourceNew;});JS;$this->registerJs($js, yiiwebView::POS_READY);?><div class="event-index"><h1><?= Html::encode($this->title) ?></h1><?php//echo $this->render('_search', ['model' => $searchModel]);?><p><?= Html::a('Create Roster', ['create'], ['class' => 'btn btn-success']) ?></p><p><select class="model_attribute" id="select_name"><option value="all">All Tech</option><option value="0">Hendy Nugraha</option><option value="1">Ginanjar Nurwin</option><option value="2">Rio Andhika</option></选择></p><div id="事件"></div><?php模态::开始(['header'=>'

名册

','id' =>'模型','尺寸' =>'模型-lg',]);echo "<div id='modelContent'></div>";模态::结束();?><?=yii2fullcalendaryii2fullcalendar::widget(array('事件'=>$事件,'id' =>'事件','clientOptions' =>['可编辑' =>真的,'事件源' =>['/event/filter-events'],'可拖动' =>真的,'droppable' =>真的,],'事件点击' =>函数(calEvent,jsEvent,视图){$(this).css('border-color', 'red');$.get('index.php?r=event/update',{'id':calEvent.id}, function(data){$('.modal').modal('show').find('#modelContent').html(数据);})$('#calendar').fullCalendar('removeEvents', function (calEvent) {返回真;});}",/*$('#event').fullCalendar({事件渲染:函数(事件,元素){if(event.status == "请假") {element.css('背景色', '#131313');} else if (event.status == "stand by") {element.css('背景色', '#678768');} else if (event.status == "active") {element.css('背景色', '#554455');}},});*/));?>

下面是我在 index.php 中评论 'events'=> $events 时的屏幕截图结果(按照您的说明).即使我通过选择选项进行选择,它也不会过滤事件

如果我取消注释事件"=> $events,它会显示所有事件,但是当我通过选择选项进行选择时,它不会过滤事件.在屏幕截图下方:

解决方案

您使用的扩展包括最新版本 FullCalendar v3.9.0.因此,请参阅最新的 API 版本 3,以获取以下所有文档参考.

方法

对我来说,如果我必须实现它,我不会使用 events 选项,因为我们需要根据从下拉列表中选择的选项在运行时过滤事件,一个更好的选项是是使用 eventSources 选项.它提供了一种指定多个事件源的方法.此选项用于代替 events 选项.您可以放置​​任意数量的 event数组、函数、JSON 提要 URL,或完整的 事件源对象进入eventSources数组.

一个基于 javascript 的简单示例

$('#calendar').fullCalendar({事件来源:['/feed1.php','/feed2.php']});

如果你查看 Fullcalendar 的文档,他们有名为 Event Data 的事件相关部分 在这里您可以看到各种选项以及提到的选项.

开始于

我们将首先为 eventSources 提供日历事件的 JSON 提要的 URL,然后删除选项 events.我将使用单一来源,如果您愿意,您也可以拥有多个来源,但我会保持简短.

更改小部件的代码并在小部件的clientOptions 选项下添加eventSources 选项.

'事件过滤日历','clientOptions' =>['可编辑' =>真的,'事件源' =>['/schedule/filter-events'],'可拖动' =>真的,'droppable' =>真的,],'事件点击' =>函数(calEvent,jsEvent,视图){$(this).css('border-color', 'red');$.get('index.php?r=event/update',{'id':calEvent.id}, function(data){$('.modal').modal('show').find('#modelContent').html(数据);});$('#calendar').fullCalendar('removeEvents', function (calEvent) {返回真;});}",));?>

此时,如果您刷新日历,您将看不到之前加载的任何事件,因为以前您使用 'events'=>$events 加载事件,但现在我们提供了一个url源'/schedule/filter-events'(把它改成你想使用的相关controller/action我会用同样的URL例如).

第二部分

因此,您之前加载的 $events 现在必须通过我们将要创建的新操作加载.如果您遵循 GitHub 页面上提供的扩展示例,并从数据库模型加载事件,然后使用 for 循环将所有事件加载到 yii2fullcalendarmodelsEvents() 模型,然后加载该数组.

由于您没有提供有关用于数据库存储和加载事件到日历的模型的任何详细信息,我假设您的模型名称是 MyEvents 相应地更改它并查询中的字段 column_name.

/**** @param type $choice* @返回类型*/公共函数 actionFilterEvents($choice = null) {Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;$query = MyEvents::find();if( is_null($choice) || $choice=='all'){//该函数应该返回你之前加载的相同事件$dbEvents = $query->all();} 别的{//这里需要查数据库//针对您选择的相关事件$dbEvents = $query->where(['=', 'column_name', ':choice'])->params([':choice' => $choice])->asArray()-> 全部();}返回 $this->loadEvents($dbEvents);}/**** @param type $dbEvents* @return yii2fullcalendarmodelsEvent*/私有函数 loadEvents($dbEvents) {foreach( $dbEvents AS $event ){//测试$Event = new yii2fullcalendarmodelsEvent();$Event->id = $event->id;$Event->title = $event->categoryAsString;$Event->start = date('Y-m-dTH:i:s', strtotime($event->date_start .' ' . $event->time_start));$Event->end = date('Y-m-dTH:i:s', strtotime($event->date_end .' ' . $event->time_end));$事件[] = $事件;}返回 $events;}

以上注意事项

  • $choice 参数在 actionFilterEvents 中,null 作为默认值,用于在日历首次加载时列出所有事件.
  • loadEvents() 方法将搜索到的事件从数据库加载到yii2fullcalendarmodelEvents,更改中使用的字段名称code>foreach 以及您将使用的相关模型字段名称,而不是 MyEvents.

此时,如果您按照上述说明正确完成了所有操作,则刷新页面后您将看到日历中加载的默认事件.

实际部分

现在是根据下拉列表的选择过滤事件的部分.对于服务器端我们已经完成了上面的工作,else 部分将通过将选定的选项与所需的列 column_name(将其替换为要与之比较的字段名称).现在还需要做的部分是客户端,我们将绑定下拉菜单的onchange事件,然后主要使用fullcalendar提供的这3个methods

  • removeEventSource,从源中动态移除一个事件源.Events将立即从日历中删除.
  • addEventSource,动态添加事件源.源可能是一个 Array/URL/Function 就像在 events 选项中一样.事件将立即从此源获取并放置在日历上.
  • refetchEvents,从所有来源重新获取事件并在屏幕.

每次我们选择一个选项时,之前的 eventSource 都会被移除,并添加一个新的 eventSource 所以基本上会构建 url schedule/filter-events?choice=all 如果选择了 All Techschedule/filter-events?choice=0 如果选择了 Hendy Nugraha,依此类推.

在您初始化小部件的视图顶部添加以下 javascript.

确保在 #select_name 下方使用的选择器与下拉列表的实际 id 匹配.

$js = <<<JSvar eventSource=['/schedule/filter-events'];$("#select_name").on('change',function() {//获取我们过滤器的当前状态到 eventSourceNewvar eventSourceNew=['/schedule/filter-events?choice=' + $(this).val()];//删除旧的事件源$('#eventFilterCalendar').fullCalendar('removeEventSource', eventSource[0]);//附加新的事件源$('#eventFilterCalendar').fullCalendar('addEventSource', eventSourceNew[0]);$('#eventFilterCalendar').fullCalendar('refetchEvents');//复制到当前源eventSource = eventSourceNew;});JS;$this->registerJs($js, yiiwebView::POS_READY);

按照上述说明执行所有操作,它将开始工作,并在您更改下拉列表中的选项后立即显示过滤结果.

注意:我已经从一个正在运行的项目中提供了上述解决方案,带有 Yii2.0.15.1 和最新的可用扩展.

编辑

我很惊讶您无法区分服务器端、HTML 和 javascript,我提供的与您需要粘贴到视图中的 javascript 相关的代码 event-indexevent-index 中a href="http://php.net/manual/en/language.types.string.php" rel="nofollow noreferrer">heredoc 你只需要复制粘贴它但不知何故你最终将 javascript 包裹在 <script> 标签中并删除了 heredoc?此外,您在脚本标签中调用 $this->registerJs() 而不是 <?php ?> 标签?¯\_(ツ)_/¯.

并且您甚至没有更改 var eventSource=['/schedule/filter-events']; 您的控制器的 javascript 代码是 Event 而不是 schedule,我在假设模型或控制器名称的每个点都写了相应的更改它,即使您的小部件代码没有相应地更新它也有 'eventSources' =>['/schedule/filter-events'], 当它应该是 'eventSources' =>['/event/filter-events'],.

所以这次只需复制粘贴下面的整个视图代码,不要更改任何内容.我不会再因为你必须正确标记它而用勺子喂你了,尽管它是正确的答案并且应该被授予赏金.

在集成代码时,排除故障和修复语法错误是您的职责.提供的解决方案有效,您未能集成它并不意味着它不是正确答案.

'event-index.php`

title = 'Roster Bul Hanine Project';$this->params['breadcrumbs'][] = $this->title;$js=<<<JSvar eventSource=['/event/filter-events'];$("#select_name").on('change',function() {//获取我们过滤器的当前状态到 eventSourceNewvar eventSourceNew=['/event/filter-events?choice=' + $(this).val()];//删除旧的事件源$('#event').fullCalendar('removeEventSource', eventSource[0]);//附加新的事件源$('#event').fullCalendar('addEventSource', eventSourceNew[0]);$('#event').fullCalendar('refetchEvents');//复制到当前源eventSource = eventSourceNew;});JS;$this->registerJs($js, yiiwebView::POS_READY);?><div class="event-index"><h1><?= Html::encode($this->title) ?></h1><?php//echo $this->render('_search', ['model' => $searchModel]);?><p><?= Html::a('Create Roster', ['create'], ['class' => 'btn btn-success']) ?></p><p><select class="model_attribute" id="select_name"><option value="all">All Tech</option><option value="0">Hendy Nugraha</option><option value="1">Ginanjar Nurwin</option><option value="2">Rio Andhika</option></选择></p><div id="事件"></div><?php模态::开始(['header'=>'

名册

','id' =>'模型','尺寸' =>'模型-lg',]);echo "<div id='modelContent'></div>";模态::结束();?><?=yii2fullcalendaryii2fullcalendar::widget(array(//'事件'=>$事件,'id' =>'事件','clientOptions' =>['可编辑' =>真的,'事件源' =>['/event/filter-events'],'可拖动' =>真的,'droppable' =>真的,],'事件点击' =>函数(calEvent,jsEvent,视图){$(this).css('border-color', 'red');$.get('index.php?r=event/update',{'id':calEvent.id}, function(data){$('.modal').modal('show').find('#modelContent').html(数据);})$('#calendar').fullCalendar('removeEvents', function (calEvent) {返回真;});}",/*$('#event').fullCalendar({事件渲染:函数(事件,元素){if(event.status == "请假") {element.css('背景色', '#131313');} else if (event.status == "stand by") {element.css('背景色', '#678768');} else if (event.status == "active") {element.css('背景色', '#554455');}},});*/));?>

I'm using Philipp Frenzel FullCalendar in Yii2 framework and its working perfectly. I want to implement basic filter events on calendar base on option select but my codes still not working. Help would be highly appreciated.

This is inside EventController :

<?php

namespace appcontrollers;

use Yii;
use appmodelsEvent;
use appmodelsEventSearch;
use yiiwebController;
use yiiwebNotFoundHttpException;
use yiifiltersVerbFilter;

/**
 * EventController implements the CRUD actions for Event model.
 */
class EventController extends Controller
{
    /**
     * {@inheritdoc}
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Lists all Event models.
     * @return mixed
     */
    public function actionIndex()
    {
        /*$searchModel = new EventSearch();
        $dataProvider = $searchModel->search(Yii::$app->request->queryParams);*/

        $events = Event::find()->all();
        $tasks = [];

        foreach ($events as $eve)
        {
              $event = new yii2fullcalendarmodelsEvent();
              $event->id = $eve->id;
              $event->backgroundColor = 'green';
              $event->title = $eve->title;
              $event->start = $eve->created_date;
              $tasks[] = $event;
        }

        return $this->render('index', [
            //'searchModel' => $searchModel,
            'events' => $tasks,
        ]);
    }

    /**
     * Displays a single Event model.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionView($id)
    {
        return $this->render('view', [
            'model' => $this->findModel($id),
        ]);
    }

    /**
     * Creates a new Event model.
     * If creation is successful, the browser will be redirected to the 'view' page.
     * @return mixed
     */
    public function actionCreate($date)
    {
        $model = new Event();
        $model->created_date = $date;

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['index']);
        }else{
            return $this->renderAjax('create', [
            'model' => $model,
            ]);
        }
    }

    /**
     * Updates an existing Event model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else { 
            return $this->renderAjax('update', [
            'model' => $model,
        ]);
        }
    }

    /**
     * Deletes an existing Event model.
     * If deletion is successful, the browser will be redirected to the 'index' page.
     * @param integer $id
     * @return mixed
     * @throws NotFoundHttpException if the model cannot be found
     */
    public function actionDelete($id)
    {
        $this->findModel($id)->delete();

        return $this->redirect(['index']);
    }

    /**
     * Finds the Event model based on its primary key value.
     * If the model is not found, a 404 HTTP exception will be thrown.
     * @param integer $id
     * @return Event the loaded model
     * @throws NotFoundHttpException if the model cannot be found
     */
    protected function findModel($id)
    {
        if (($model = Event::findOne($id)) !== null) {
            return $model;
        }

        throw new NotFoundHttpException('The requested page does not exist.');
    }


    /**
 * 
 * @param type $choice
 * @return type
 */
    public function actionFilterEvents($choice = null) {
        Yii::$app->reponse->format = yiiwebResponse::FORMAT_JSON;
        $query = modelsEvent::find();

        if( is_null($choice) || $choice=='all'){
            //the function should return the same events that you were loading before
            $dbEvents = $query->all();
            $events = $this->loadEvents($dbEvents);
        } else{
            //here you need to look up into the data base 
            //for the relevant events against your choice
            $dbEvents = $query->where(['=', 'column_name', ':choice'])
                    ->params([':choice' => $choice])
                    ->asArray()
                    ->all();
            $events = $this->loadEvents($dbEvents);
        }
        return $events;
    }

    /**
     * 
     * @param type $dbEvents
     * @return yii2fullcalendarmodelsEvent
     */
    private function loadEvents($dbEvents) {
        foreach( $dbEvents AS $event ){
            //Testing
            $Event = new yii2fullcalendarmodelsEvent();
            $Event->id = $event->id;
            $Event->title = $event->categoryAsString;
            $Event->description = $event->description;
            $Event->start = date('Y-m-dTH:i:s', strtotime($event->created_date . ' ' . $event->created_date));
            $Event->end = date('Y-m-dTH:i:s', strtotime($event->time_out . ' ' . $event->time_out));
            $Event->status = $event->status;
            $Event->remarks = $event->remarks;
            $events[] = $Event;
        }
        return $events;
    }
}

This is event-index :

<?php

use yiihelpersHtml;
use yiigridGridView;
use yiiootstrapModal;

$this->title = 'Roster Bul Hanine Project';
$this->params['breadcrumbs'][] = $this->title;

$js=<<< JS
var eventSource=['/event/filter-events'];
$("#select_name").on('change',function() {
    //get current status of our filters into eventSourceNew
    var eventSourceNew=['/event/filter-events?choice=' +  $(this).val()];
    //remove the old eventSources
    $('#event').fullCalendar('removeEventSource', eventSource[0]);
    //attach the new eventSources
    $('#event').fullCalendar('addEventSource', eventSourceNew[0]);
    $('#event').fullCalendar('refetchEvents');
    //copy to current source 
    eventSource = eventSourceNew;
});
JS;
    $this->registerJs($js, yiiwebView::POS_READY);

?>
<div class="event-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

    <p><?= Html::a('Create Roster', ['create'], ['class' => 'btn btn-success']) ?></p>
    <p>
        <select class="model_attribute" id="select_name">
            <option value="all">All Tech</option>
            <option value="0">Hendy Nugraha</option>
            <option value="1">Ginanjar Nurwin</option>
            <option value="2">Rio Andhika</option>
        </select>
    </p>
    <div id="event"></div>

    <?php 
        Modal::begin([
            'header'=>'<h4>Roster</h4>',
            'id' => 'model',
            'size' => 'model-lg',
        ]);
        echo "<div id='modelContent'></div>";
        Modal::end();
    ?>

    <?=yii2fullcalendaryii2fullcalendar::widget(array(
      'events'=> $events, 
      'id' => 'event',
      'clientOptions' => [ 
        'editable' => true,
        'eventSources' => ['/event/filter-events'],
        'draggable' => true,
        'droppable' => true,
        ],
      'eventClick' => "function(calEvent, jsEvent, view) {

                $(this).css('border-color', 'red');

                $.get('index.php?r=event/update',{'id':calEvent.id}, function(data){
                    $('.modal').modal('show')
                    .find('#modelContent')
                    .html(data);
                })

                $('#calendar').fullCalendar('removeEvents', function (calEvent) {
                    return true;
                });

           }",

           /*$('#event').fullCalendar({
            eventRender: function(event, element) {
                if(event.status == "on leave") {
                    element.css('background-color', '#131313');
                } else if (event.status == "stand by") {
                    element.css('background-color', '#678768');
                } else if (event.status == "active") {
                    element.css('background-color', '#554455');
                }
            },
        });*/
    ));

    ?>
</div>

below is screen shot result when i comment 'events'=> $events, inside index.php, (as per your instruction). even I choose via select option, it's not filtering the event

if I un-comment 'events'=> $events, it's showing all events, but when i choose via select option, it's not filtering event. below the screen shot:

解决方案

The extension you are using includes the latest version FullCalendar v3.9.0. So refer to the latest API version 3 for all the documentation references below.

Approach

To me, if I have to implement it I won't be using the events option as we need to filter events on runtime base on the option selected from the drop-down a better option would be to use eventSources option. It provides a way to specify multiple event sources. This option is used instead of the events option.You can put any number of event arrays, functions, JSON feed URLs, or full-out Event Source Objects into the eventSources array.

A simple example javascript based

$('#calendar').fullCalendar({
  eventSources: [
    '/feed1.php',
    '/feed2.php'
  ]
});

If you look into the documentation for Fullcalendar they have events related section with the name Event Data where you can see various options along with the one mentioned.

Start From

We will start by providing eventSources a URL for our JSON feed for the calendar events, and remove the option events. I will use a single source you can have multiple too if you like but i will keep it short and simple.

Change the code for the Widget and add the eventSources option under the clientOptions option for the widget.

<?=
yii2fullcalendaryii2fullcalendar::widget(array(
    'id' => 'eventFilterCalendar',
    'clientOptions' => [
        'editable' => true,
        'eventSources' => ['/schedule/filter-events'],
        'draggable' => true,
        'droppable' => true,
    ],
    'eventClick' => "function(calEvent, jsEvent, view) {
        $(this).css('border-color', 'red');
        $.get('index.php?r=event/update',{'id':calEvent.id}, function(data){
            $('.modal').modal('show')
            .find('#modelContent')
            .html(data);
        });

        $('#calendar').fullCalendar('removeEvents', function (calEvent) {
            return true;
        });

    }",
));
?>

At this point if you will refresh the calendar you will not see any events that you were loading before because previously you were using the 'events'=>$events to load the events but now we have provided a url source '/schedule/filter-events' (change it to the relevant controller/action you want to use I will use the same URL for the example).

Second Part

So the $events that you were loading before, will now have to load via the new action we are going to create. If you are following the example provided on the GitHub page for the extension and loading your events from the database model and then looping over with a for loop to load all of the events to the yii2fullcalendarmodelsEvents() model and then load that array.

As you have not provided any detail regarding the model you are using for the database to store and load events to the calendar, I assume that your model name is MyEvents change it accordingly and the field column_name in the query.

/**
 * 
 * @param type $choice
 * @return type
 */
public function actionFilterEvents($choice = null) {
    Yii::$app->response->format = yiiwebResponse::FORMAT_JSON;
    $query = MyEvents::find();

    if( is_null($choice) || $choice=='all'){
        //the function should return the same events that you were loading before
        $dbEvents = $query->all();

    } else{
        //here you need to look up into the data base 
        //for the relevant events against your choice
        $dbEvents = $query->where(['=', 'column_name', ':choice'])
                ->params([':choice' => $choice])
                ->asArray()
                ->all();
    }

    return $this->loadEvents($dbEvents);
}

/**
 * 
 * @param type $dbEvents
 * @return yii2fullcalendarmodelsEvent
 */
private function loadEvents($dbEvents) {
    foreach( $dbEvents AS $event ){
        //Testing
        $Event = new yii2fullcalendarmodelsEvent();
        $Event->id = $event->id;
        $Event->title = $event->categoryAsString;
        $Event->start = date('Y-m-dTH:i:s', strtotime($event->date_start . ' ' . $event->time_start));
        $Event->end = date('Y-m-dTH:i:s', strtotime($event->date_end . ' ' . $event->time_end));
        $events[] = $Event;
    }
    return $events;
}

Things to notice above

  • $choice parameter in actionFilterEvents with null as the default value for listing all the events when the calendar loads for the first time.
  • The loadEvents() method to load the searched events from the database to yii2fullcalendarmodelEvents, do change the field names used in the foreach with the relevant model field names that you will use instead of MyEvents.

At this point, if you have done everything correctly as mentioned if you refresh your page you will see the default events loading in the calendar.

Actual part

Now comes the part of filtering the events depending on the choice of the drop-down. For server-side we have already done the work above, the else part will handle filtering all the events from the database by comparing the selected choice with the desired column column_name (replace it with the field name you want to compare with). The part still to be done is the client-side now, we will bind the onchange event of the dropdown and then use mainly these 3 methods provided by fullcalendar

  • removeEventSource,Dynamically removes an event source.Events from the source will be immediately removed from the calendar.
  • addEventSource,Dynamically adds an event source.The source may be an Array/URL/Function just as in the events option. Events will be immediately fetched from this source and placed on the calendar.
  • refetchEvents, Refetches events from all sources and rerenders them on the screen.

Every time we select a choice the previous eventSource is removed and a new eventSource is added so basically will building the url schedule/filter-events?choice=all if All Tech is selected, schedule/filter-events?choice=0 if Hendy Nugraha is selected and so on.

Add the below javascript on top of your view where you have initialized your widget.

Make sure the selector used below #select_name is matched with your drop-down's actual id.

$js = <<< JS

        var eventSource=['/schedule/filter-events'];

        $("#select_name").on('change',function() {

        //get current status of our filters into eventSourceNew
        var eventSourceNew=['/schedule/filter-events?choice=' +  $(this).val()];

        //remove the old eventSources
        $('#eventFilterCalendar').fullCalendar('removeEventSource', eventSource[0]);
        //attach the new eventSources
        $('#eventFilterCalendar').fullCalendar('addEventSource', eventSourceNew[0]);
        $('#eventFilterCalendar').fullCalendar('refetchEvents');

        //copy to current source 
        eventSource = eventSourceNew;
    });
JS;

$this->registerJs($js, yiiwebView::POS_READY);

Do everything as told above and it will start working and will show you filtered results as soon as you change options in the drop-down.

Note: I have provided the solution above from a running project, with Yii2.0.15.1 and the latest available extension.

EDIT

I am amazed that you can't differentiate between server-side, HTML and javascript, the code I provided related to javascript that you needed to paste in the view event-index was inside the heredoc and you had to just copy paste it but somehow you ended up wrapping the javascript inside the <script> tag and removed the heredoc? and moreover you are calling the $this->registerJs() inside the script tag rather than the <?php ?> tags ? ¯\_(ツ)_/¯.

And you didn't even changed the controller name in the URL for the var eventSource=['/schedule/filter-events']; javascript code your controller is Event and not schedule, i wrote at every point where i assumed a model or controller name to change it accordingly, even your widget code is not updated accordingly it also has the 'eventSources' => ['/schedule/filter-events'], when it should be 'eventSources' => ['/event/filter-events'],.

So this time just copy paste the whole view code below and DO NOT CHANGE anything. I won't be spoon feeding you anymore just because you have to mark it correct, although it is the correct answer and should Have been awarded the Bounty.

Troubleshooting and fixing syntax errors are your duties to fix along when you are integrating the code. The solution provided is working and you failing to integrate it does not mean it isnt the correct answer.

'event-index.php`

<?php

use yiihelpersHtml;
use yiigridGridView;
use yiiootstrapModal;

$this->title = 'Roster Bul Hanine Project';
$this->params['breadcrumbs'][] = $this->title;

$js=<<< JS
var eventSource=['/event/filter-events'];
$("#select_name").on('change',function() {
    //get current status of our filters into eventSourceNew
    var eventSourceNew=['/event/filter-events?choice=' +  $(this).val()];
    //remove the old eventSources
    $('#event').fullCalendar('removeEventSource', eventSource[0]);
    //attach the new eventSources
    $('#event').fullCalendar('addEventSource', eventSourceNew[0]);
    $('#event').fullCalendar('refetchEvents');
    //copy to current source 
    eventSource = eventSourceNew;
});
JS;
    $this->registerJs($js, yiiwebView::POS_READY);

?>
<div class="event-index">

    <h1><?= Html::encode($this->title) ?></h1>
    <?php // echo $this->render('_search', ['model' => $searchModel]); ?>

    <p><?= Html::a('Create Roster', ['create'], ['class' => 'btn btn-success']) ?></p>
    <p>
        <select class="model_attribute" id="select_name">
            <option value="all">All Tech</option>
            <option value="0">Hendy Nugraha</option>
            <option value="1">Ginanjar Nurwin</option>
            <option value="2">Rio Andhika</option>
        </select>
    </p>
    <div id="event"></div>



    <?php 
        Modal::begin([
            'header'=>'<h4>Roster</h4>',
            'id' => 'model',
            'size' => 'model-lg',
        ]);
        echo "<div id='modelContent'></div>";
        Modal::end();

    ?>

    <?=yii2fullcalendaryii2fullcalendar::widget(array(
      //'events'=> $events, 
      'id' => 'event',
      'clientOptions' => [ 
        'editable' => true,
        'eventSources' => ['/event/filter-events'],
        'draggable' => true,
        'droppable' => true,
        ],
      'eventClick' => "function(calEvent, jsEvent, view) {

                $(this).css('border-color', 'red');

                $.get('index.php?r=event/update',{'id':calEvent.id}, function(data){
                    $('.modal').modal('show')
                    .find('#modelContent')
                    .html(data);
                })

                $('#calendar').fullCalendar('removeEvents', function (calEvent) {
                    return true;
                });

           }",

           /*$('#event').fullCalendar({
            eventRender: function(event, element) {
                if(event.status == "on leave") {
                    element.css('background-color', '#131313');
                } else if (event.status == "stand by") {
                    element.css('background-color', '#678768');
                } else if (event.status == "active") {
                    element.css('background-color', '#554455');
                }
            },
        });*/
    ));

    ?>
</div>

相关文章