0

when i click in a empty slot and open a bootstrap modal i need he fill a form input fields with dates from calendar, to create a new record and this is working fine with event select in shown.bs.modal.

but when i click in event with eventClick i need only load a form that i already have in update url. But the problem is in eventClick the code inside shown.bs.modal is also fired and fields are replaced.

modal (yii2 framework)

<?php
Modal::begin([
    'header' => '<b> NEW </b>',
    'id' => 'modal',
    'size' => 'modal-lg',
]);
echo "<div id='modalContent'></div>";
Modal::end();
?>

fullcalendar.js (3.10.0)

$('#calendar').fullCalendar({
    defaultView: 'agendaDay',
    locale: 'en-gb',
    contentHeight: 'auto',
    expandRows: true,
    height: '100%',
    header: {
        left: 'prev,next',
        center: 'title',
        right: 'timelineDay,agendaDay'
    },
    groupByResource: true,
    views: {
        timelineDay: {
        slotLabelFormat: ['HH:mm'],
        },
    },
    weekends: false,
    slotLabelFormat : "HH:mm",
    minTime: "08:00:00",
    maxTime: "17:00:00",
    slotLabelInterval: "01:00:00",
    slotDuration: '00:30:00',
    slotWidth: "50",
    slotEventOverlap: false,
    selectable: true,
    defaultDate: day,
    selectOverlap: false,
    displayEventTime: false,
    select: function(start, end, jsEvent, view, resource) {
        $('#modal')
        .on('shown.bs.modal', function (e) {
           $('#salas-date_begin').val(moment(start).format('YYYY-MM-DD HH:mm'));
           $('#salas-date_end').val(moment(end).format('YYYY-MM-DD HH:mm'));
           console.log('here!');
        }).modal('show').find('#modalContent').load('http://url/create');
    },
    eventClick: function(event, jsEvent, view) {
        $('#modal')
        .modal('show').find('#modalContent').load('http://url/update?id=' + event.id);
    },
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
    resourceLabelText: 'Rooms',
    events: events
});

update all of the view

<?php

use kartik\export\ExportMenu;
use yii\bootstrap\Modal;
use yii\helpers\Html;
use yii\grid\GridView;
use yii\helpers\Json;
use yii\web\View;
use yii\widgets\Pjax;
/* @var $this yii\web\View */
/* @var $searchModel common\models\SalasSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = Yii::t('app', 'Salas');
$this->params['breadcrumbs'][] = $this->title;

$this->registerJsFile('https://fullcalendar.io/releases/fullcalendar/3.10.0/lib/moment.min.js', ['depends' => [\yii\web\JqueryAsset::className()]]);
$this->registerJsFile('https://fullcalendar.io/releases/fullcalendar/3.10.0/fullcalendar.min.js', ['depends' => [\yii\web\JqueryAsset::className()]]);
$this->registerJsFile('https://fullcalendar.io/releases/fullcalendar-scheduler/1.9.4/scheduler.min.js', ['depends' => [\yii\web\JqueryAsset::className()]]);

$script2 = <<< JS

$(document).ready(function() {
    $('#modal').on('hide.bs.modal', function (e) {
    console.log($(e.currentTarget).off('shown.bs.modal')); // or $(this)

    });
});
JS;
$this->registerJs($script2);

Modal::begin([
    'header' => '<b> NEW </b>',
    'id' => 'modal',
    'size' => 'modal-lg',
]);
echo "<div id='modalContent'></div>";
Modal::end();

?>


<div class="salas-index">
    <div class="row">
        <div class="col-xs-12">
            <div class="box">
                <div class="box-body">

                        <link rel="stylesheet" href="https://fullcalendar.io/releases/fullcalendar/3.10.0/fullcalendar.min.css">
                        <link rel="stylesheet" href="https://fullcalendar.io/releases/fullcalendar-scheduler/1.9.4/scheduler.min.css">

                        <div id='calendar-container'>
                            <div id="calendar" class="fc fc-ltr fc-unthemed"></div>
                        </div>

                </div>
            </div>
        </div>
    </div>
</div>

<?php

$script = <<< JS
    
  $('#calendar').fullCalendar({
    defaultView: 'agendaDay',
    locale: 'en-gb',
    contentHeight: 'auto',
    expandRows: true,
    height: '100%',
    header: {
        left: 'prev,next',
        center: 'title',
        right: 'timelineDay,agendaDay'
    },
    groupByResource: true,
    views: {
        timelineDay: {
        slotLabelFormat: ['HH:mm'],
        },
    },
    weekends: false,
    slotLabelFormat : "HH:mm",
    minTime: "08:00:00",
    maxTime: "17:00:00",
    slotLabelInterval: "01:00:00",
    slotDuration: '00:30:00',
    slotWidth: "50",
    slotEventOverlap: false,
    selectable: true,
    defaultDate: day,
    selectOverlap: false,
    displayEventTime: false,
    select: function(start, end, jsEvent, view, resource) {
        $('#modal')
        .on('shown.bs.modal', function (e) {
           $('#salas-date_begin').val(moment(start).format('YYYY-MM-DD HH:mm'));
           $('#salas-date_end').val(moment(end).format('YYYY-MM-DD HH:mm'));
           console.log('here!');
        }).modal('show').find('#modalContent').load('http://url/create');
    },
    eventClick: function(event, jsEvent, view) {
        $('#modal')
        .modal('show').find('#modalContent').load('http://url/update?id=' + event.id);
    },
    schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
    resourceLabelText: 'Rooms',
    events: events
});

JS;
$this->registerJs($script);


?>
Moutinho
  • 321
  • 3
  • 14
  • so when you run it without `console.log()` and try to click on edit does the `console.log('here!');` inside the `shown.bs.modal` still print inside the console? – Reborn Feb 27 '21 at 00:18
  • @MuhammadOmerAslam now is correct i make a bit confused my files, i mark your answer correct, thanks for patience and for the correct answer as always :) – Moutinho Feb 27 '21 at 00:52

1 Answers1

2

That is because once you click the date in the calendar the event shown.bs.modal is bind to fill in the inputs with the start and end dates.I would have avoided doing it the first time. Why? because every time you select the date you bind the same event again without removing the previous one which will effect the performance and will have weird behavior too.

Instead I would use $.get inside the select to load the form/view via controller/action and get all the inputs filled with preloaded values and just push the html inside the modal.

In your case currently what you can do is that you can un-bind the event shown.bs.modal once the modal window is closed after creating the event, as it will bind again when you click on the date and the select event of full calendar fires.

You should register it on the top of your view within the document.ready

/* First option */
$('#modal').on('hide.bs.modal', function (e) {
    $(e.currentTarget).off('shown.bs.modal'); // or $(this)
});

Note: i am using .off() as of jQuery 3 the .unbind() is deprecated in the favor of .off()

Above all you should use the yii's available extension and integrate the full calendar https://www.yiiframework.com/extension/yii2fullcalendar and use event sources to load the events from the database. I have added an answer in past on the integration of the full calendar with the events modal from the database and filtering them here if you like to see.

Reborn
  • 19,713
  • 8
  • 36
  • 61
  • nice explaination, bute `$(e.currentTarget).off('shown.bs.modal'); // or $(this)` don´t work, the result is same :( – Moutinho Feb 26 '21 at 23:36
  • 1
    @Moutinho i dont know why it wont work without knowing how you are running it , verify if the event is invoked when you close the modal window , you can use `console.log()` to check – Reborn Feb 26 '21 at 23:54
  • i add this code $script2 = <<< JS `$(document).ready(function() { $('#modal').on('hide.bs.modal', function (e) { console.log($(e.currentTarget).off('shown.bs.modal')); // or $(this) }); }); JS; $this->registerJs($script2);` and when close the modal the output the console is `Object { 0: div#modal.fade.modal.in, length: 1 }` – Moutinho Feb 26 '21 at 23:57
  • 1
    where ? how would i know with seeing , copy the whole view file in your question – Reborn Feb 27 '21 at 00:00
  • i update all of the view in initial post – Moutinho Feb 27 '21 at 00:11