FullCalendar Timeline View 使用
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 使用的更多相关文章
- 日历插件FullCalendar应用:(一)数据展现
在博客园逛了很长时间了,它帮助我获得了很多知识,很感谢大家的分享,而自己呢,由于各种纠结一直没提笔写博客,直到我看到了这篇文章http://www.cnblogs.com/zhaopei/p/why_ ...
- FullCalendar 的学习笔记(二)
下面是一个.NET webForm的具体列子 注意引用了artDialog 以及异步请求数据的json格式字符串 <html xmlns="http://www.w3.org/1999 ...
- fullCalendar:中文API
1.与google日历连接,别忘记加入<script type='text/javascript' src='js/gcal.js'/> events: $.fullCalendar.gc ...
- FullCalendar(日程管理控件)
(以下是我学习FullCalendar控件时,网络上收集的一些资料) jQuery.fullCalendar官方网址: http://arshaw.com/fullcalendar/ http://a ...
- Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译
本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 相关文章: ...
- dhtmlxScheduler日历日程控件包括天视图,周视图,月视图,年视图和日程表视图
dhtmlxScheduler 是一个基于Web的类似于Outlook的日历日程控件. 它完全由javascript/js/css编写, 提供类似于MS Outlook Calendar, Apple ...
- JavaScript 中 4 种常见的内存泄露陷阱
了解 JavaScript 的内存泄露和解决方式! 在这篇文章中我们将要探索客户端 JavaScript 代码中常见的一些内存泄漏的情况,并且学习如何使用 Chrome 的开发工具来发现他们.读一读吧 ...
- chrome 浏览器 开发者工具 性能检测 参数解释
Sending is time spent uploading the data/request to the server. It occurs between blocking and waiti ...
- JS内存泄漏 和Chrome 内存分析工具简介(摘)
原文地址:http://web.jobbole.com/88463/ JavaScript 中 4 种常见的内存泄露陷阱 原文:Sebastián Peyrott 译文:伯乐在线专栏作者 - AR ...
随机推荐
- opencv3.2.0实现视频抽帧,并保存成图片
.实现指定帧数的抽取.和全部帧数的抽取,并保存到指定目录. 在QT新建一个控制台程序,程序源码如下:(程序实现每十帧获取一次帧) #include <QCoreApplication> # ...
- Hive是读时模式
Hive处理的数据是大数据,在保存表数据时不对数据进行校验,而是在读数据时校验,不符合格式的数据设置为NULL: 读时模式的优点是,加载数据库快. 传统的数据库如mysql.oracle是写时模式,不 ...
- 带你从零学ReactNative开发跨平台App开发(十)
ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...
- 带你从零学ReactNative开发跨平台App开发[expo 打包发布](八)
ReactNative跨平台开发系列教程: 带你从零学ReactNative开发跨平台App开发(一) 带你从零学ReactNative开发跨平台App开发(二) 带你从零学ReactNative开发 ...
- 如何使用CSS进行网页布局(HTML/CSS)
什么叫做布局? 又称为版式布局,是网页UI设计师将有限的视觉元素进行有机的排列组合. 题目:假设高度已知,请写出三栏布局,其中左栏和右栏宽度各为300px,中间自适应 1.浮动布局 <!DOCT ...
- twemproxy源码分析
twemproxy是twitter开源的redis/memcached 代理,数据分片提供取模,一致性哈希等手段,维护和后端server的长连接,自动踢除server,恢复server,提供专门的状态 ...
- SQL Server ->> 使用CROSS APPLY语句是遇到聚合函数中包含外部引用列时报错
本次遇到的问题是CROSS APPLY的内部查询语句中的聚合函数包含CASE WHEN判断,且同时又内部语句的表的列和外部引用的表的列,此时会报下列的错误. 消息 8124,级别 16,状态 1,第 ...
- 1. 跟踪标记 (Trace Flag) 1117, 1118 文件增长及空间分配方式
跟踪标记:1117 功能: 默认,同一个文件组下的多个文件,如果某个文件没有可用空间,且设置了自动增长,则该文件自动增长,其他文件大小保持不变: 开启后,同一文件组下的多个文件,如果某个文件没有可用空 ...
- [翻译] JTSReachability
JTSReachabilit An adaptation of Apple's Reachability with some block-based conveniences. 这是一个苹果的网络检测 ...
- [UI] 精美UI界面欣赏[2]
精美UI界面欣赏[2]