Laravel后台极速开发框架(记实) - 集成日历组件

时间:2024-10-29 18:37:38

效果截图

Laravel后台极速开发框架(记实) - 集成日历组件_Laravel-admin

Laravel后台极速开发框架(记实) - 集成日历组件_Laravel_02

代码实现

<?php

namespace Dcat\Admin\Widgets;

use Illuminate\Support\Str;

class Calendar extends Widget {

    public static $js = [
        '@fullcalendar'
    ];

    public static $css = [
        '@fullcalendar'
    ];
    /**
     * @var string
     */
    protected $view = 'admin::widgets.calendar';

    protected $calendarId;
    /**
     * @var array
     */
    protected $items = [];

    protected $locale = 'zh-cn';

    protected $timeZone = 'Asia/Shanghai';

    protected $initialView = 'dayGridMonth';

    protected $header_toolbar_right_btn = 'dayGridMonth,timeGridWeek,timeGridDay,listWeek';

    /**
     * Collapse constructor.
     */
    public function __construct() {
        $this->calendarId = 'calendar' . Str::random(5);
        $this->id('calendar-' . uniqid());
        $this->class('box-group');
        $this->style('margin-bottom: 20px');
    }

    /**
     * @desc 设置 日历容器ID
     * @param $id
     */
    public function calendarId($id) {
        $this->calendarId = $id;
        return $this;
    }

    /**
     * @desc 设置 日历语言包
     * @param $value
     */
    public function locale($value) {
        $this->locale = $value;
        return $this;
    }

    /**
     * @desc 设置 日历的时区
     * @param $value
     */
    public function timeZone($value) {
        $this->timeZone = $value;
        return $this;
    }

    /**
     * @desc 设置 日历的初始化视图  可选值 dayGridMonth,timeGridWeek,timeGridDay,listWeek
     * @param $value
     */

    public function initialView($value) {
        $this->initialView = $value;
        return $this;
    }

    /**
     * @desc 设置 日历的头部右侧所展示的btn  全部:dayGridMonth,timeGridWeek,timeGridDay,listWeek
     * @param $value
     */
    public function headerToolbarRightBtn($value) {
        $this->header_toolbar_right_btn = $value;
        return $this;
    }

    /**
     * @desc 设置 日历的日期事件
     * @param $value
     */
    public function eventItem(array $item) {
        $this->items = $item;
        return $this;
    }

    /**
     * Add item.
     * 单个增加日历的日期事件
     * @param string $title 标题
     * @param string $title 描述
     * @param string $start 开始日期
     * @param string $end   结束日期
     * @return $this
     */
    public function addEvents($title, $description = '', $start, $end = '') {
        $event_info = [
            'title'       => $title,
            'description' => $description,
            'start'       => $start,
            'allDay'      => false,
            'showModal'   => true,
        ];
        if (!empty($end)) {
            $event_info['end'] = $end;
        }
        $this->items[] = $event_info;

        return $this;
    }
    // 
    public function backgroundColor($color) {
        if(!empty($this->items[count($this->items) - 1])){
            $this->items[count($this->items) - 1]['backgroundColor'] = $color;
        }
        return $this;
    }

    public function borderColor($color) {
        if(!empty($this->items[count($this->items) - 1])){
            $this->items[count($this->items) - 1]['borderColor'] = $color;
        }
        
        return $this;
    }

    public function allDay($bool) {
        if(!empty($this->items[count($this->items) - 1])){
            $this->items[count($this->items) - 1]['allDay'] = $bool;
        }
        
        return $this;
    }

    /**
     * @desc 设置 日历的日期事件是否 点击 展示modal
     * @param $value
     */
    public function showModal($bool = true) {
        if(!empty($this->items[count($this->items) - 1])){
            $this->items[count($this->items) - 1]['showModal'] = $bool;
        }
        
        return $this;
    }

    /**
     * @desc 设置 日历的日期事件的weburl
     * @param $value
     */
    public function webUrl($url) {
        if(!empty($this->items[count($this->items) - 1])){
            $this->items[count($this->items) - 1]['url'] = $url;
        }
        
        return $this;
    }
    /**
     * {@inheritdoc}
     */
    public function defaultVariables() {

        return [
            'id'                       => $this->id,
            'locale'                   => $this->locale,
            'timeZone'                 => $this->timeZone,
            'initialView'              => $this->initialView,
            'header_toolbar_right_btn' => $this->header_toolbar_right_btn,
            'calendar_id'              => $this->calendarId,
            'items'                    => json_encode($this->items, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES),
            'attributes'               => $this->formatAttributes(),
        ];
    }

}

** 对应的前端模板**

<div class="calendar-box">
    <div id="{{$calendar_id}}"></div>

    <div id="external-events">
    </div>
    <div id="drop-remove">

    </div>

    <!-- 模态框 -->
    <div class="modal fade" id="{{$calendar_id}}-Modal" tabindex="-1" data-backdrop="static" role="dialog" aria-labelledby="eventModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content ">
                <div class="modal-header">
                    <h5 class="modal-title">事件详情</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">×</span>
                    </button>
                </div>
                <div class="modal-body">

                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">知道了</button>
                </div>
            </div>
        </div>
    </div>
</div>

<script>

    /* initialize the external events
     -----------------------------------------------------------------*/
    function ini_events(ele) {
        ele.each(function () {

            // create an Event Object (https://fullcalendar.io/docs/event-object)
            // it doesn't need to have a start or end
            var eventObject = {
                title: $.trim($(this).text()) // use the element's text as the event title
            }

            // store the Event Object in the DOM element so we can get to it later
            $(this).data('eventObject', eventObject)

            // make the event draggable using jQuery UI
            $(this).draggable({
                zIndex: 1070,
                revert: true, // will cause the event to go back to its
                revertDuration: 0  //  original position after the drag
            })

        })
    }

    ini_events($('#external-events div.external-event'))

    /* initialize the calendar
 -----------------------------------------------------------------*/
    //Date for the calendar events (dummy data)
    var date = new Date()
    var d = date.getDate(),
        m = date.getMonth(),
        y = date.getFullYear()

    var Calendar = FullCalendar.Calendar;
    var Draggable = FullCalendar.Draggable;

    var containerEl = document.getElementById('external-events');
    var checkbox = document.getElementById('drop-remove');
    var calendarEl = document.getElementById('{{$calendar_id}}');

    // initialize the external events
    // ----------------------------------------------------------------
    new Draggable(containerEl, {
        itemSelector: '.external-event',
        eventData: function (eventEl) {
            return {
                title: eventEl.innerText,
                backgroundColor: window.getComputedStyle(eventEl, null).getPropertyValue('background-color'),
                borderColor: window.getComputedStyle(eventEl, null).getPropertyValue('background-color'),
                textColor: window.getComputedStyle(eventEl, null).getPropertyValue('color'),
            };
        }
    });

    var calendar = new Calendar(calendarEl, {
        initialView: '{{$initialView}}',
        selectable: true,
        locale: '{{$locale}}',
        timeZone: '{{$timeZone}}',
        headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            right: '{{$header_toolbar_right_btn}}'
        },
        buttonText: { // 设置按钮文本为中文
            today: '今天',
            month: '月',
            week: '周',
            day: '日',
            list: '日程',
        },
        views: {
            list: {
                buttonText: '日程',
            }
        },
        themeSystem: 'bootstrap',
        events: {!! $items !!},
        eventClick: function(info) {
            // 检查事件是否允许弹出模态框
            if (info.event.extendedProps.showModal) {
                // 获取事件的标题和描述
                var eventTitle = info.event.title;
                var eventDescription = info.event.extendedProps.description;

                // 设置模态框的内容
                $('#{{$calendar_id}}-Modal').find('.modal-title').text(eventTitle);
                $('#{{$calendar_id}}-Modal').find('.modal-body').text(eventDescription);
                // 显示模态框
                $('#{{$calendar_id}}-Modal').modal('show');
            }

        },
        editable: true,
        droppable: false, // this allows things to be dropped onto the calendar !!!
        drop: function (info) {
            // is the "remove after drop" checkbox checked?
            if (checkbox.checked) {
                // if so, remove the element from the "Draggable Events" list
                info.draggedEl.parentNode.removeChild(info.draggedEl);
            }
        }
    });

    calendar.render();
    // $('#calendar').fullCalendar()

    /* ADDING EVENTS */
    var currColor = '#3c8dbc' //Red by default
    // Color chooser button
    $('#color-chooser > li > a').click(function (e) {
        e.preventDefault()
        // Save color
        currColor = $(this).css('color')
        // Add color effect to button
        $('#add-new-event').css({
            'background-color': currColor,
            'border-color': currColor
        })
    })
    $('#add-new-event').click(function (e) {
        e.preventDefault()
        // Get value and make sure it is not null
        var val = $('#new-event').val()
        if (val.length == 0) {
            return
        }

        // Create events
        var event = $('<div />')
        event.css({
            'background-color': currColor,
            'border-color': currColor,
            'color': '#fff'
        }).addClass('external-event')
        event.text(val)
        $('#external-events').prepend(event)

        // Add draggable funtionality
        ini_events(event)

        // Remove event from text input
        $('#new-event').val('')
    })
</script>

使用方法

<?php

use Dcat\Admin\Widgets\Calendar;

// 获取实例
$calendar = Calendar::make();
$events_list = [
            [
                'title' => '今天的事项',// 事项标题
                'start' => '2024-10-01 14:00:00', // 事项开始日期,您可以根据需要替换
                'end' => '2024-10-02 16:00:00', // 事项结束日期
                'backgroundColor' => '#f56954', // red
                'borderColor' => '#f56954', // red
                'allDay' => false, // 指示事件是否为全天事件。默认为 false
                'description' => '这是今天的事项描述', // 描述信息
                'showModal' => true, // 是否弹出 事项详情 modal 
                // 'url' => 'https://www.baidu.com/', // 指定跳转url
            ]
        ];
$calendar->eventItem($events_list); // 给定日期事项列表

配置项

<?php

// 获取实例
$calendar = Calendar::make();

// 设置 日历容器ID 
$calendar->calendarId('calendar_ids');

// 设置 日历语言包 默认 zh-cn
$calendar->locale('zh-cn');

// 设置 日历的时区 默认 Asia/Shanghai
$calendar->timeZone('Asia/Shanghai');

// 设置 日历的初始化视图 默认 dayGridMonth  可选值 dayGridMonth,timeGridWeek,timeGridDay,listWeek
$calendar->initialView('dayGridMonth');

// 设置 日历的头部右侧所展示的btn  可选值:dayGridMonth,timeGridWeek,timeGridDay,listWeek 。可全部
$calendar->headerToolbarRightBtn('dayGridMonth');

plus 版已集成,可直接使用

composer require dcat-plus/laravel-admin:1.2.8

plus 版已集成多种表单组件

表单:sku 来自于 :https://github.com/abbotton/dcat-sku-plus

表单:多媒体选择器 来自于:https://github.com/deatil/dcat-form-media

在此感谢他们开源对dcat-admin 的贡献。

Laravel后台极速开发框架(记实) - 集成日历组件_Laravel_03

Laravel后台极速开发框架(记实) - 集成日历组件_模态框_04

Laravel后台极速开发框架(记实) - 集成日历组件_模态框_05

Laravel后台极速开发框架(记实) - 集成日历组件_Laravel-admin_06