2017-01-26 52 views
1

用在我的引導支持Web應用程序的iNotesCalendar視圖提供了一個不那麼吸引人的日曆(見下文)的XPages引導啓用日曆

enter image description here

有沒有辦法來包裝日曆周圍的一些引導的造型?我在XPages4Bootstrap或Bootstrap頁面找不到關於引導程序日曆的任何信息。

+2

我不會使用的iCalendar的事情。我會使用類似https://fullcalendar.io/我沒有做過它自己,但Declan在公司做了,它在XPages中運行良好。 –

+0

這聽起來像個好主意。我已經開始考慮了。謝謝大衛。 –

+1

@BryanSchmiedeler,無恥的插件,但我已經博客了,http://elstarit.nl/2015/08/27/quick-xpages-tip-add-fullcalendar-plugin-to-your-application/ –

回答

0

正如埃裏克建議我要回答我自己的問題。一個非常好的起點是Frank's excellent post

我會發布很多代碼和儘可能多的解釋。

首先,您需要獲取文件並將它們添加到NSF的WebContent文件夾中,您可以在Package Explorer中找到它。我創建了一個名爲「FullCalendar」的子文件夾來保持有序。

enter image description here

創建日曆自定義控件。 [代碼爲這個在這個條目的底部。]

在我的自定義控件幾件事情,我不得不添加到弗蘭克的解釋,即是特定的,以我的環境中 - 他們可能是你的也是如此。

首先,請注意,我將xsp.resources.aggregate屬性設置爲「true」,它將覆蓋false的數據庫設置。我不記得我爲什麼必須這樣做,但是我的日程表沒有工作,除非我做到了。

注意:我找到了code and the reason in this post

接下來,我添加了三個與FullCalendar相關的資源(第四個是一些常見的佈局CSS)。這裏的排序非常重要。 jQuery必須在之前加載moment.min.js,它必須在fullcalendar.min.js之前加載。雖然沒有看到jQuery嗎? jQuery已經加載到我的主題中,不想再次加載它。

注意,使用head標籤和屬性加載一些陌生的語法。我發佈了一個關於使用Bootstrap with Full Calendar的問題。長話短說,您還必須解決AMD問題(請參閱帖子),並加載資源,因爲我一直在努力實現這一目標,儘管我想我錯了!

按鈕等有一些標準類型的代碼,以及div容器。真正的工作在腳本塊中,重要的部分是調用其餘的服務。我試圖讓這個標準相當 - 我總是把剩餘的元素放在名爲XpRest.xsp的設計元素中,然後在每個元素上放置一個特定的名稱,這個元素是CalendarEvents。

這個剩餘的服務元素調用一個Java 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; 
    } 

} 

此休息服務尚未完全完成,因爲我沒有抓住「結束」日期,也沒有抓住allDay元素,儘管我已經在報名表格中爲他們加入了鉤子。但我認爲這很容易添加到此代碼中。所以這裏

<?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> 

OK是針對ccCalendarView01代碼:

<?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>