XForms/儀表盤構建器
您希望一個表單可以佈局單個頁面儀表盤。在這種情況下,儀表盤由一組“Portlets”組成,每個 Portlet 都有獨立的內容。
我們的儀表盤構建器將控制一個儀表盤庫。每個儀表盤都有一個名稱、佈局資訊以及在儀表盤中呈現的一系列 Portlet。在我們的示例中,儀表盤最多可以包含 36 個 Portlet,但最佳實踐通常包含 7 個 Portlet,加上或減去一到兩個。
我們的儀表盤佈局將採用三種類型之一
- 行方向,其中同一行中的所有 Portlet 具有相同的高度
- 列方向,其中同一列中的所有 Portlet 共享相同的寬度
- 網格方向,其中所有 Portlet 必須包含在規則的網格結構中
該工具將允許使用者建立一個新儀表盤併為其命名。然後,使用者選擇三種佈局型別之一。每種佈局型別都允許使用者指定每行或每列的屬性,例如使用畫素的絕對寬度/高度或寬度/高度的相對高度/寬度百分比。請注意,為了允許儀表盤調整大小以適應不同的螢幕尺寸,應使用相對大小。
在每行、每列或每個網格中,使用者可以指定一組 Portlet,然後為每個 Portlet 指定一些引數。
當用戶儲存儀表盤時,它將儲存一個 XML 例項文件,其中包含儀表盤佈局的規範。可以使用 XQuery 或 XSLT 將此佈局轉換為 CSS 檔案,該檔案在每次顯示儀表盤時載入。
- 儀表盤佈局型別
-
行
-
列
-
網格
此表單僅應在選擇行佈局或網格佈局時顯示行高度規範。類似地,只有在選擇列布局或網格佈局時才會顯示列寬度。
以下程式碼提供了此邏輯。
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<title>Demonstration of relevant fields.</title>
<xf:model>
<xf:instance id="my-data" xmlns="">
<data>
<DashboardLayoutCode>row</DashboardLayoutCode>
</data>
</xf:instance>
<xf:instance id="views" xmlns="">
<data>
<row-info />
<col-info />
</data>
</xf:instance>
<xf:bind nodeset="instance('views')/row-info" relevant="instance('my-data')/DashboardLayoutCode!='col' " />
<xf:bind nodeset="instance('views')/col-info" relevant="instance('my-data')/DashboardLayoutCode!='row'" />
</xf:model>
<body>
<p>Demonstration of relevant fields. Grid layouts require both rows and columns to be specified.</p>
<xf:select1 ref="instance('my-data')/DashboardLayoutCode">
<xf:label>Enter Layout Type: </xf:label>
<xf:item>
<xf:label>Row</xf:label>
<xf:value>row</xf:value>
</xf:item>
<xf:item>
<xf:label>Col</xf:label>
<xf:value>col</xf:value>
</xf:item>
<xf:item>
<xf:label>Grid</xf:label>
<xf:value>grid</xf:value>
</xf:item>
</xf:select1>
<br />
<xf:group ref="instance('views')/row-info">
<h1>Row</h1>
</xf:group>
<xf:group ref="instance('views')/col-info">
<h1>Col</h1>
</xf:group>
</body>
</html>
注意:正在開發中!
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Form Title</title>
<style type="text/css">
@namespace xf url("http://www.w3.org/2002/xforms");
body {font-family:Helvetica, sans-serif;}
/* This line ensures all the separate input controls appear on their own lines */
xf|input, xf|select, xf|select1, xf|textarea {display:block; margin:5px 0;}
/* Makes the labels right aligned in a 170px wide column that floats to the left of the input controls. */
xf|input > xf|label, xf|select > xf|label, xf|select1 > xf|label, xf|textarea > xf|label, xf|output > xf|label
{text-align:right; padding-right:10px; width:170px; float:left; text-align:right; font-weight: bold;}
.DashboardDescriptionText textarea {
width: 400px;
height: 8em;
font-family:Helvetica, sans-serif;
}
/* anything marked as a cell is inside a table */
.cell * {display: inline; padding: 1px 1px;}
/* set to column widths in the portlet table */
.PortletID {width: 10px;}
.PortletRow {width: 10px;}
.RowPlacement {width: 10px;}
.PortletHeight {width: 10px;}
.PortletWidth {width: 10px;}
</style>
<xf:model>
<xf:instance id="my-dash" xmlns="">
<DashboardDocument>
<DashboardID>123</DashboardID>
<DashboardName>Sample Dashboard</DashboardName>
<DashboardDescriptionText>A full description of the </DashboardDescriptionText>
<DashboardKeywords>test, example, sample</DashboardKeywords>
<DashboardLayoutCode>row</DashboardLayoutCode>
<DashboardRowCount>3</DashboardRowCount>
<DashboardColumnCount>4</DashboardColumnCount>
<Rows>
<Row>
<RowHeight>20%</RowHeight>
</Row>
<Row>
<RowHeight>50%</RowHeight>
</Row>
<Row>
<RowHeight>30%</RowHeight>
</Row>
</Rows>
<Portlets>
<Portlet>
<PortletID>1</PortletID>
<PortletName>Portlet1</PortletName>
<RowPlacement>1</RowPlacement>
<PortletWidth>25%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>2</PortletID>
<PortletName>Portlet2</PortletName>
<RowPlacement>1</RowPlacement>
<PortletWidth>25%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>3</PortletID>
<PortletName>Portlet3</PortletName>
<RowPlacement>1</RowPlacement>
<PortletWidth>25%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>4</PortletID>
<PortletName>Portlet4</PortletName>
<RowPlacement>1</RowPlacement>
<PortletWidth>25%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>5</PortletID>
<PortletName>Portlet5</PortletName>
<RowPlacement>2</RowPlacement>
<PortletWidth>33%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>6</PortletID>
<PortletName>Portlet3</PortletName>
<RowPlacement>2</RowPlacement>
<PortletWidth>33%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>7</PortletID>
<PortletName>Portlet3</PortletName>
<RowPlacement>2</RowPlacement>
<PortletWidth>33%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>8</PortletID>
<PortletName>Portlet3</PortletName>
<RowPlacement>3</RowPlacement>
<PortletWidth>33%</PortletWidth>
<PortletHeight />
</Portlet>
<Portlet>
<PortletID>9</PortletID>
<PortletName>Portlet3</PortletName>
<RowPlacement>3</RowPlacement>
<PortletWidth>33%</PortletWidth>
<PortletHeight />
</Portlet>
</Portlets>
</DashboardDocument>
</xf:instance>
<!-- used to select the number of rows and columns -->
<xf:instance id="layout-items" xmlns="">
<data>
<item>1</item>
<item>2</item>
<item>3</item>
<item>4</item>
<item>5</item>
<item>6</item>
</data>
</xf:instance>
<!-- named views that are conditionally relevent based on the rules -->
<xf:instance id="views" xmlns="">
<data>
<row-view />
<col-view />
</data>
</xf:instance>
<!-- the rules on how to display the views -->
<!-- if we have a row or grid oriented display get the number of rows -->
<xf:bind id="row-view" nodeset="instance('views')/row-view" relevant="instance('my-dash')/DashboardLayoutCode='row' | instance('my-dash')/DashboardLayoutCode='grid'" />
<!-- if we have a column or grid oriented display get the number of columns -->
<xf:bind id="col-view" nodeset="instance('views')/col-view" relevant="instance('my-dash')/DashboardLayoutCode='col' | instance('my-dash')/DashboardLayoutCode='grid'" />
</xf:model>
</head>
<body>
<xf:output ref="DashboardID">
<xf:label>Dashboard ID:</xf:label>
</xf:output>
<xf:input ref="DashboardName">
<xf:label>Dashboard Name</xf:label>
<xf:hint>A short name under 50 characters.</xf:hint>
</xf:input>
<xf:textarea ref="DashboardDescriptionText" class="DashboardDescriptionText">
<xf:label>Description:</xf:label>
<xf:hint>Full description text. Used for searching for dashboards.</xf:hint>
</xf:textarea>
<xf:input ref="DashboardKeywords">
<xf:label>Keywords:</xf:label>
<xf:hint>Use comma to separate keywords.</xf:hint>
</xf:input>
<xf:select1 ref="DashboardLayoutCode">
<xf:label>Layout Style:</xf:label>
<xf:item>
<xf:label>Row</xf:label>
<xf:value>row</xf:value>
</xf:item>
<xf:item>
<xf:label>Column</xf:label>
<xf:value>col</xf:value>
</xf:item>
<xf:item>
<xf:label>Grid</xf:label>
<xf:value>grid</xf:value>
</xf:item>
</xf:select1>
<xf:group ref="instance('views')/row-view">
<xf:group ref="instance('my-dash')">
<xf:select1 ref="DashboardRowCount">
<xf:label>Number of Rows: </xf:label>
<xf:itemset nodeset="instance('layout-items')/item">
<xf:item>
<xf:label ref="." />
<xf:value ref="." />
</xf:item>
</xf:itemset>
</xf:select1>
</xf:group>
</xf:group>
<xf:group ref="instance('views')/col-view">
<xf:group ref="instance('my-dash')">
<xf:select1 ref="DashboardColumnCount">
<xf:label>Number of Columns: </xf:label>
<xf:itemset nodeset="instance('layout-items')/item">
<xf:item>
<xf:label ref="." />
<xf:value ref="." />
</xf:item>
</xf:itemset>
</xf:select1>
</xf:group>
</xf:group>
<table>
<thead>
<tr>
<th class="cell PortletID">ID</th>
<th class="cell PortletName">Name</th>
<th class="cell RowPlacement">Placement</th>
<th class="cell PortletHeight">Height</th>
<th class="cell PortletWidth">Width</th>
</tr>
</thead>
</table>
<xf:repeat nodeset="instance('my-dash')/Portlets/Portlet">
<span class="cell PortletID">
<xf:input ref="PortletID"/>
</span>
<span class="cell PortletName">
<xf:input ref="PortletName"/>
</span>
<span class="cell RowPlacement">
<xf:input ref="RowPlacement"/>
</span>
<span class="cell PortletHeight">
<xf:input ref="PortletHeight"/>
</span>
<span class="cell PortletWidth">
<xf:input ref="PortletWidth"/>
</span>
</xf:repeat>
</body>
</html>
儀表盤是 Web 門戶中常見的特性。為了實現互操作性,每個 Portlet 的內容可以透過在 JSR-168 規範中指定的 CSS 標籤來指定。JSR-168 旨在與 OASIS 遠端 Portlet 的 Web 服務 標準保持一致。
要了解建立 Portlet 的人機工程學最佳實踐,請參閱 Stephen Few 的優秀著作 資訊儀表盤設計。有關使用哪些指標的優秀參考資料,請參閱 Wayne W. Erickson 的著作 效能儀表盤。Richardson 等人的著作 使用開源工具進行門戶開發 中也討論了門戶標準。