Edofre / yii2-fullcalendar

Yii 2 component for easy fullcalendar integration
MIT License
27 stars 9 forks source link

drag n drop #13

Closed djnordeen closed 7 years ago

djnordeen commented 7 years ago

Hello, I cannot seem to make the calendar editable? Hope you can help me. I am loading the events from a database. Controller: public function actionAllEventsedofre() { $events = Events::find()->all(); $tasks = []; $draggable = "fc-draggable fc-resizable"; foreach ($events as $eve) { $event = new \yii2fullcalendar\models\Event(); $house = House::getHouseAddress($eve->house_id); $event->id = $eve->event_id; $event->start = $eve->start; $event->end = $eve->end; $event->title = $eve->title; $event->description = $house; $event->className = $draggable; $event->editable = true; $event->backgroundColor = $eve->background_color; $tasks[] = $event; } return $this->render('all-eventsedofre', [ 'events' => $tasks, ]); }

View: edofre\fullcalendar\Fullcalendar::widget([ 'events => $events, 'options' => [ 'id' => 'calendar', 'language' => 'nl', ], 'clientOptions' => [ 'weekNumbers' => true, 'selectable' => true, 'selectHelper' => true, 'editable' => true, 'startEditable' => true, 'durationEditable' => true, 'droppable' => true, 'draggable' => true, 'defaultView' => 'agendaWeek', 'eventResize' => new JsExpression(" function(event, delta, revertFunc, jsEvent, ui, view) { console.log(event); } "), ]);

Thanks

Edofre commented 7 years ago

With some tweaks to the above code I can drag/drop/resize events without a problem. However in your code I see some things that might cause the problems you're having.

djnordeen commented 7 years ago

Thanks for the response. Could you tell me the tweaks you made? I followed an example you had and did not realize I loaded the events in json. I will check it out tomorrow. Thanks

djnordeen commented 7 years ago

I deleted the json and added the model. I edited my original post sending the model to the view. Extend original calendar model? How? Sorry, clueless. editable = 1 startEditable = 1 durationEditable = 1

However, now the calendar displays correctly but it is blank

Edofre commented 7 years ago

Are you sure the event dates are correct? And that the dates from the events are in the week you're currently looking at in the calendar?

Check to make sure that the start and/or end attributes are according to this format '2017-04-02T12:00:00'

djnordeen commented 7 years ago

Ok, So here is what I have done. Controller: Changed this line: $event = new \yii2fullcalendar\models\Event(); to $event = new \edofre\fullcalendar\models\Event();

In the View: Added this block before widget <?php foreach ($events as $event) { echo $event->id; echo $event->start; echo $event->end; echo $event->editable; echo $event->startEditable; echo $event->durationEditable; die(); } ?> This is the result:
12016-12-08 12:00:002016-12-08 13:30:00111 id 1 start 2016-12-08 12:00:00 end 2016-12-08 13:30:00 editable 1 startEditable 1 durationEditable 1

There are 2250 events in $events

Edofre commented 7 years ago

That date format should work, can you share your full controller and full view?

djnordeen commented 7 years ago

controller: `namespace backend\controllers;

use Yii; use backend\models\Events; use backend\models\Customers; use backend\models\Employees; use backend\models\House; use edofre\fullcalendar\models; use backend\models\DeleteEvents; use backend\models\search\EventsSearch; use common\models\PermissionHelpers; use yii\web\Controller; use yii\web\NotFoundHttpException; use yii\filters\VerbFilter; use kartik\widgets\DepDrop; use yii\helpers\Json;

/**
 * EventsController implements the CRUD actions for Events model.
 */
class EventsController extends Controller
{
/**
 * @inheritdoc
 */
public function behaviors()
{

return [

'access' => [
       'class' => \yii\filters\AccessControl::className(),
       'only' => ['index', 'all-events', 'all-eventsmod', 'employee_schedule', 'view','create', 'update', 'delete'],
       'rules' => [
           [
               'actions' => ['index', 'all-events', 'all-eventsmod', 'employee_schedule', 'create', 'view', 'update'],
               'allow' => true,
               'roles' => ['@'],
               'matchCallback' => function ($rule, $action) {
                return PermissionHelpers::requireMinimumRole('Admin') 
                && PermissionHelpers::requireStatus('Active');
               }
           ],
            [
               'actions' => [ 'delete'],
               'allow' => true,
               'roles' => ['@'],
               'matchCallback' => function ($rule, $action) {
                return PermissionHelpers::requireMinimumRole('SuperUser') 
                && PermissionHelpers::requireStatus('Active');
               }
           ],

       ],

   ],

  'verbs' => [
            'class' => VerbFilter::className(),
            'actions' => [
                'delete' => ['post'],
            ],
        ],
    ];
}

/**
 * Lists all events models.
 * @return mixed
 */
public function actionAllEventsedofre()
{
    $events = Events::find()->all();
    $tasks = [];
    $draggable = "fc-draggable fc-resizable";
    foreach ($events as $eve) {

        $event = new \edofre\fullcalendar\models\Event();

        $house = House::getHouseAddress($eve->house_id);

        $event->id = $eve->event_id;
        $event->start = $eve->start;
        $event->end = $eve->end;
        $event->title = $eve->title;
        //$event->description = $house;
        $event->className = $draggable;
        $event->editable = true;
        $event->startEditable = true;
        $event->durationEditable = true;
        $event->backgroundColor = $eve->background_color;
        $tasks[] = $event;
    }

        return $this->render('all-eventsedofre', [
        'events' => $tasks,
    ]);

}

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

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

/**
 * Displays a single Events model.
 * @param integer $id
 * @return mixed
 */
public function actionView($id)
{
    return $this->render('view', [
        'model' => $this->findModel($id),
    ]);
}

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

    if ($model->load(Yii::$app->request->post()) && $model->save()) {

        $yearEnd = "2018 01 01 00:00";

        $repeats = House::getRepeatEvent($model->house_id);
        $frequency = House::getFrequency($model->house_id);

        if ($repeats === 1) {

            while($model->start < $yearEnd){

            $address = House::getHouseAddress($model->house_id);

            $model->event_id = ($model->event_id + 1);  
                $startDate = $model->start;
                $endDate = $model->end;
                $model->start = date('Y-m-d H:i', strtotime($startDate. ' +'.$frequency.'  days'));
                $model->end = date('Y-m-d H:i', strtotime($endDate. ' +'.$frequency.' days'));
                $model->description = '';
                $model->isNewRecord = true;
                $model->save(false);
            }  
        }

        return $this->redirect(['view', 'id' => $model->event_id]);
    } 

    else {
       return $this->render('create', [
            'model' => $model,
        ]);

    }  

}

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

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

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

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

public function actionCancel()  
{
    $model= new DeleteEvents();
    if ($model->load(Yii::$app->request->post()))
    {
        $from = date("Y-m-d", strtotime($model->start_date));
        $to = date("Y-m-d", strtotime($model->end_date));
        $events = Events::find()->where(['between', 'start', $from, $to])
        ->andWhere(['house_id'=> $model->house_id])->all();
        echo "Start loop";

        $count = [];
        foreach ($events as $eve) {
            $count = $count + 1;
            $eve->delete();

        }echo $count.' '."rows deleted";
            echo "<br>";
        die();
        return $this->render('index', [ 
        'model' => $model,
        ]);
    } else {
        return $this->render('cancel', [
            'model' => $model,
        ]);
    }
}

public function actionDeleteAll()
{
    $model= new DeleteEvents();
    $model = find() -> where(['between', 'start', $events -> a, $salesReport -> toDate]);
}

public function actionSubcat() {
    $out = [];
    if (isset($_POST['depdrop_parents'])) {
        $parents = $_POST['depdrop_parents'];
        if ($parents != null) {
            $cat_id = $parents[0];
            $out = House::getOptionsbyHouse($cat_id);
            echo Json::encode(['output' => $out, 'selected' => '']);
            return;
        }
    }
    echo Json::encode(['output' => '', 'selected' => '']);
}    

/**
 * Finds the Events model based on its primary key value.
 * If the model is not found, a 404 HTTP exception will be thrown.
 * @param integer $id
 * @return Events the loaded model
 * @throws NotFoundHttpException if the model cannot be found
 */
protected function findModel($id)
{
    if (($model = Events::findOne($id)) !== null) {
        return $model;
    } else {
        throw new NotFoundHttpException('The requested page does not exist.');
    }
}
}`
djnordeen commented 7 years ago

view: `<?php

use yii\helpers\Html;
use yii\grid\GridView;
use yii\web\JsExpression;

/* @var $this yii\web\View */
/* @var $searchModel backend\models\search\EventsSearch */
/* @var $dataProvider yii\data\ActiveDataProvider */

$this->title = 'Employee Payroll';
$this->params['breadcrumbs'][] = $this->title;

?>
<div class="all-payroll">

<h1><?= Html::encode($this->title) ?></h1>

<p>
    <?= Html::a('Create Emolyee Payroll', ['create'], ['class' => 'btn btn-success']) ?>
    <?= Html::a('Edit Emolyee Payroll', ['index'], ['class' => 'btn btn-primary']) ?>

</p>

<?= edofre\fullcalendar\Fullcalendar::widget([
    'events' => $events,
    'options'       => [
        'id'       => 'calendar',
        'language' => 'en',
    ],
    'clientOptions' => [
        'weekNumbers' => true,
        'selectable'  => true,
        'selectHelper' => true,
        'editable' => true,
        'startEditable' => true,
        'durationEditable' => true,
        'droppable' => true,
        'draggable' => true,
        'defaultView' => 'agendaWeek',
        'eventResize' => new JsExpression("
            function(event, delta, revertFunc, jsEvent, ui, view) {
                console.log(event);
            }
        "),

    ],

]);
?>

</div>
`
Edofre commented 7 years ago

Ok, make sure that the dates from your Events::find()->all(); models are properly set. If I copy the code for your views and controller and change it so it uses other events than Events::find()->all() it works.

public function actionCalendarTest()
    {
        $events = [
            // minimum
            new Event([
                'id'    => uniqid(),
                'title' => 'Appointment #' . rand(1, 999),
                'start' => '2017-04-03 14:00:00',
            ]),
            // Everything editable
            new Event([
                'id'    => uniqid(),
                'title' => 'Appointment #' . rand(1, 999),
                'start' => '2017-04-03 14:30:00',
                'end'   => '2017-04-03 15:00:00',
            ]),
            // No overlap
            new Event([
                'id'    => uniqid(),
                'title' => 'Appointment #' . rand(1, 999),
                'start' => '2017-04-03 15:30:00',
                'end'   => '2017-04-03 19:30:00',
            ]),
            // Only duration editable
            new Event([
                'id'    => uniqid(),
                'title' => 'Appointment #' . rand(1, 999),
                'start' => '2017-04-04 11:00:00',
                'end'   => '2017-04-04 11:30:00',
            ]),
            // Only start editable
            new Event([
                'id'    => uniqid(),
                'title' => 'Appointment #' . rand(1, 999),
                'start' => '2017-04-05 14:00:00',
                'end'   => '2017-04-05 15:30:00',
            ]),
        ];

        $tasks = [];
        $draggable = "fc-draggable fc-resizable";
        foreach ($events as $eve) {
            $event = new \edofre\fullcalendar\models\Event();
            $event->id = $eve->id;
            $event->start = $eve->start;
            $event->end = $eve->end;
            $event->title = $eve->title;
            //$event->description = $house;
            $event->className = $draggable;
            $event->editable = true;
            $event->startEditable = true;
            $event->durationEditable = true;
            $event->backgroundColor = $eve->backgroundColor;
            $tasks[] = $event;
        }

        return $this->render('calendartest', [
            'events' => $tasks,
        ]);
    }
<?= edofre\fullcalendar\Fullcalendar::widget([
            'events'        => $events,
            'options'       => [
                'id'       => 'calendar',
                'language' => 'en',
            ],
            'clientOptions' => [
                'weekNumbers'      => true,
                'selectable'       => true,
                'selectHelper'     => true,
                'editable'         => true,
                'startEditable'    => true,
                'durationEditable' => true,
                'droppable'        => true,
                'draggable'        => true,
                'defaultView'      => 'agendaWeek',
                'eventResize'      => new JsExpression("
                    function(event, delta, revertFunc, jsEvent, ui, view) {
                        console.log(event);
                    }
                "),
            ],
        ]);
        ?>
djnordeen commented 7 years ago

If I run my controller and echo out the result of the foreach loop event. Isn't this in the right format? Do I have to run the foreach loop in the view? It would appear that I have the correct format for the $events model. foreach ($events as $eve) {

        $event = new \edofre\fullcalendar\models\Event();

        $house = House::getHouseAddress($eve->house_id);

        $event->id = $eve->event_id;
        $event->start = $eve->start;
        $event->end = $eve->end;
        $event->title = $eve->title;
        //$event->description = $house;
        //$event->className = $draggable;
        //$event->editable = true;
        //$event->startEditable = true;
        //$event->durationEditable = true;
        //$event->backgroundColor = $eve->background_color;
        $tasks[] = $event;
        echo $event->id;
        echo "<br>";
        echo $event->title;
        echo "<br>";
        echo $event->start;
        echo "<br>";
        echo $event->end;
        echo "<br>";

    }die();

Result: 1 Adam 2016-12-08 12:00:00 2016-12-08 13:30:00

2 Adam 2016-12-22 12:00:00 2016-12-22 13:30:00

3 Adam 2017-01-05 12:00:00 2017-01-05 13:30:00

4 Adam 2017-01-19 12:00:00 2017-01-19 13:30:00

5 Adam 2017-02-02 12:00:00 2017-02-02 13:30:00

6 Adam 2017-02-16 12:00:00 2017-02-16 13:30:00

7 Adam 2017-03-02 12:00:00 2017-03-02 13:30:00

8

Edofre commented 7 years ago

And the calendar and events show up but you can't move them right?

djnordeen commented 7 years ago

Unfortunately the events do not show up.

Edofre commented 7 years ago

Do you get any errors in your browser console? And silly question but do the event dates match the currently displayed date on the calendar? That you're not displaying a week that has no events.

djnordeen commented 7 years ago

No errors. This would help, but no. I have dates that would appear all year long. If I echo the $events array 2500 records. I think that the line 'events' => $events; somehow the information is not getting passed.

djnordeen commented 7 years ago

In your example $events = [ // minimum new Event([ 'id' => uniqid(), 'title' => 'Appointment #' . rand(1, 999), 'start' => '2017-04-03 14:00:00', ]),

When I try this I get an error Event not found. But when I add the edofre\fullcalendar\Fullcalendar\Event There is no error but the event will not display

Edofre commented 7 years ago

That's because I set the namespace at the top of my controller.

use edofre\fullcalendar\models\Event;
djnordeen commented 7 years ago

I see that now. I had wrong use statement. Still not rendering the events. Will try to load calendar in new project.

djnordeen commented 7 years ago

Here is part of my $events array that I pass to the model: [ 0 => yii2fullcalendar\models\Event#1 ( [id] => 1 [title] => 'Adam' [description] => '4777 Wilcox Road, Holt, MI 48842' [allDay] => null [start] => '2016-12-08 12:00:00' [end] => '2016-12-08 13:30:00' [ranges] => null [dow] => null [url] => null [className] => null [editable] => null [startEditable] => null [durationEditable] => null [source] => null [color] => null [backgroundColor] => ' #CC73E1' [borderColor] => null [textColor] => null [resourceId] => null [yii\base\Model:_errors] => null [yii\base\Model:_validators] => null [yii\base\Model:_scenario] => 'default' [yii\base\Component:_events] => [] [yii\base\Component:_behaviors] => null )

Edofre commented 7 years ago

Hm, it could be that it's taking a super long time to render the events as it's 2500 events. Maybe you can fetch the events using AJAX and filter out the events that should not currently be displayed.

Edofre commented 7 years ago

I'm closing this because there has been no response/update in a month.