FullCalendar  Timeline View(v4)

The Scheduler add-on provides a new view called “timeline view” with a customizable horizontal time-axis and resources as rows.

1. 先安装fullcalendar和用到的插件

npm install --save @fullcalendar/core @fullcalendar/resource-timeline @fullcalendar/interaction

2.在使用时导入

import {Calendar} from '@fullcalendar/core';
import resourceTimelinePlugin from '@fullcalendar/resource-timeline';
import interactionPlugin from '@fullcalendar/interaction';
import '@fullcalendar/core/main.css';
import '@fullcalendar/timeline/main.css';
import '@fullcalendar/resource-timeline/main.css';

3. 初始化Calendar时,添加使用的插件

 plugins: [interactionPlugin, resourceTimelinePlugin],

4.最终实现资源/事件的添加删除.

上代码.

 import {Calendar} from '@fullcalendar/core';
import resourceTimelinePlugin from '@fullcalendar/resource-timeline';
import interactionPlugin from '@fullcalendar/interaction';
import '@fullcalendar/core/main.css';
import '@fullcalendar/timeline/main.css';
import '@fullcalendar/resource-timeline/main.css'; // import zh_cn from '@fullcalendar/core/locales/zh-cn';
let option = {
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
plugins: [interactionPlugin, resourceTimelinePlugin],
defaultView: 'resourceTimeline',
now: '2019-03-07',
// locale: zh_cn,
selectable: true,
selectHelper: true,
editable: true, // enable draggable events
eventResourceEditable: false,
aspectRatio: 1,
// height: 440,
contentHeight: 440,
resourceAreaWidth: '120px',
eventOverlap: false,
selectOverlap: false,
eventTextColor: '#fff',
displayEventTime: true,
displayEventEnd: true,
slotLabelFormat: {
hour: 'numeric',
minute: '2-digit',
omitZeroMinute: true,
meridiem: 'short',
hour12: false,
},
eventTimeFormat: {
hour: 'numeric',
minute: '2-digit',
meridiem: 'narrow',
hour12: false,
},
header: {
left: '',
center: '',
right: '',
},
resourceLabelText: '姓名',
resources: [],
events: [],
};
/**
* {Object} option , onSelect: function onEventClick: function ,
*/ class Timeline {
constructor(el, opt = {}, callBack = () => {}) {
this.callBack = callBack;
console.log('timeline -init');
this._option = Object.assign(
{
select: info => this.select(info),
dateClick: info => this.dateClick(info),
eventClick: info => this.eventClick(info),
eventMouseEnter: info => this.eventMouseEnter(info),
eventMouseLeave: info => this.eventMouseLeave(info),
eventResize: info => this.eventResize(info),
eventDrop: info => this.eventDrop(info),
resourceRender: info => this.resourceRender(info),
eventRender: info => this.eventRender(info),
eventDestroy: info => this.eventDestroy(info),
},
option,
opt
);
console.log('timeline-option==>>', this._option);
this.calendar = new Calendar(el, this._option);
this.render(); let currentDate = new Date(this._option.now);
let end = new Date().setDate(currentDate.getDate());
if (currentDate.getHours() !== 0) {
end = new Date().setDate(currentDate.getDate() + 1);
}
console.table('start, end', currentDate, new Date(end));
this.setOption('visibleRange', {
start: currentDate,
end: end,
});
} /**
* @param {Object} value
*/
setOption(key, value) {
this.calendar.setOption(key, value);
this._option[key] = value;
} // methods
render() {
this.calendar.render();
}
addResource(resource) {
if (!resource) {
return;
}
this.calendar.addResource(resource);
}
removeResource(resource, e) {
if (!this._option.editable) {
return;
}
this._option.onRemoveResource && this._option.onRemoveResource(resource);
let events = resource.getEvents();
events.forEach(event => {
event.remove();
});
resource.remove();
this.getResult(); e.target.removeEventListener('click', this.removeResource);
}
addEvent(event) {
if (!event) {
return;
}
let tmp = this.calendar.getEventById(event.id);
if (tmp) {
for (let key in event) {
if (tmp.extendedProps[key]) {
tmp.setExtendedProp(key, event[key]);
continue;
}
if (tmp[key]) {
tmp.setProp(key, event[key]);
}
}
} else {
this.calendar.addEvent(event);
console.log('addd', event);
}
}
removeEvent(eventId) {
let event = this.calendar.getEventById(eventId);
if (event) {
event.remove();
this.getResult();
}
} destroy() {
this.calendar.destroy();
console.log('timeline destroy >>>>>>>');
}
getResult() {
let resources = this.calendar.getResources();
let result = [];
resources.map(item => {
let tmp = {
resource: item,
events: item.getEvents(),
};
result.push(tmp);
}); this.callBack && this.callBack(result);
}
isValid(event) {
let now = this._option.now;
let start = new Date(event.start).getTime();
let end = new Date(event.end).getTime();
let startH = new Date(now).getHours();
let startD = new Date(now).getDate();
let crossDate = new Date(now);
crossDate.setDate(startD);
crossDate.setHours(23);
let endPoint = crossDate.getTime();
if (startH !== 0) {
crossDate.setDate(startD + 1);
crossDate.setHours(startH);
endPoint = crossDate.getTime();
}
if (start < now || end < now || start > endPoint || end > endPoint) {
return false;
}
return true;
}
/**
callbacks
*/
select(info) {
if (!this.isValid({start: info.start, end: info.end})) {
// info.revert();
return;
}
this._option.onSelect && this._option.onSelect(info);
}
dateClick(arg) {
console.log('dateClick', arg.date, arg.resource ? arg.resource.id : '(no resource)');
}
eventClick(info) {
this._option.onEventClick && this._option.onEventClick(info);
}
eventMouseEnter(info) {
this._option.onEventMouseEnter && this._option.onEventMouseEnter(info);
}
eventMouseLeave(info) {
this._option.onEventMouseLeave && this._option.onEventMouseLeave(info);
}
eventResize(info) {
if (!this.isValid(info.event)) {
info.revert();
}
// this.getResult();
}
eventDrop(info) {
if (!this.isValid(info.event)) {
info.revert();
}
// this.getResult();
}
resourceRender(info) {
let dom = info.el;
dom.style = dom.style + ';position:relative;';
let close = document.createElement('i');
close.classList.add('iconfont', 'icon-c');
close.style = 'position:absolute;right:10px;top:50%;transform:translateY(-50%);font-size: 10px;';
close.addEventListener('click', e => this.removeResource(info.resource, e));
dom.appendChild(close);
}
eventRender(info) {
this.getResult();
} eventDestroy(info) {
// this.getResult();
// console.log('eventDestroy', info);
}
} export default Timeline;

使用(示例)

 let timelineView = new Timeline(
document.querySelector('#time-line-day'), {
now: new Date(),
onSelect: info => {
let event = {
id: this.eventId,
title: this.eventId,
resourceId: info.resource.id,
start: info.start,
end: info.end,
};
timelineView.addEvent(event); },
onRemoveResource: info => { },
onEventClick: info => {
let event = {
id: info.event.id,
title: info.event.title,
resourceId: info.event.getResources()[0].id,
start: info.event.start,
end: info.event.end,
};
let resourceId = info.event.getResources()[0].id; },
},
result => { }
);

FullCalendar插件 plug-index

FullCalendar Timeline View 使用的更多相关文章

  1. 日历插件FullCalendar应用:(一)数据展现

    在博客园逛了很长时间了,它帮助我获得了很多知识,很感谢大家的分享,而自己呢,由于各种纠结一直没提笔写博客,直到我看到了这篇文章http://www.cnblogs.com/zhaopei/p/why_ ...

  2. FullCalendar 的学习笔记(二)

    下面是一个.NET webForm的具体列子 注意引用了artDialog 以及异步请求数据的json格式字符串 <html xmlns="http://www.w3.org/1999 ...

  3. fullCalendar:中文API

    1.与google日历连接,别忘记加入<script type='text/javascript' src='js/gcal.js'/> events: $.fullCalendar.gc ...

  4. FullCalendar(日程管理控件)

    (以下是我学习FullCalendar控件时,网络上收集的一些资料) jQuery.fullCalendar官方网址: http://arshaw.com/fullcalendar/ http://a ...

  5. Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译

    本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 相关文章: ...

  6. dhtmlxScheduler日历日程控件包括天视图,周视图,月视图,年视图和日程表视图

    dhtmlxScheduler 是一个基于Web的类似于Outlook的日历日程控件. 它完全由javascript/js/css编写, 提供类似于MS Outlook Calendar, Apple ...

  7. JavaScript 中 4 种常见的内存泄露陷阱

    了解 JavaScript 的内存泄露和解决方式! 在这篇文章中我们将要探索客户端 JavaScript 代码中常见的一些内存泄漏的情况,并且学习如何使用 Chrome 的开发工具来发现他们.读一读吧 ...

  8. chrome 浏览器 开发者工具 性能检测 参数解释

    Sending is time spent uploading the data/request to the server. It occurs between blocking and waiti ...

  9. JS内存泄漏 和Chrome 内存分析工具简介(摘)

    原文地址:http://web.jobbole.com/88463/ JavaScript 中 4 种常见的内存泄露陷阱   原文:Sebastián Peyrott 译文:伯乐在线专栏作者 - AR ...

随机推荐

  1. Ubuntu 添加删除用户 How to Add and Delete Users on Ubuntu 16.04

      Introduction One of the most basic tasks that you should know how to do on a fresh Linux server is ...

  2. linux 软件包安装方式选择、安装位置、源码包安装

    对外提供服务,比如apache,应使用源码包安装对内提供服务,比如gcc,只是我自己使用,使用rpm包安装 rpm包不需要指定安装位置,源码包的安装需要手动指定安装位置 rpm包默认安装位置/etc/ ...

  3. node(4)express 框架 EJS模板,cookie, session的学习

    一.EJS 概述:前端咱们使用过的一个模板套路,是underscore的套路.接下来EJS它属于后台工程师人的模板. https://www.npmjs.com/package/ejs 官网地址 特点 ...

  4. Ad-hoc 查询以及动态SQL的罪恶[译]

    本文为翻译文章,原文地址:https://www.simple-talk.com/blogs/2009/08/03/stolen-pages-ad-hoc-queries-and-the-sins-o ...

  5. 32位Windows7 利用多余的不能识别的电脑内存 RAMDISK5.5教程

    32位Windows7 利用多余的不能识别的电脑内存 RAMDISK5.5教程 环境:Windows7 32位 Ultimate 内存8GB 只能识别2.95GB内存 ramdisk5.5只适用于Wi ...

  6. Oracle EBS 报错:此责任无可用函数。 更改责任或与您的系统管理员联系。

    解决:修改配置文件        1.FND: Diagnostics (FND:诊断)            启用设为”是”        2.Utilities:Diagnostics (公用程序 ...

  7. 使用keychain永久存储数据

    使用keychain永久存储数据 https://github.com/soffes/sskeychain keychain当然还是使用开源的好:),keychain是干啥用的?这个,baidu一下你 ...

  8. 使用AHKActionSheet

    使用AHKActionSheet https://github.com/fastred/AHKActionSheet 基本配置代码: AHKActionSheet *actionSheet = [[A ...

  9. (1)构造方法和方法重载 (2)this关键字 (3)方法的传参和递归调用

    1.构造方法和方法重载如: Person p = new Person(); - 声明Person类型的引用p指向Person类型的对象 p.show(); - 调用名字为show()的成员方法 1. ...

  10. NCE3

    Lesson1  A puma at large Pumas are large, cat-like animals which are found in America. When reports ...