Планировщик dhtmlx Редактировать и удалять - PullRequest
0 голосов
/ 05 марта 2019

Я использую планировщик DHTMLX в своем проекте с использованием фреймворка Symfony.все хорошо, я могу успешно создавать события и добавлять их в базу данных, а затем отображать их.но каждый раз, когда я пытаюсь отредактировать или удалить, отображается сообщение «Ошибка: невозможно удалить или невозможно редактировать».

  1. schedulerScript.js
  2. scheduler.html.twig
  3. SchedulerController.php

:

// 1. Configure Scheduler Basic Settings
scheduler.config.xml_date="%Y-%m-%d %H:%i";
scheduler.config.first_hour = 6;
scheduler.config.last_hour = 24;
scheduler.config.limit_time_select = true;
scheduler.config.details_on_create = true;
// Disable event edition with single click
scheduler.config.select = false;
scheduler.config.details_on_dblclick = true;
scheduler.config.max_month_events = 5;
scheduler.config.resize_month_events = true;

// 2. Configure Lightbox (form) sections
scheduler.config.lightbox.sections = [
    // If you have another field on your Appointment entity (e.g example_field column), you would add it like
    // {name:"Example Field", height:30, map_to:"example_field", type:"textarea"},
    {name:"Title", height:30, map_to:"text", type:"textarea"},
    {name:"Description", height:70, map_to:"description", type:"textarea"},
    {name:"time", height:72, type:"time", map_to:"auto"}
];

// 3. Start calendar with custom settings
var initSettings = {
    // Element where the scheduler will be started
    elementId: "scheduler_element",
    // Date object where the scheduler should be started
    startDate: new Date(),
    // Start mode
    mode: "month"
};

scheduler.init(initSettings.elementId, initSettings.startDate , initSettings.mode);

// 4. Parse the initial (From index controller) appointments
scheduler.parse(window.GLOBAL_APPOINTMENTS, "json");

// Retrieve the format date method (that follows the given pattern) from the scheduler library
var formatDate = scheduler.date.date_to_str("%d-%m-%Y %H:%i:%s");

/**
 * Returns an Object with the desired structure of the server.
 * 
 * @param {*} id 
 * @param {*} useJavascriptDate 
 */
function getFormatedEvent(id, useJavascriptDate){
    var event;

    // If id is already an event object, use it and don't search for it
    if(typeof(id) == "object"){
        event = id;
    }else{
        event = scheduler.getEvent(parseInt(id));
    }

    if(!event){
        console.error("The ID of the event doesn't exist: " + id);
        return false;
    }
     
    var start , end;
    
    if(useJavascriptDate){
        start = event.start_date;
        end = event.end_date;
    }else{
        start = formatDate(event.start_date);
        end = formatDate(event.end_date);
    }
    
    return {
        id: event.id,
        start_date : start,
        end_date : end,
        description : event.description,
        title : event.text
    };
}

// 6. Attach Event Handlers !

/**
 * Handle the CREATE scheduler event
 */
scheduler.attachEvent("onEventAdded", function(id,ev){
    var schedulerState = scheduler.getState();
    
    $.ajax({
        url:  window.GLOBAL_SCHEDULER_ROUTES.create,
        data: getFormatedEvent(ev),
        dataType: "json",
        type: "POST",
        success: function(response){
            // Very important:
            // Update the ID of the scheduler appointment with the ID of the database
            // so we can edit the same appointment now !
            
            scheduler.changeEventId(ev.id , response.id);

            alert('The appointment '+ev.text+ " has been succesfully created");
        },
        error:function(error){
            alert('Error: The appointment '+ev.text+' couldnt be created');
            console.log(error);
        }
    }); 
});

/**
 * Handle the UPDATE event of the scheduler on all possible cases (drag and drop, resize etc..)
 *  
 */
scheduler.attachEvent("onEventChanged", function(id,ev){
    $.ajax({
        url:  window.GLOBAL_SCHEDULER_ROUTES.update,
        data: getFormatedEvent(ev),
        dataType: "json",
        type: "POST",
        success: function(response){
            if(response.status === "success"){
                alert("Event succesfully updated !");
            }
        },
        error: function(err){
            alert("Error: Cannot save changes");
            console.error(err);
        }
    });

    return true;
});

/**
 * Handle the DELETE appointment event
 */
scheduler.attachEvent("onConfirmedBeforeEventDelete",function(id,ev){
    $.ajax({
        url: window.GLOBAL_SCHEDULER_ROUTES.delete,
        data:{
            id: id
        },
        dataType: "json",
        type: "DELETE",
        success: function(response){
            if(response.status === "success"){
                if(!ev.willDeleted){
                    alert("Appointment succesfully deleted");
                }
            }else if(response.status === "error"){
                alert("Error: Cannot delete appointment");
            }
        },
        error:function(error){
            alert("Error: Cannot delete appointment: " + ev.text);
            console.log(error);
        }
    });
    
    return true;
});


/**
 * Edit event with the right click too
 * 
 * @param {type} id
 * @param {type} ev
 * @returns {Boolean}
 */
scheduler.attachEvent("onContextMenu", function (id, e){
    scheduler.showLightbox(id);
    e.preventDefault();
});
{% extends 'backend.html.twig' %}

{% block body -%}
    <!-- Include the flat style of the scheduler -->
    <link rel='stylesheet' type='text/css' href='{{ asset("libraries/dhtmlx/codebase/dhtmlxscheduler_flat.css") }}' charset="utf-8"/>
    <link rel='stylesheet' type='text/css' href='/assets/libraries/dhtmlx/codebase/dhtmlxscheduler_flat.css' charset="utf-8"/>
    <!-- If you won't use full screen mode, ignore the following style -->



    <div id="scheduler_element" class="dhx_cal_container" style='width:100%; height:100vh;'>
        <div class="dhx_cal_navline">
            <div class="dhx_cal_prev_button">&nbsp;</div>
            <div class="dhx_cal_next_button">&nbsp;</div>
            <div class="dhx_cal_today_button"></div>
            <div class="dhx_cal_date"></div>
            <div class="dhx_cal_tab" name="day_tab" style="right:204px;"></div>
            <div class="dhx_cal_tab" name="week_tab" style="right:140px;"></div>
            <div class="dhx_cal_tab" name="month_tab" style="right:76px;"></div>
        </div>
        <div class="dhx_cal_header"></div>
        <div class="dhx_cal_data"></div>
    </div>


    <!-- Include the scheduler library -->
    <script src='{{ asset("libraries/dhtmlx/codebase/dhtmlxscheduler.js") }}' type='text/javascript' charset="utf-8"></script>
    <link rel='stylesheet' type='text/css' href='/assets/libraries/dhtmlx/codebase/dhtmlxscheduler.js' charset="utf-8"/>

    <!-- Include jQuery to handle AJAX Requests -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>



    <script>
        // Expose the appointments globally by printing the JSON string with twig and the raw filter
        // so they can be accesible by the schedulerScripts.js the controller
        window.GLOBAL_APPOINTMENTS = {{ appointments|raw }};

        // As the scheduler scripts will be in other files, the routes generated by twig
        // should be exposed in the window too
        window.GLOBAL_SCHEDULER_ROUTES = {
            create: '{{ path("scheduler_create") }}',
            update: '{{ path("scheduler_update") }}',
            delete: '{{ path("scheduler_delete") }}'
        };
    </script>

    <!-- Include the schedulerScripts that you will need to write in the next step -->
    <script src='{{ asset("libraries/schedulerScripts.js") }}' type='text/javascript' charset="utf-8"></script>


{% endblock %}
 /**
 * Handle the update of the appointments.
 *
 */
public function updateAction(Request $request){
    $em = $this->getDoctrine()->getManager();
    $repositoryAppointments = $em->getRepository("AppBundle:Appointments");

    $appointmentId = $request->request->get("id");

    $appointment = $repositoryAppointments->find($appointmentId);

    if(!$appointment){
        return new JsonResponse(array(
            "status" => "error",
            "message" => "The appointment to update $appointmentId doesn't exist."
        ));
    }

    // Use the same format used by Moment.js in the view
    $format = "d-m-Y H:i:s";

    // Update fields of the appointment
    $appointment->setTitle($request->request->get("title"));
    $appointment->setDescription($request->request->get("description"));
    $appointment->setStartDate(
        \DateTime::createFromFormat($format, $request->request->get("start_date"))
    );
    $appointment->setEndDate(
        \DateTime::createFromFormat($format, $request->request->get("end_date"))
    );
    $user = $this->get('security.token_storage')
        ->getToken()
        ->getUser()->getIdUser();
    $repositoryUser = $this->getDoctrine()->getRepository(User::class);
    $users = $repositoryUser->findOneByIdUser($user);
    $appointment->setIdUser($users);

    // Update appointment
    $em->persist($appointment);
    $em->flush();

    return new JsonResponse(array(
        "status" => "success"
    ));
}

/**
 * Deletes an appointment from the database
 *
 */
public function deleteAction(Request $request){
    $em = $this->getDoctrine()->getManager();
    $repositoryAppointments = $em->getRepository("AppBundle:Appointments");

    $appointmentId = $request->request->get("id");

    $appointment = $repositoryAppointments->find($appointmentId);

    if(!$appointment){
        return new JsonResponse(array(
            "status" => "error",
            "message" => "The given appointment $appointmentId doesn't exist."
        ));
    }

    // Remove appointment from database !
    $em->remove($appointment);
    $em->flush();

    return new JsonResponse(array(
        "status" => "success"
    ));
}
...