OneUIを使ったXPageの作り方

ここで、OneUIを使った、基本的なXPageの作り方を説明してみよう。

こんな感じのページを作ってみようと思う。PCの管理台帳をイメージしたものだ。 文書の一覧をクリックすると、文書が開き、編集モードにして保存する、という感じ。

基本XPagesアプリ

基本としては、以下の流れになる。

ここで作ったサンプルAppはbasicApp.nsfからDL可能。

アプリケーションの作成

クラシカルNotesと同じく、まずはアプリケーションという器を作る。その中に、フォーム、ビュー、XPageを作っていく。 アプリケーションは[ファイル/新規/アプリケーション]メニューで作成する。

サーバを用意してないなら、アプリケーションはPC上に作成する。よって、サーバは「ローカル」になる。

アプリケーションの作成

アプリケーションを作成すると、以下のような「アプリケーションナビゲータ」が表示される。ここで、フォーム、ビュー、XPagesを作っていくわけだ。

アプリケーションナビゲータ

アクセス権の設定

DominoDesignerは設計したXPagesを処理できるWebサーバを内蔵している。後で設計したアプリケーションをWebブラウザからアクセスできるように、 アプリケーションのACLに"anonymous"を設定しておく。アクセス権は編集者以上にしておかないとエラーになる。

エラーの表示

XPagesで実行時エラーが起きた時に、どこでエラーが起きたかちゃんと表示されるようにしておく。

フォームの作成

XPagesの世界でも、フォームは使用するが、役割がだいぶ違う。

XPagesの世界では、フォームはデータを格納する文書内のフィールドを定義しているものでしかない。 フォームには見栄えの要素はまったく必要ないので、ずらずらとフィールドを並べていけばいい。

XPagesでは、フォームが「データソース」になる。「データソース」とは、データの格納先や参照先と思えばいい。 データソースに保存処理を行えば、文書がアプリケーション内に保存される。文書IDや検索などを使って、 文書を特定できたら、それがデータソースになり、フィールドからデータを取り出すことができる。 取り出したデータは、Webページ(XPage)に表示できる。

フィールドには役割が推測できるようないい名前をつけておこう。XPageのソースコードが読みやすくなる。 フィールド名に漢字を使ってもまったく問題ない。 また、フィールドのとなりには、フィールド名を見出しに書いておこう。後でNotesクライアントでデータをメンテナンスするときに、見出しがあると便利。

フォームの設計

ビューの作成

ビューは、XPagesの世界でも結構重要。XPage内にビューを組み込めるので、必要と思われるビューはあらかじめ用意しておこう。 また、リストボックスの選択肢なども、ビューから作れるので、キーワード用などのビューも用意しておく。

XPagesでは、ビューもデータソースになる。ビューはデータの入った表だと思えばよくて、データソースに検索処理を行って、必要な情報を得る。

また、ビューはXPageに組み込んで文書の一覧表示用に使える。文書の一覧をクリックすれば、その文書を開くといったこともできる。

ビューにも役割がわかるようないい名前をつけておこう。

フォームと同じく、ビューも見栄えは関係ない。大事なのは列の並びやソート順。これらはXPageにも引き継がれる。 第一列をカテゴリ別にして、省略表示可にしておけば、XPage上でも省略表示ができる。このあたりは必要に応じて組んでおこう。

ビューの設計

XPage画面のレイアウト

XPageの設計では、画面の構成がある程度決められていると思っていい。 それぞれの位置に名前がつけられていて、設計時に名前を指定することで、画面デザインがかなりカッコよくなる。

oneUIのレイアウト

名前からわかるとおり、Lotusが決めた名前。これがCSSのクラス名と一致している。 このレイアウトの規約を「oneUI」というらしい。こまごまとしたデザイン指定をやりたくない人はoneUIに従っておくと楽。

oneUIを使用できるようにする

「アプリケーションのテーマ」で"oneUI"を選ぶだけ。

テーマの定義場所

XPagesアプリケーションの基本構造

XPagesアプリケーションでは、文書であろうと文書一覧であろうと、XPageというページ単位で表示できる。ページの種類だけXPageを用意することになる。

ただ、どのページも、上側にロゴやメニューがあり、左脇にはメニュー、下側にはバナーが配置されるという基本構造がある。

つまりページによって異なる真ん中の部分をページごとに切り替えて、文書一覧、文書の表示などを行う。

テーマの定義場所

カスタムコントロールについて

こういうことを実現するために、基本構造を実現する「カスタムコントロール」を用意して、そこに表示するパーツを切り替えるようにする。

カスタムコントロールというのは、テキストボックスやラベルなど基本パーツをグルーピングしておく入れ物のようなもの。XPageや他のカスタムコントロールに組み込んで使うことができる。 1つのXPageの設計が複雑になってきたら、いくつかのカスタムコントロールに分解しておき、カスタムコントロールを並べるようにしてページを構成することができる。 まさにプログラミングの関数のように使える。

共通のカスタムコントロールは、バナーやメニューなどを配置しておき、真ん中にはめ込み領域を用意しておく。

各XPageには共通のカスタムコントロールを組み込んでおき、はめ込み領域に、ビューや文書表示を行うカスタムコントロールを関数の引数のように指定する。

カスタムコントロールの設計

カスタムコントロールにもいい名前をつけよう。今回はこんな名前のカスタムコントロールを用意する。

カスタムコントロールのレイアウト

カスタムコントロールの作り方

アプリケーションナビゲータの「カスタムコントロール」を開き、[新規カスタムコントロール]を選ぶ。 その後でカスタムコントロールの名前を入れて、カスタムコントロールの設計開始。

カスタムコントロールの新規作成

xcBanner

バナーとなるイメージは、あらかじめ用意しておく。リソース/イメージに登録しておけば、「イメージコントロール」の貼り付けで イメージファイルを選択できる。

リソースのイメージ

イメージコントロール貼り付け

イメージの選択

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
     <xp:image url="/logo.png" id="image2" ></xp:image>
  </xp:view>
  

oneUIの流儀では、これを以下のように書き換えるらしい(XPages Phonebbokからのパクリ)。これでxcBannerカスタムコントロールが、oneUIにおけるlotusBannerになる。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
      <div class="lotusBanner">
          <div class="lotusRightCorner">
              <div class="lotusInner">
                  <xp:image url="/logo.png" id="image2" ></xp:image>
              </div>
          </div>
      </div>
  </xp:view>
  

xcTitleBar

同じ要領で、タイトル部を作成。xcTitleBarというカスタムコントロールを新規作成し、ラベルコントロールを貼り付ける。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <xp:label value="XPages Base" id="label1"></xp:label>
  </xp:view>
  

これもoneUIの流儀にあわせると、こうなる。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
      <div class="lotusTitleBar">
          <div class="lotusRightCorner">
              <div class="lotusInner">
                  <h1>
                     <xp:text escape="true" id="mainTitle" value="XPages Base"></xp:text>
                  </h1>
              </div>
          </div>
      </div>
  </xp:view>    
  

xcFooter

連絡先や紹介しているWebページなどへのリンクを貼っておくxcFooterカスタムコントロールを作成する。。 企業Webページなら著作権表示など。

こんな表記になる。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
    <div id="lotusFooter">
      <xp:panel styleClass="lotusRightCorner">
        <xp:panel styleClass="lotusInner">
          <xp:span styleClass="lotusRight">
            Profuced by 
            <xp:link escape="true" text=" My Technical Notes" id="link1"
              value="http://tech-notes.org" title="TechNotes">
            </xp:link>
          </xp:span>
        </xp:panel>
      </xp:panel>
    </div>
  </xp:view>
  

xcMenu

ビューを切り替えたりするメニュー部となるxcMenuカスタムコントロールを作成。 まだリンク先は空だが。

いっぱい、クラスが指定されている。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
      <div class="lotusColLeft">
          <div class="lotusMenu">
              <div class="lotusBottomCorner">
                  <div class="lotusInner">
                      <div class="lotusMenuSection">
                          <h3>Select View</h3>
                      </div>
                      <div class="lotusMenuSubsection">
                          <ul>
                              <li>
                                  <xp:link escape="true" id="link1" text="管理部署別"></xp:link>
                                  <xp:link escape="true" id="link2" text="場所別"></xp:link>
                              </li>
                          </ul>
                      </div>
                  </div>
              </div>
          </div>
      </div>
  </xp:view>
  

xcLayout

共用部分を作る。これまでに作ったカスタムコントロールを束ねて、かつ、はめ込み領域を作る。 はめ込み領域のoneUIはコンテンツを示すlotusContnentを指定する。

<xp:callback>の部分に外で指定したコントロールが組み込まれる。組み込み位置を特定するためにfactNameを指定しておく。 「facetBodyで指定される領域にこのコントロールを」という形で指定する。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
      <div class="lotusFrame">
          <xc:xcBanner></xc:xcBanner>
          <xc:xcTitleBar></xc:xcTitleBar>
          <div class="lotusMain">
              <xc:xcMenu></xc:xcMenu>
              <div class="lotusContent">
                  <xp:callback facetName="facetBody" id="facetBody"></xp:callback>
              </div>
          </div>
          <xc:xcFooter></xc:xcFooter>
      </div>
  </xp:view>
  

xcView

文書の一覧を表示するビューを用意する。

カスタムコントロールを作り、「ビューコントロール」を貼り付ける。

ビューコントロールの組み込み

組み込むときに、以下のパネルが開くので、どのビューに紐付けるか指定する。 もちろん、従来のNotesのビューはあらかじめ作っておく(作り方は説明しない)。ビューの列の並びやソート順は引き継がれる。

ビューコントロール設定

他にも、以下の設定をしておく。

xcForm

文書表示用のカスタムコントロールを用意する。

とりあえず、Notesフォームの内容をそのまま貼り付けてみよう。

まずは、他のカスタムコントロールと同じく、xcFormという名前のカスタムコントロールを新規作成する。

次に「データソース」というものを定義する。画面に出すデータの元がデータソースである。

右のコントロールパレットで、「データ」タブを選び、「データソース」のコンボボックスで「データソースの定義...」を選ぶ。

データソースの定義

次にデータソースの種類を聞いてくる。今回は、文書を表示したいので、データソースの種類は「Domino文書」になる。

すぐにデータソースのプロパティ設定画面が開く。ここで大事なのは、どのフォームの文書を使うかということ。デフォルトアクションで文書を新規 作成にするのかどうかはあまり重要じゃないような気がする。

データソースのプロパティ設定

これを指定すると、コントロールパレットのデータソースの下に、フィールドの一覧が並ぶ。

データソースの定義

後はこれらをxcDocumentカスタムコントロールに貼り付けるだけである。表の形でフィールドがテキストボックスの形で貼り付けられる。

データソースの貼り付け

ソースコードはこんな感じになる。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core">
      <xp:this.data>
          <xp:dominoDocument var="document1" formName="main"></xp:dominoDocument>
      </xp:this.data>
      <xp:table>
          <xp:tr>
              <xp:td>
                  <xp:label value="From:" id="from_Label1" for="from1"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.from}" id="from1"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="管理番号:" id="管理番号_Label2" for="管理番号2"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.管理番号}" id="管理番号2"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="OS:" id="oS_Label2" for="OS1"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.OS}" id="OS1"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="備考:" id="備考_Label2" for="備考1"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.備考}" id="備考1"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="管理部署:" id="管理部署_Label2" for="管理部署2"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.管理部署}" id="管理部署2"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="ホスト名:" id="ホスト名_Label2" for="ホスト名2"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.ホスト名}" id="ホスト名2"></xp:inputText>
              </xp:td>
          </xp:tr>
          <xp:tr>
              <xp:td>
                  <xp:label value="管理者:" id="管理者_Label2" for="管理者2"></xp:label>
              </xp:td>
              <xp:td>
                  <xp:inputText value="#{document1.管理者}" id="管理者2"></xp:inputText>
              </xp:td>
          </xp:tr>
      </xp:table>
  </xp:view>
  

 

保存と編集のボタン追加

ついでに、保存と編集のボタンをつけておく。 文書にはクラシカルNotesと同じく、表示モードと編集モードの2種類がある。[編集]ボタンを押すと、編集モードに切り替わり、[保存]を押せば編集中の文書を 保存するようにしてみる。

xcFormカスタムコントロールを開き、ボタンを追加する。コントロールパレットのコアコントロールから「ボタン」を選び、貼り付ける。 ボタンのラベルを編集と保存に設定しておく。

後は、ボタンのonclickイベントに「編集モードにする」と「文書を保存」のシンプルアクションを設定すればいい。とりあえずは文書を保存しても、画面はそのままにしておく。

  <xp:button id="button1" value="編集">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
      <xp:this.action>
        <xp:changeDocumentMode mode="edit" var="document1"></xp:changeDocumentMode>
      </xp:this.action>
    </xp:eventHandler>
  </xp:button>
  <xp:button value="保存" id="button2">
    <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
      <xp:this.action>
        <xp:saveDocument var="document1"></xp:saveDocument>
      </xp:this.action>
    </xp:eventHandler>
  </xp:button>
  

文書表示用XPageを作る(form)

カスタムコントロールの用意ができたので、XPageを作る。

貼った直後のソースがこれ。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
      <xc:xcLayout>
          <xp:this.facets>
              <xc:xcForm xp:key="facetBody"></xc:xcForm>
          </xp:this.facets>
      </xc:xcLayout>
  </xp:view>
  

この状態で、こんな感じの画面が表示される。oneUIの設定はちょっと面倒だったけど、面倒なデザイン設定をしなくてもここまでの画面が出るのは驚きだ。

サンプルアプリの画面

ビュー用のXPageを作る

今度はビューを表示するXPageを作る。

ソースはこんな感じ。

  <?xml version="1.0" encoding="UTF-8"?>
  <xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
    <xc:xcLayout>
        <xp:this.facets>
            <xc:xcView xp:key="facetBody"></xc:xcView>
        </xp:this.facets>
    </xc:xcLayout>
  </xp:view>
  

これでこのように表示される。

サンプルアプリの画面

新規作成のボタンを表示するなら、こんな感じで。

  <xp:button value="新規作成" id="button1">
      <xp:eventHandler event="onclick" submit="true"
          refreshMode="complete">
          <xp:this.action>
              <xp:openPage name="/form.xsp" target="newDocument"></xp:openPage>
          </xp:this.action>
      </xp:eventHandler>
  </xp:button>
  

その他設定

他にもいくつか設定をしておく。

アプリケーション起動時に何を開くかの指定

アプリケーションのプロパティで起動時に何を開くかを指定。ここでは文書の一覧を表示する「viewByDate」を指定しておく 起動オプション

文書保存時の移動先の指定

文書表示用のxcFormの[保存ボタン]を押したとき、保存した後、ビューの画面に戻るようにしておく。

単に文書モードを編集モード→読み取りモードに変えて自文書を開く方法もあるが、それでは文書を開く時に動作させるイベント処理(postOpenDocument)が起動されないので注意。

シンプルアクションでも作れるが、以下のコードを組み込んでも動作する。

  document1.save();
  context.redirectToPage("view");
  

保存後、編集中のページをひらき直したいなら、以下のコードになる。

  document1.save();
  var unid = document1.getDocument().getUniversalID();
  var url = "/form.xsp?documentId=" + unid + "&action=openDocument";
  context.redirectToPage(url);
  

メニューの整備

メニューでビューを切り替えたり、文書の新規作成ができるようにする。cxMenuのリンク部分を以下のように書き換えればいい。

  <li>
    <xp:link escape="true" id="link1" text="日付別" value="/view.xsp"></xp:link>
    <xp:link escape="true" id="link2" text="新規作成"  value="/form.xsp"></xp:link>
  </li>