我在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时的屏幕截图结果(根据您的说明)。即使我通过选择选项进行选择,也不会过滤事件
如果我取消注释'events'=> $ events,它将显示所有事件,但是当我通过select选项进行选择时,它不会过滤事件。屏幕截图下方:
最佳答案
您使用的扩展名包括最新版本的FullCalendar v3.9.0
。因此,请参阅下面的所有文档引用的最新API版本3。
方法
对我来说,如果我必须实现它,那么我就不会使用events
选项,因为我们需要基于下拉菜单中选择的选项来过滤运行时事件,一个更好的选择是使用eventSources
选项。它提供了一种指定多个事件源的方法。使用此选项代替events
选项。您可以将任意数量的event arrays,functions,JSON feed URLs或完整的Event Source Objects放入eventSources
数组中。
一个简单的基于javascript的示例
$('#calendar').fullCalendar({
eventSources: [
'/feed1.php',
'/feed2.php'
]
});
如果您查看Fullcalendar的文档,则它们具有与事件相关的部分,名称为
Event Data
,您可以在其中看到各种选项以及提到的选项。从...开始
首先,我们为JSON事件的JSON供稿提供
eventSources
URL,然后删除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;
});
}",
));
?>
此时,如果您刷新日历,将不会看到之前正在加载的任何事件,因为以前您是使用
'events'=>$events
加载事件的,但现在我们提供了url源'/schedule/filter-events'
(将其更改为所需的相关controller/action
使用时,我将对示例使用相同的URL)。第二部分
因此,您之前要加载的
$events
现在必须通过我们将要创建的新操作来加载。如果您遵循GitHub页面上提供的扩展示例,并从数据库模型加载事件,然后使用for循环进行循环,以将所有事件加载到\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
。 此时,如果刷新页面时如前所述正确地完成了所有操作,则日历中将显示默认事件。
实际部分
现在是根据下拉菜单选择过滤事件的部分。对于服务器端,我们已经完成了上面的工作,
else
部分将通过将所选选项与所需的列column_name
比较(将其替换为要与进行比较的字段名称),来处理从数据库中过滤所有事件的操作。现在尚需做的部分是客户端,我们将绑定(bind)下拉列表的
onchange
事件,然后主要使用fullcalendar提供的这3个methods
removeEventSource
,动态删除事件源。源中的事件将立即从日历中删除。 addEventSource
,动态添加事件源。该源可以是Array/URL/Function,与events选项相同。 Activity 将立即从该来源获取并放置在日历上。 refetchEvents
,从所有来源重新获取事件并将其重新呈现在屏幕上。 每次我们选择一个选项时,都会删除以前的
eventSource
并添加一个新的eventSource
,因此,如果选择了schedule/filter-events?choice=all
,则基本上将构建url All Tech
;如果选择了schedule/filter-events?choice=0
,则将构建Hendy Nugraha
,依此类推。在您已初始化小部件的 View 上方添加以下javascript。
确保
#select_name
下面使用的选择器与下拉列表的实际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, \yii\web\View::POS_READY);
按照上述说明进行所有操作,它将立即开始工作,并且在下拉菜单中更改选项后将立即显示经过过滤的结果。
注意:我已经从一个正在运行的项目中提供了上述解决方案,其中包含
Yii2.0.15.1
和最新的可用扩展名。 编辑
我很惊讶您无法区分服务器端,HTML和javascript,我提供的与javascript相关的代码需要粘贴到
event-index
View 中,该代码位于 heredoc
内部,您只需要复制粘贴即可,但是以某种方式结束了将javascript包裹在<script>
标记内,并删除了heredoc
吗?而且,您是在script标签而不是$this->registerJs()
标签内调用<?php ?>
? ¯\_(ツ)_/¯。而且,您甚至都没有更改
var eventSource=['/schedule/filter-events'];
javascript代码的URL中的 Controller 名称,您的 Controller 是Event
而不是schedule
,我在每一个要写模型或 Controller 名称的地方都进行了相应的更改,即使您的小部件代码不是进行相应更新后,当应为'eventSources' => ['/schedule/filter-events'],
时,它也具有'eventSources' => ['/event/filter-events'],
。因此,这一次只需将整个 View 代码复制粘贴到下面,然后请勿更改任何内容。我不会再为您喂食,只是因为您必须将其标记为正确,尽管这是正确的答案,并且应该被授予赏金。
故障排除和修复语法错误是集成代码时要解决的责任。提供的解决方案正在运行,并且您未能集成该解决方案并不意味着它不是正确的答案。
'event-index.php`
<?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>
关于php - Yii2完整日历事件过滤不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52076369/