概要
关于开发插件所需的文件以及插件的打包方法请参考kintone插件开发流程。
本次以“kintone日历活动插件”为例,向大家介绍插件的做成方法。
步骤0.准备插件用的应用
关于应用必须的设置,请参考kintone日历活动插件的设置表单。
步骤1.准备做成插件所需的文件
根据kintone 插件开发流程,我们来作成文件。
图标文件
使用画图软件作成下面这样的图标文件。
文件名叫“colorful-weekly.png”。
前台PC专用JavaScript文件
重点
用kintone.plugin.app.getConfig()获取插件的设置信息。
应用列表页面
- 从插件设置信息中获取列表,用FullCalendar并将其显示成日历形式(可切换显示日/周/月)。
- 更改活动的时间时,更新相应的数据。
- 根据插件的设置信息,流程管理状态按照指定的颜色显示。记录编辑页面/记录添加页面/列表编辑页面
- 控制活动开始时间和结束时间的输入时间格式等的处理用了Moment。
/* * eventCalendar Plug-in * Copyright (c) 2016 Cybozu * * Licensed under the MIT License */ jQuery.noConflict(); (function($, PLUGIN_ID) { 'use strict'; // 根据用户设置的语言切换显示中/日 function createMultilingual(num){ var user_lang = kintone.getLoginUser().language; var multilingual = { 'ja':{ '1': 'YYYY年M月', '2': 'YYYY年 M月 D日', '3': 'YYYY年 M月 D日[(]ddd[)]', '4':'今日', '5': '月', '6': '週', '7': '日', '8': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], '9': ['日曜', '月曜', '火曜', '水曜', '木曜', '金曜', '土曜'], '10': ['日', '月', '火', '水', '木', '金', '土'], '11': 'すべて見る', '12':'未入力項目があります', '13': '必須です', '14': '開始日時が終了日時より未来になっています', '15': '終了日時より過去にして下さい', '16': '開始日時より未来にして下さい', '17': '開始日時と終了日時は1分以上あけて下さ' }, 'zh':{ '1': 'YYYY年M月', '2': 'YYYY年 M月 D日', '3': 'YYYY年 M月 D日[(]ddd[)]', '4':'今天', '5': '月', '6': '周', '7': '日', '8': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], '9': ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], '10': ['周日', '周一', '周二', '周三', '周四', '周五', '周六'], '11': '显示全部', '12':'有必填项未填', '13': '必填', '14': '开始时间比结束时间晚', '15': '请选择比结束时间早的时间', '16': '请选择比开始时间晚的时间', '17': '开始时间和结束时间必须间隔至少1分钟' } }; if(!multilingual[user_lang]) { user_lang = 'ja'; } return multilingual[user_lang][num]; } // 在日历上更改活动时间时的更新处理 function putRecord(event) { var putConfig = kintone.plugin.app.getConfig(PLUGIN_ID); var stdtKey = putConfig.start_datetime; var eddtKey = putConfig.end_datetime; kintone.api('/k/v1/record', 'PUT', { 'app': kintone.app.getId(), 'id': event.rec, 'record': (function() { var param = {}; param[stdtKey] = { 'value': moment(event.start).add(-9, 'hours').format('YYYY-MM-DDTHH:mm:ssZ') }; param[eddtKey] = { 'value': moment(event.end).add(-9, 'hours').format('YYYY-MM-DDTHH:mm:ssZ') }; return param; })() }); } // 获取所有记录的函数 function fetchRecords(appId, query, opt_offset, opt_limit, opt_records) { var offset = opt_offset || 0; var limit = opt_limit || 500; var allRecords = opt_records || []; var params = {app: appId, query: query + ' limit ' + limit + ' offset ' + offset}; return kintone.api('/k/v1/records', 'GET', params).then(function(resp) { allRecords = allRecords.concat(resp.records); if (resp.records.length === limit) { return fetchRecords(appId, query, offset + limit, limit, allRecords); } return allRecords; }); } // 显示记录列表页面时的处理 kintone.events.on('app.record.index.show', function(event) { var config = kintone.plugin.app.getConfig(PLUGIN_ID); if (!config) { return false; } new kintone.Promise(function(resolve, reject) { var evTitle = config.name; var evStart = config.start_datetime; var evEnd = config.end_datetime; var startDate; var endDate; fetchRecords(kintone.app.getId(), '').then(function(calRecords) { var records = calRecords; var recEvents = []; // 当有记录存在时循环以下处理 if (records.length !== 0) { for (var i = 0; i < records.length; i++) { startDate = moment(records[i][evStart].value); endDate = moment(records[i][evEnd].value); // 当活动背景设设置有误或流程管理功能未启用时默认显示蓝色 var eventColor = '#0000ff'; // 设置活动背景色的处理 var eventStatus var flag = false; if(typeof (records[i].ステータス) !== 'undefined') { eventStatus = records[i].ステータス.value; } else if(typeof (records[i].状态) !== 'undefined'){ eventStatus = records[i].状态.value; } else if(typeof (records[i].Status) !== 'undefined') { eventStatus = records[i].Status.value; } else { flag = true; } if(flag === false) { for (var k = 1; k < 6; k++) { var stsPropName = 'status' + k; var clrPropName = 'color' + k; var status = config[stsPropName]; if (status === eventStatus) { eventColor = config[clrPropName]; break; } } } recEvents.push({ title: records[i][evTitle].value, start: startDate.format('YYYY-MM-DD HH:mm:ss'), end: endDate.format('YYYY-MM-DD HH:mm:ss'), url: location.protocol + '//' + location.hostname + '/k/' + kintone.app.getId() + '/show#record=' + records[i].$id.value, rec: records[i].$id.value, backgroundColor: eventColor, borderColor: eventColor }); } } // 设置日历 $('#calendar').fullCalendar({ lang: 'ja', theme: false, // 顶部的按钮和标题 header: { left: 'prev,next, today', center: 'title', right: ' month,agendaWeek,agendaDay' }, // 日历按日显示时 columnFormat: { month: 'ddd', week: 'M/D[(]ddd[)]', day: 'M/D[(]ddd[)]' }, // 日历的标题 titleFormat: { month: createMultilingual('1'), week: createMultilingual('2'), day: createMultilingual('3') }, // 按钮里的字符 buttonText: { prev: '<', next: '>', today: createMultilingual('4'), month: createMultilingual('5'), week: createMultilingual('6'), day: createMultilingual('7') }, // 使用以周日为起始日的日历 firstDay: '0', // 显示周末(周六,周日) weekends: true, // 默认按月显示 defaultView: 'month', // 月的处理 monthNames: createMultilingual('8'), monthNamesShort: createMultilingual('8'), // 周的处理 dayNames: createMultilingual('9'), dayNamesShort: createMultilingual('10'), // 各日历的时间格式 axisFormat: 'H:mm', timeFormat: 'H:mm', // 在日历上编辑活动 editable: true, durationEditable: true, startEditable: true, unselectAuto: true, unselectCancel: '', dragRevertDuration: 100, // 不显示一整天的预定 allDaySlot: false, // 使用以0点为一天的起点的日历 nextDayThreshold: '00:00:00', // 日历的高度 height: 700, contentHeight: 600, // 时间轴的单位 slotDuration: '01:00:00', // 拉动条状移动时,按每几分为单位移动 snapDuration: '01:00:00', // 按日显示时的详细显示 views: { day: { slotDuration: '00:30:00', snapDuration: '00:30:00', scrollTime: '06:00:00' } }, minTime: '00:00:00', maxTime: '24:00:00', // 初始时间位置 scrollTime: '00:00:00', // 按月显示时,活动如果太多省略显示不下的部分 eventLimit: true, eventLimitText: createMultilingual('11'), eventResize: function(ev, delta, revertFunc, jsEvent, ui, view) { putRecord(ev); $('#calendar').fullCalendar('unselect'); }, eventDrop: function(ev, delta, revertFunc, jsEvent, ui, view) { putRecord(ev); $('#calendar').fullCalendar('unselect'); }, eventSources: [{ events: recEvents }] }); resolve(event); }); }).then(function() { return event; }); }); // 添加记录・编辑记录・在列表页面编辑记录时 kintone.events.on(['app.record.create.submit', 'app.record.edit.submit', 'app.record.index.edit.submit'], function(event) { var record = event.record; var config = kintone.plugin.app.getConfig(PLUGIN_ID); if (!config) { return false; } var evTitleVal = record[config.name].value; var evStartVal = record[config.start_datetime].value; var evEndVal = record[config.end_datetime].value; // 活动标题・活动开始/结束时间不可为空 if (!evTitleVal || !evStartVal || !evEndVal) { event.error = createMultilingual('12'); if (!evTitleVal) { record[config.name].error = createMultilingual('13'); } if (!evStartVal) { record[config.start_datetime].error = createMultilingual('13'); } if (!evEndVal) { record[config.end_datetime].error = createMultilingual('13'); } // 开始时间晚于结束时间时报错 } else if (moment(evStartVal).format('X') > moment(evEndVal).format('X')) { event.error = createMultilingual('14'); record[config.start_datetime].error = createMultilingual('15'); record[config.end_datetime].error = createMultilingual('16'); // 开始时间和结束时间相同时报错(FullCalendar规格上的要求) } else if (moment(evStartVal).format('X') === moment(evEndVal).format('X')) { event.error = createMultilingual('17'); record[config.start_datetime].error = createMultilingual('15'); record[config.end_datetime].error = createMultilingual('16'); } return event; }); })(jQuery, kintone.$PLUGIN_ID);
以上代码另存为desktop.js,文字编码设为UTF-8,保存。
前台PC专用CSS文件
对日历列表上的周六/周日和当天等的背景色进行设置。
将以下文件保存为customize.css。
/* 周日 */ .fc-head .fc-sun { background: rgb(250, 220, 233); } /* 周六 */ .fc-head .fc-sat { background: rgb(211, 237, 251); } /* 今日 */ .fc-today { background: rgb(255, 255, 204); } .fc-center { margin-right: 1.75em; } .fc-clear { clear: none; }
另外还用到了FullCalendar库提供的CSS,在后面的资源配置文件中会将其链接添加进去。此处无需做处理。
前台智能手机端专用JavaScript文件
本次省略。
后台设置页面的HTML文件
这次我们将创建一个设置页面的HTML文件。
设置页面上,放置3个下拉框,可分别从应用表单选择一个字段作为活动标题,活动的开始时间和结束数据。还有一个5行列表,可最多对5个流程管理的状态分别设置背景色
重点
设置页面的HTML可以只写正文(body)内容。
本次为了实现可以根据用户设置的语言自动切换中文和日文的功能,使用jsrender库将设置页面上的文字放到JavaScript文件的变量里,然后在HTML里调用该变量。
<!-- * eventCalendar Plug-in * Copyright (c) 2016 Cybozu * * Licensed under the MIT License --> <div id="EventCalendarPlugin"> <div class="block"> <label class="kintoneplugin-label"> <span id ="container_label">{{html:terms.event_title}}</span> <span class="kintoneplugin-require">*</span> </label> <div class="kintoneplugin-row">{{html:terms.event_title_description}}</div> <div class="kintoneplugin-select-outer"> <div class="kintoneplugin-select"> <select id="name_code"> </select> </div> </div> </div> <div class="block"> <label class="kintoneplugin-label"> <span id ="container_label">{{html:terms.start_dateTime}}</span> <span class="kintoneplugin-require">*</span> </label> <div class="kintoneplugin-row">{{html:terms.start_dateTime_description}}</div> <div class="kintoneplugin-select-outer"> <div class="kintoneplugin-select"> <select id="start_datetime_code"> </select> </div> </div> </div> <div class="block"> <label class="kintoneplugin-label"> <span id ="container_label">{{html:terms.end_dateTime}}</span> <span class="kintoneplugin-require">*</span> </label> <div class="kintoneplugin-row">{{html:terms.end_dateTime_description}}</div> <div class="kintoneplugin-select-outer"> <div class="kintoneplugin-select"> <select id="end_datetime_code"> </select> </div> </div> </div> <div class="block"> <label class="kintoneplugin-label"> <span id ="container_label">{{html:terms.background}}</span> </label> <div class="kintoneplugin-row">{{html:terms.background_description}}</div> <div class="kintoneplugin-input-outer"> <table> <tr style="background:#ccccff"> <th>No.</th> <th>{{html:terms.background_status}}</th> <th>{{html:terms.background_color}}</th> </tr> <tr> <td>1</td> <td><input id="status1" class="kintoneplugin-input-text"></input> </td> <td><input id="color1" class="kintoneplugin-input-text"></input> </td> </tr> <tr> <td>2</td> <td><input id="status2" class="kintoneplugin-input-text"></input> </td> <td><input id="color2" class="kintoneplugin-input-text"></input> </td> </tr> <tr> <td>3</td> <td><input id="status3" class="kintoneplugin-input-text"></input> </td> <td><input id="color3" class="kintoneplugin-input-text"></input> </td> </tr> <tr> <td>4</td> <td><input id="status4" class="kintoneplugin-input-text"></input> </td> <td><input id="color4" class="kintoneplugin-input-text"></input> </td> </tr> <tr> <td>5</td> <td><input id="status5" class="kintoneplugin-input-text"></input> </td> <td><input id="color5" class="kintoneplugin-input-text"></input> </td> </tr> </table> </div> </div> <div class="block"> <button type="button" id="submit" class="kintoneplugin-button-dialog-ok">{{html:terms.save_button}}</button> <button type="button" id="cancel" class="kintoneplugin-button-dialog-cancel">{{html:terms.cancel_button}}</button> </div> </div>
单独一个HTML文件在浏览器上打开时显示如下。
插件打包后,HTML文件会读取Javascript文件中含有设置页面文字的变量,显示结果如下。
写完之后,以UTF-8的格式保存。文件名为“config.html"。
后续请点击【kintone活动日历插件的作成范例【后篇】】
回复(2)
你好,打包规则已经更新了,你可以参考以下内容:
https://developer.cybozu.io/hc/ja/articles/360000910783#step6
https://developer.cybozu.io/hc/ja/articles/360000975763
我们会及时更新中文网站,敬请期待。
请问,最后那个打包好的文件,没有出现是为什么,前面都是按照步骤做的