Yii2完整日历事件过滤不起作用

时间:2018-08-29 11:27:49

标签: php jquery yii2 fullcalendar yii2-basic-app

我在Yii2框架中使用Philipp Frenzel FullCalendar,并且它运行良好。我想基于选项select在日历上实现基本的过滤器事件,但是我的代码仍然无法正常工作。帮助将不胜感激。

这是在EventController内部:

<?php

namespace app\controllers;

use Yii;
use app\models\Event;
use app\models\EventSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;

/**
 * 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 \yii2fullcalendar\models\Event();
              $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 = \yii\web\Response::FORMAT_JSON;
        $query = models\Event::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 \yii2fullcalendar\models\Event
     */
    private function loadEvents($dbEvents) {
        foreach( $dbEvents AS $event ){
            //Testing
            $Event = new \yii2fullcalendar\models\Event();
            $Event->id = $event->id;
            $Event->title = $event->categoryAsString;
            $Event->description = $event->description;
            $Event->start = date('Y-m-d\TH:i:s\Z', strtotime($event->created_date . ' ' . $event->created_date));
            $Event->end = date('Y-m-d\TH:i:s\Z', strtotime($event->time_out . ' ' . $event->time_out));
            $Event->status = $event->status;
            $Event->remarks = $event->remarks;
            $events[] = $Event;
        }
        return $events;
    }
}

这是事件索引:

<?php

use yii\helpers\Html;
use yii\grid\GridView;
use yii\bootstrap\Modal;

$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, \yii\web\View::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();
    ?>

    <?=\yii2fullcalendar\yii2fullcalendar::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>
下面的

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

enter image description here

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

enter image description here

1 个答案:

答案 0 :(得分:4)

您使用的扩展名包括最新版本FullCalendar v3.9.0。因此,请参考以下最新的API版本3。

方法

对我来说,如果我必须实现它,我将不会使用events选项,因为我们需要基于从下拉列表中选择的选项来过滤运行时事件,因此最好使用eventSources选项。它提供了一种指定多个事件源的方法。使用此选项代替events选项。您可以将任意数量的event arraysfunctionsJSON feed URLs或完整Event Source Objects放入{ {1}}数组。

基于javascript的简单示例

eventSources

如果您查看Fullcalendar的文档,它们的事件相关部分的名称为Event Data,您可以在其中看到各种选项以及提到的选项。

开始于

我们将首先为日历事件的JSON feed提供$('#calendar').fullCalendar({ eventSources: [ '/feed1.php', '/feed2.php' ] }); URL,然后删除选项eventSources。我将使用一个来源,如果您愿意,也可以有多个来源,但我会尽量简短。

更改窗口小部件的代码,并在窗口小部件的events选项下添加eventSources选项。

clientOptions

在这一点上,如果您刷新日历,将不会看到之前正在加载的任何事件,因为以前您是使用<?= \yii2fullcalendar\yii2fullcalendar::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; }); }", )); ?> 加载事件的,但是现在我们提供了网址来源{{1} }(将其更改为您要使用的相关'events'=>$events,我将在示例中使用相同的URL )。

第二部分

因此,您之前加载的'/schedule/filter-events'现在必须通过我们将要创建的新操作来加载。如果您遵循GitHub页面上提供的扩展示例,并从数据库模型加载事件,然后使用for循环进行循环,以将所有事件加载到controller/action模型中,然后加载该数组。

由于您没有提供有关数据库用于存储事件并将事件加载到日历的模型的任何详细信息,因此我假设您的模型名称为$events,并相应地对其进行了更改,而字段{ {1}}。

\yii2fullcalendar\models\Events()

上述注意事项

    MyEvents中的
  • column_name参数,其中/** * * @param type $choice * @return type */ public function actionFilterEvents($choice = null) { Yii::$app->response->format = \yii\web\Response::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 \yii2fullcalendar\models\Event */ private function loadEvents($dbEvents) { foreach( $dbEvents AS $event ){ //Testing $Event = new \yii2fullcalendar\models\Event(); $Event->id = $event->id; $Event->title = $event->categoryAsString; $Event->start = date('Y-m-d\TH:i:s\Z', strtotime($event->date_start . ' ' . $event->time_start)); $Event->end = date('Y-m-d\TH:i:s\Z', strtotime($event->date_end . ' ' . $event->time_end)); $events[] = $Event; } return $events; } 为默认值,用于在首次加载日历时列出所有事件。
  • 使用$choice方法将搜索到的事件从数据库加载到actionFilterEvents用相关模型字段名称更改null中使用的字段名称使用而不是loadEvents()

在这一点上,如果刷新页面时如前所述正确完成了所有操作,则日历中会加载默认事件。

实际部分

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

  • removeEventSource,动态删除事件源。源中的事件将立即从日历中删除。
  • addEventSource,动态添加事件源。该源可以是Array / URL / Function,就像在events选项中一样。活动将立即从此来源获取并放置在日历上。
  • refetchEvents,从所有来源重新获取事件,并将其重新呈现在屏幕上。

每次选择一个选项时,都会删除先前的column_name并添加一个新的onchange,因此,如果选择了methods,{{ 1}}(如果选择了eventSource,依此类推。

在已初始化小部件的视图上方添加以下javascript。

请确保eventSource下使用的选择器与下拉列表的实际schedule/filter-events?choice=all相匹配。

All Tech

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

注意:我已经从一个正在运行的项目中提供了上述解决方案,其中包含schedule/filter-events?choice=0和最新的可用扩展名。

编辑

我很惊讶您无法区分服务器端,HTML和javascript,我提供的与JavaScript相关的代码需要粘贴到视图Hendy Nugraha中,并且该代码位于heredoc内,并且您只需要复制粘贴即可,但是以某种方式最终将javascript包装在#select_name标记内并删除了id?而且,您是在script标记内调用$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, \yii\web\View::POS_READY); 而不是Yii2.0.15.1标记? ¯\ _(ツ)_ /¯

您甚至没有更改event-index javascript代码的URL中的控制器名称,您的控制器是<script>而不是heredoc,我在每一个假定型号或控制器名称以进行相应更改,即使您的窗口小部件代码未进行相应的更新,它也应具有$this->registerJs()的位置<?php ?>

因此,这一次只需复制以下粘贴整个视图代码,然后请勿更改。我不会再为您喂食,只是因为您必须将其标记为正确,尽管这是正确的答案,应该被授予赏金。

对错误进行故障排除和修复是集成代码时要解决的任务。提供的解决方案有效,并且您无法集成它并不意味着它不是正确的答案。

'event-index.php`

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