Используемое расширение включает в себя последнюю версию FullCalendar v3.9.0
. Так что обратитесь к последней версии API 3 для всех ссылок на документацию ниже.
подход
Для меня, если мне придется реализовать его, я не буду использовать опцию events
, поскольку нам нужно фильтровать события на основе времени выполнения по опции, выбранной из раскрывающегося списка, лучшим вариантом будет использование * 1007. * вариант. Он позволяет указать несколько источников событий. Эта опция используется вместо опции events
. Вы можете поместить любое количество массивов событий , функций , URL-адреса фида JSON или полного Объекты-источники событий в массив eventSources
.
Простой пример на основе JavaScript
$('#calendar').fullCalendar({
eventSources: [
'/feed1.php',
'/feed2.php'
]
});
Если вы загляните в документацию для Fullcalendar, у них есть раздел, связанный с событиями, с именем Event Data
, где вы можете увидеть различные варианты наряду с упомянутым.
Начать с
Мы начнем с предоставления eventSources
URL-адреса нашей ленты JSON для событий календаря и удалим опцию 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
( замените его на нужное имя поля сравнить с ).
Часть, которую еще предстоит сделать, теперь на стороне клиента, мы свяжем событие onchange
раскрывающегося списка, а затем будем использовать в основном эти 3 methods
, предоставленные fullcalendar
removeEventSource
, Динамически удаляет источник события. События из источника будут немедленно удалены из календаря.
addEventSource
, динамически добавляет источник события. Источником может быть массив / URL / функция, как в опции событий. События будут немедленно получены из этого источника и помещены в календарь.
refetchEvents
, извлекает события из всех источников и отображает их на экране.
Каждый раз, когда мы выбираем выбор, предыдущий eventSource
удаляется и добавляется новый eventSource
, поэтому в основном будет строиться URL schedule/filter-events?choice=all
, если выбран All Tech
, schedule/filter-events?choice=0
, если выбран Hendy Nugraha
, и скоро.
Добавьте приведенный ниже 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
и последним доступным расширением.
EDIT
Я поражен тем, что вы не можете различить серверную часть, HTML и javascript, предоставленный мною код, связанный с javascript, который вам нужно было вставить в представление event-index
, был внутри heredoc
и вам нужно было просто скопировать и вставить его, но каким-то образом вы завернули завершение javascript в тег <script>
и удалили heredoc
? и, кроме того, вы вызываете $this->registerJs()
внутри тега script, а не <?php ?>
? ¯ \ _ (ツ) _ / ¯ .
И вы даже не изменили имя контроллера в URL-адресе для var eventSource=['/schedule/filter-events'];
javascript-кода вашего контроллера Event
, а не schedule
, я писал в каждой точке, где я предполагал изменить модель или имя контроллера соответственно, даже ваш код виджета не обновляется, соответственно он также имеет 'eventSources' => ['/schedule/filter-events'],
, когда он должен быть 'eventSources' => ['/event/filter-events'],
.
Так что на этот раз просто скопируйте и вставьте весь код вида ниже и НЕ ИЗМЕНЯЙТЕ ничего. Я больше не буду кормить тебя ложкой только потому, что ты должен пометить это правильно, хотя это правильный ответ и должен был получить награду.
Устранение неполадок и исправление синтаксических ошибок - это ваши обязанности, которые необходимо исправить при интеграции кода. Предоставленное решение работает, и вы не можете его интегрировать, это не значит, что он не является правильным ответом.
'событийно-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>