支持Xpages引导的日历

支持Xpages引导的日历,xpages,Xpages,在启用引导功能的web应用程序中使用iNotesCalendar视图提供了一个不太吸引人的日历(见下文) 有没有一种方法可以在日历中包装一些引导样式?我在XPages4Bootstrap或bootstrap页面上找不到任何关于引导日历的信息。正如Eric所建议的,我将回答我自己的问题。一个很好的起点是 我会发布很多代码和尽可能多的解释 首先,您需要获取文件并将其添加到NSF的WebContent文件夹中,您可以在PackageExplorer中找到该文件夹。我制作了一个名为“FullCalen

在启用引导功能的web应用程序中使用iNotesCalendar视图提供了一个不太吸引人的日历(见下文)


有没有一种方法可以在日历中包装一些引导样式?我在XPages4Bootstrap或bootstrap页面上找不到任何关于引导日历的信息。

正如Eric所建议的,我将回答我自己的问题。一个很好的起点是

我会发布很多代码和尽可能多的解释

首先,您需要获取文件并将其添加到NSF的WebContent文件夹中,您可以在PackageExplorer中找到该文件夹。我制作了一个名为“FullCalendar”的子文件夹来保持事情的有序

为日历创建自定义控件。[此条目底部的代码。]

在我的自定义控件中,有一些东西我必须添加到Frank的解释中,这些东西对于我的环境是特定的——它们可能也适用于您的环境

首先,请注意,我将xsp.resources.aggregate属性设置为“true”,这将覆盖数据库设置false。我不记得为什么我必须这样做,但除非我这样做,否则我的日历就不起作用了

注意:我找到了

接下来,我添加了三个资源,3个与FullCalendar相关的资源(第四个是一些常见的css布局)。这里的订货很重要。jQuery必须在矩.min.js之前加载,矩.min.js必须在fullcalendar.min.js之前加载。但是没有看到jQuery吗?jQuery已加载到我的主题中,不想再次加载它

请注意,使用head标记和属性加载了一些不熟悉的语法。我发布了一个关于使用的问题。长话短说,您还必须修复AMD问题(请参阅文章),并像我那样加载资源以使其正常工作,尽管我认为我做错了什么

按钮等有一些标准类型的代码,还有一个div容器。真正的工作在脚本块中,重要的部分是调用rest服务。我试图使这一点变得相当标准——我总是将rest元素放在一个名为XpRest.xsp的设计元素中,然后在每个元素上加上一个特定的名称,这个名称就是CalendarEvents

此rest服务元素调用java rest服务。rest服务扩展库设计元素的代码为:

<xe:restService
    id="restService2"
    pathInfo="calendarEvents"
    ignoreRequestParams="false"
    state="false"
    preventDojoStore="true">
    <xe:this.service>
        <xe:customRestService
            contentType="application/json"
            serviceBean="com.XXXX.rest.CalendarEvents">
        </xe:customRestService>
    </xe:this.service>
</xe:restService> 

这将调用一个java rest服务,其代码是

package com.XXXXX.rest;

import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.openntf.domino.Database;
import org.openntf.domino.Session;
import org.openntf.domino.View;
import org.openntf.domino.ViewEntry;
import org.openntf.domino.ViewNavigator;
import org.openntf.domino.utils.Factory;
import org.openntf.domino.DateTime;

import com.ibm.commons.util.io.json.JsonException;
import com.ibm.commons.util.io.json.util.JsonWriter;
import com.ibm.domino.services.ServiceException;
import com.ibm.domino.services.rest.RestServiceEngine;
import com.ibm.xsp.extlib.component.rest.CustomService;
import com.ibm.xsp.extlib.component.rest.CustomServiceBean;
import com.scoular.cache.CacheBean;

public class CalendarEvents extends CustomServiceBean {

    @SuppressWarnings("unused")
    private Database dataDB;

    @Override
    public void renderService(CustomService service, RestServiceEngine engine) throws ServiceException {

        try {

            HttpServletRequest request = engine.getHttpRequest();
            HttpServletResponse response = engine.getHttpResponse();

            response.setHeader("Content-Type", "application/json; charset=UTF-8");
            response.setContentType("application/json");
            response.setHeader("Cache-Control", "no-cache");
            response.setCharacterEncoding("utf-8");
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Max-Age", "86400");

            String method = request.getMethod();

            if (method.equals("GET")) {
                this.doGet(request, response);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, JsonException {

        try {

            Integer cnt = 0;

            ViewNavigator nav;
            View chgView;
            DateTime tmpDte;
            Date tmpDte2; 

            Database DB = this.getDataDB();

            chgView = DB.getView("(xpViewCalendar01)");

            nav = chgView.createViewNav();

            Writer out = response.getWriter();
            JsonWriter writer = new JsonWriter(out, false);
            writer.isCompact();

            writer.startArray();

            for (ViewEntry entry : nav) {
                //Vector<?> columnValues = entry.getColumnValues();

                cnt = cnt + 1;

                writer.startArrayItem();
                writer.startObject();

                //Event Title
                writer.startProperty("title");
                writer.outStringLiteral(String.valueOf(entry.getColumnValues().get(0)));
                writer.endProperty();

                //Change id
                writer.startProperty("id");
                writer.outStringLiteral(cnt.toString());
                writer.endProperty();

                //Start Date and Time
                writer.startProperty("start");
                tmpDte = (DateTime) entry.getColumnValues().get(4);
                tmpDte2 = tmpDte.toJavaDate();
                DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"); 
                String tmpStr = df.format(tmpDte2);
                writer.outStringLiteral(tmpStr);
                writer.endProperty();

                //End Date and Time (same as start)
                writer.startProperty("end");
                writer.outStringLiteral(tmpStr);
                writer.endProperty();

                writer.endObject();
                writer.endArrayItem();
            }

            writer.endArray();
            writer.flush();

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    public Database getDataDB() {
        Session session = Factory.getSession();
        Database DataDB  = session.getDatabase(CacheBean.get().getAppDataDBPath());
        return DataDB;
    }

    public void setDataDB(Database dataDB) {
        this.dataDB = dataDB;
    }

}
package com.XXXXX.rest;
导入java.io.IOException;
导入java.io.Writer;
导入java.util.Date;
导入java.text.DateFormat;
导入java.text.simpleDataFormat;
导入javax.servlet.http.HttpServletRequest;
导入javax.servlet.http.HttpServletResponse;
导入org.openntf.domino.Database;
导入org.openntf.domino.Session;
导入org.openntf.domino.View;
导入org.openntf.domino.ViewEntry;
导入org.openntf.domino.ViewNavigator;
导入org.openntf.domino.utils.Factory;
导入org.openntf.domino.DateTime;
导入com.ibm.commons.util.io.json.JsonException;
导入com.ibm.commons.util.io.json.util.JsonWriter;
导入com.ibm.domino.services.ServiceException;
导入com.ibm.domino.services.rest.RestServiceEngine;
导入com.ibm.xsp.extlib.component.rest.CustomService;
导入com.ibm.xsp.extlib.component.rest.CustomServiceBean;
导入com.scoular.cache.CacheBean;
公共类CalendarEvents扩展了CustomServiceBean{
@抑制警告(“未使用”)
专用数据库数据库;
@凌驾
public void renderService(CustomService服务、RestServiceEngine引擎)引发ServiceException{
试一试{
HttpServletRequest=engine.getHttpRequest();
HttpServletResponse=engine.getHttpResponse();
setHeader(“内容类型”,“应用程序/json;字符集=UTF-8”);
setContentType(“应用程序/json”);
setHeader(“缓存控制”、“无缓存”);
响应。setCharacterEncoding(“utf-8”);
addHeader(“访问控制允许来源”,“*”);
addHeader(“访问控制允许凭据”,“true”);
addHeader(“访问控制允许方法”、“获取、发布”);
addHeader(“访问控制允许头”,“内容类型”);
addHeader(“访问控制最大年龄”,“86400”);
String方法=request.getMethod();
if(method.equals(“GET”)){
这是doGet(请求、响应);
}
}捕获(例外e){
抛出新的运行时异常(e);
}
}
私有void doGet(HttpServletRequest,HttpServletResponse)抛出IOException,jsoneexception{
试一试{
整数cnt=0;
视图导航器导航;
查看chgView;
日期时间tmpDte;
日期tmpDte2;
Database DB=this.getDataDB();
chgView=DB.getView(“(xpViewCalendar01)”;
nav=chgView.createViewNav();
Writer out=response.getWriter();
JsonWriter=newjsonwriter(out,false);
writer.isCompact();
作者:startArray();
用于(视图条目:导航){
//Vector columnValues=entry.getColumnValues();
cnt=cnt+1;
writer.startArrayItem();
writer.startObject();
//活动名称
作者:startProperty(“标题”);
writer.outStringLiteral(String.valueOf(entry.getColumnValues().get(0));
writer.endProperty();
//更改id
编写者。startProperty(“id”);
writer.outStringLiteral(cnt.toString());
writer.endProperty();
//开始日期和时间
作者:startProperty(“开始”);
tmpDte=(DateTime)entry.getColumnValues().get(4);
tmpDte2=tmpDte.toJavaDate();
DateFormat df=新Simp
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex">

    <xp:this.properties>
        <xp:parameter name="xsp.resources.aggregate" value="true" />
    </xp:this.properties>

    <xp:this.resources>
        <xp:headTag tagName="script">
            <xp:this.attributes>
                <xp:parameter name="type" value="text/javascript" />
                <xp:parameter name="src"
                    value="FullCalendar/moment.min.js" />
            </xp:this.attributes>
        </xp:headTag>
        <xp:script src="FullCalendar/fullcalendar.min.js"
            clientSide="true">
        </xp:script>
        <xp:styleSheet href="FullCalendar/fullcalendar1.min.css"></xp:styleSheet>
        <xp:styleSheet href="/cc_CommonGrid.css"></xp:styleSheet>
    </xp:this.resources>

    <!--The Container-->
    <div class="container-fluid">

        <!--The Button Bar-->
        <div class="toolbar" style="width: 100% !important">
            <div class="row">
                <span style="margin-right:10px">
                    <button type="button" id="newDoc"
                        class="btn btn-primary">
                        Add Event
                    </button>
                </span>

                <span style="float: right">
                    <div class="input-group" style="width:300px">
                        <input type="text" id="searchInput"
                            class="form-control"
                            style="border-radius: 5px; border-bottom-right-radius:0px ;border-top-right-radius: 0px"
                            placeholder="Search for..." />
                    </div>
                </span>
            </div>

        </div>
        <!--The Button Bar-->
<!--The Grid-->
<div 
    id="div1"  
    class="row"
    style="margin-top:15px">

        <!--The Grid-->
        <xp:div 
            id="grid"
            style="background-color:rgb(255,255,255)"
            styleClass="cal">
        </xp:div>
        <!--The Grid-->
</div>
<!--The Grid-->

    </div>
    <!--The Container-->

    <xp:scriptBlock id="scriptBlock1">
        <xp:this.value><![CDATA[// Add Document
$('#newDoc').click(function(event){
    var url = "xpFormEvent.xsp";
    window.open(url,"_self");
});

$(document).ready(function() {

    //Get URL for web serice
    var b1 = "#{javascript:context.getUrl().getAddress().replace(view.getPageName(), '');}"
    var b2 = b1 + "/xpRest.xsp/calendarEvents";
    var calCon = $(".cal");
    calCon.fullCalendar({

    header: {
                left:   'prevYear,nextYear',
                center: 'title',
                right:  'today,month,prev,next'
    },

    eventSources: [
{
    url: b2
}
            ]

    });
})

]]></xp:this.value>
    </xp:scriptBlock>
</xp:view>
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
    xmlns:xe="http://www.ibm.com/xsp/coreex">

    <xp:this.properties>
        <xp:parameter name="xsp.resources.aggregate" value="true" />
    </xp:this.properties>

    <xp:this.resources>
        <xp:headTag tagName="script">
            <xp:this.attributes>
                <xp:parameter name="type" value="text/javascript" />
                <xp:parameter name="src"
                    value="FullCalendar/moment.min.js" />
            </xp:this.attributes>
        </xp:headTag>
        <xp:script src="FullCalendar/fullcalendar.min.js"
            clientSide="true">
        </xp:script>
        <xp:styleSheet href="FullCalendar/fullcalendar1.min.css"></xp:styleSheet>
        <xp:styleSheet href="/cc_CommonGrid.css"></xp:styleSheet>
    </xp:this.resources>

    <!--The Container-->
    <div class="container-fluid">

        <!--The Button Bar-->
        <div class="toolbar" style="width: 100% !important">
            <div class="row">
                <span style="margin-right:10px">
                    <button type="button" id="newDoc"
                        class="btn btn-primary">
                        Add Event
                    </button>
                </span>

                <span style="float: right">
                    <div class="input-group" style="width:300px">
                        <input type="text" id="searchInput"
                            class="form-control"
                            style="border-radius: 5px; border-bottom-right-radius:0px ;border-top-right-radius: 0px"
                            placeholder="Search for..." />
                    </div>
                </span>
            </div>

        </div>
        <!--The Button Bar-->
<!--The Grid-->
<div 
    id="div1"  
    class="row"
    style="margin-top:15px">

        <!--The Grid-->
        <xp:div 
            id="grid"
            style="background-color:rgb(255,255,255)"
            styleClass="cal">
        </xp:div>
        <!--The Grid-->
</div>
<!--The Grid-->

    </div>
    <!--The Container-->

    <xp:scriptBlock id="scriptBlock1">
        <xp:this.value><![CDATA[// Add Document
$('#newDoc').click(function(event){
    var url = "xpFormEvent.xsp";
    window.open(url,"_self");
});

$(document).ready(function() {

    //Get URL for web serice
    var b1 = "#{javascript:context.getUrl().getAddress().replace(view.getPageName(), '');}"
    var b2 = b1 + "/xpRest.xsp/calendarEvents";
    var calCon = $(".cal");
    calCon.fullCalendar({

    header: {
                left:   'prevYear,nextYear',
                center: 'title',
                right:  'today,month,prev,next'
    },

    eventSources: [
{
    url: b2
}
            ]

    });
})

]]></xp:this.value>
    </xp:scriptBlock>
</xp:view>