65. XPages自定义控件(三)高级搜索之三

RecordView控件的两个文件的完整代码在本文末尾给出。虽说完整,仅靠这两个文件,RecordView控件还不能正常工作,因为在这两个文件里还引用了其他自定义控件,调用了作为managed bean的starrow.xsp.App的方法,即使把这些代码也都全加上,仍然不是自足的,因为在starrow.xsp.App类里,又调用了其他辅助类的代码。所以这两个文件的代码不像笔者在以前很多文章中给出的代码一样可以直接使用,而仅仅是为了展示RecordView控件的全貌,起到参考作用。XPages自定义控件(三)高级搜索整个系列的三篇文章与其说是介绍一个可重用的控件,不如说是用一个实例解剖自定义控件,展示它的结构、创建和使用它涉及到的知识和技术以及用XPages实现多条件查询。无法给出一个通用的控件,除了前面提到的多条件查询的界面要据具体需求设计以外,还有两方面的原因。一是大家已经看到的一个自定义控件的功能除了控件本身的两个文件之外,还可能会依赖其他自定义控件,用到保存在其他设计元素里的服务器端JavaScript和Java代码,需要faces-config.xml配置文件里的managed bean的设置。这样的分散性,再加上自定义控件的名称本身并没有全局唯一性的保证,使得对像本文介绍的这样的自定义控件,很难做到像系统自带的控件那样轻松在不同应用程序里重用。第二个原因则和XPages技术本身跨浏览器的能力和稳定性有关。笔者在8.5.3的环境下开发出63. XPages自定义控件(三)高级搜索之一提到的员工考勤系统,在做浏览器测试的时候,发现在IE 9和Firefox下多条件查询界面都能正常工作,但是输入起始日期的两个日期框显示略有差别,为了使日期框与同一行的输入员工姓名的编辑框保持水平一致,笔者还在这两个控件上加了一些CSS属性。因为不能确保系统用户所用的IE版本,笔者又用IE 9自带的开发工具模拟IE 8、7和Quicks模式,结果十分令人失望。有的模式下日期框显示正常,有的显示不正常但能正常工作,有的两者皆不行。无奈笔者只能使用一个技巧,指示浏览器在可能的情况下采用最新的IE 9模式(在下面代码的页面的beforeRenderResponse事件里可见到这段SSJS),这样实际上也没有彻底解决问题。既然选择了基于组件的用户界面技术,保证控件可以跨浏览器是基本要求,可惜XPages在这一点上做得不算好,在8.5.1版本时,日期控件就不支持IE 8,需要使用同样的技巧让浏览器模拟IE 7的模式(http://www-10.lotus.com/ldd/ddwiki.nsf/dx/Date_Time_Picker_XPages_8.5.1_and_Internet_Explorer_8)。实际上如果用XPages Extension Library里的dojo的日期控件都不会有这样的问题。时间到了Lotus Domino 9,情况又有了更新,在Firefox和IE 7、8、9、Quicks模式和最新的IE 10下,日期控件都能正常工作了,除了在IE 7和新的IE 5 Quicks模式下显示依然不正常以外。这实际上就印证了笔者在61. 两种类型的web框架:基于请求的和基于组件的里的观点,基于组件的框架要保证控件能够跨浏览器并且在浏览器和自己的不断升级中保持住这一点,是很困难的。
RecordView.xsp:

<?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"
    xmlns:xp_1="http://www.ibm.com/xsp/coreex">
    <xp:this.beforeRenderResponse><![CDATA[#{javascript:if (context.getUserAgent().isIE()) {
  facesContext.getExternalContext().getResponse().setHeader("X-UA-Compatible", "IE=9");
}}]]></xp:this.beforeRenderResponse>
    <xp:panel rendered="${javascript:compositeData.showSearch}">
        Staff
        <xc:InputUser id="inputUser1"></xc:InputUser>
        From
        <xp:inputText id="inpFrom" style="auto; top:0px;">
            <xp:dateTimeHelper id="dateTimeHelper1"></xp:dateTimeHelper>
            <xp:this.converter>
                <xp:convertDateTime type="date"></xp:convertDateTime>
            </xp:this.converter>
        </xp:inputText>
        To
        <xp:inputText id="inpTo" style="auto; top:0px;">
            <xp:dateTimeHelper id="dateTimeHelper2"></xp:dateTimeHelper>
            <xp:this.converter>
                <xp:convertDateTime type="date"></xp:convertDateTime>
            </xp:this.converter>
        </xp:inputText>
        <xp:button value="Test" id="button2" rendered="false">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="complete">
                <xp:this.action><![CDATA[#{javascript:var inputUser1:com.ibm.xsp.component.UIIncludeComposite = getComponent("inputUser1");
requestScope.message=inputUser1.findComponent("Users").getValue();
}]]></xp:this.action>
            </xp:eventHandler>
        </xp:button>
        <xp:button value="Search" id="btnSearch">
            <xp:eventHandler event="onclick" action="#{app.search}"
                submit="true" refreshMode="complete">
            </xp:eventHandler>
        </xp:button>

        <xp:button value="Clear" id="button1">
            <xp:eventHandler event="onclick" action="#{app.clearSearch}"
                submit="true" refreshMode="complete">
            </xp:eventHandler>
        </xp:button>
        <xp:br></xp:br>
        <xc:Message>
            <xc:this.rendered><![CDATA[${javascript:app.isLocal() || session.getEffectiveUserName()=="CN=Starrow Pan/OU=SCRO/O=CITIGROUP";}]]></xc:this.rendered>
        </xc:Message>
    </xp:panel>
    <xp:panel rendered="${javascript:compositeData.showEdit}">

        <xp:button value="Refresh" id="button5">
            <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
                <xp:this.action><![CDATA[#{javascript:database.updateFTIndex(false);}]]></xp:this.action>
            </xp:eventHandler></xp:button><xp:button value="New" id="button3" rendered="true">
        <xp:eventHandler event="onclick" submit="false">
            <xp:this.script><![CDATA[window.open("record.xsp", "_blank");]]></xp:this.script>
        </xp:eventHandler></xp:button>
        <xp:button value="Delete" id="button4"><xp:eventHandler event="onclick" submit="true" refreshMode="complete">
    <xp:this.action>
        <xp:deleteSelectedDocuments view="viewPanel1"
            message="Are you sure to delete the selected records?">
        </xp:deleteSelectedDocuments>
    </xp:this.action></xp:eventHandler></xp:button>
        </xp:panel>
    <xp:viewPanel rows="20" id="viewPanel1" viewStyle="99%"
        pageName="/record.xsp">
        <xp:this.facets>
            <xp:pager partialRefresh="true" layout="Previous Group Next"
                xp:key="headerPager" id="pager1">
            </xp:pager>
            <xp:pager partialRefresh="true" layout="Previous Group Next"
                xp:key="footerPager" id="pager2">
            </xp:pager>
        </xp:this.facets>
        <xp:this.data>
            <xp:dominoView var="view1"
                viewName="${javascript:compositeData.notesView;}"
                search="#{javascript:compositeData.filter;}" sortOrder="descending"
                sortColumn="$8">
            </xp:dominoView>
        </xp:this.data>
        <xp:viewColumn id="viewColumn8" columnName="$8"
            showCheckbox="${javascript:compositeData.showEdit}">
            <xp:this.displayAs><![CDATA[${javascript:if (compositeData.showEdit) return "link";}]]></xp:this.displayAs>
            <xp:this.facets>
                <xp:viewColumnHeader xp:key="header"
                    id="viewColumnHeader8" value="Date">
                </xp:viewColumnHeader>
            </xp:this.facets>
            <xp:this.converter>
                <xp:convertDateTime type="date"></xp:convertDateTime>
            </xp:this.converter>
        </xp:viewColumn>
        <xp:viewColumn columnName="StaffName" id="viewColumn4">
            <xp:viewColumnHeader value="Staff Name"
                id="viewColumnHeader4">
            </xp:viewColumnHeader>
        </xp:viewColumn>
        <xp:viewColumn columnName="AccessTime" id="viewColumn1">
            <xp:this.converter>
                <xp:convertDateTime type="time"></xp:convertDateTime>
            </xp:this.converter>
            <xp:viewColumnHeader value="Access Time"
                id="viewColumnHeader1">
            </xp:viewColumnHeader>
        </xp:viewColumn>
        <xp:viewColumn id="viewColumn9" columnName="Type">
            <xp:this.facets>
                <xp:viewColumnHeader xp:key="header"
                    id="viewColumnHeader9" value="Type">
                </xp:viewColumnHeader>
            </xp:this.facets>
        </xp:viewColumn>
        <xp:viewColumn columnName="CardNo" id="viewColumn2"
            rendered="false">
            <xp:viewColumnHeader value="Card Number"
                id="viewColumnHeader2">
            </xp:viewColumnHeader>
        </xp:viewColumn>
        <xp:viewColumn columnName="StaffNo" id="viewColumn3"
            rendered="false">
            <xp:viewColumnHeader value="Staff Number"
                id="viewColumnHeader3">
            </xp:viewColumnHeader>
        </xp:viewColumn>
        <xp:viewColumn columnName="Department" id="viewColumn5">
            <xp:viewColumnHeader value="Department"
                id="viewColumnHeader5">
            </xp:viewColumnHeader>
        </xp:viewColumn>

        <xp:viewColumn columnName="Office" id="viewColumn7">
            <xp:viewColumnHeader value="Office"
                id="viewColumnHeader7">
            </xp:viewColumnHeader>
        </xp:viewColumn>
    </xp:viewPanel>
</xp:view>

RecordView.xsp-config:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
  <faces-config-extension>
    <namespace-uri>http://www.ibm.com/xsp/custom</namespace-uri>
    <default-prefix>xc</default-prefix>
  </faces-config-extension>
  <composite-component>
    <component-type>RecordView</component-type>
    <composite-name>RecordView</composite-name>
    <composite-file>/RecordView.xsp</composite-file>
    <composite-extension>
      <designer-extension>
        <in-palette>true</in-palette>
      </designer-extension>
    </composite-extension>
    <property>
      <property-name>filter</property-name>
      <property-class>string</property-class>
      <property-extension>
        <designer-extension>
          <default-value>${javascript:""}</default-value>
          <editor>com.ibm.std.String</editor>
        </designer-extension>
        <required>false</required>
      </property-extension>
    </property>
    <property>
      <property-name>notesView</property-name>
      <property-class>string</property-class>
      <display-name>NotesView</display-name>
      <property-extension>
        <designer-extension>
          <editor>com.ibm.xsp.extlib.designer.tooling.editor.ViewNameEditor</editor>
        </designer-extension>
      </property-extension>
    </property>
    <property>
      <property-name>showSearch</property-name>
      <property-class>boolean</property-class>
      <display-name>Show search function</display-name>
      <property-extension>
        <designer-extension>
          <editor>com.ibm.std.Boolean</editor>
          <default-value>true</default-value>
        </designer-extension>
      </property-extension>
    </property>
    <property>
      <property-name>showEdit</property-name>
      <property-class>boolean</property-class>
      <display-name/>
      <description>Determine whether to display the features for editing records.</description>
    </property>
    <property>
      <property-name>showLink</property-name>
      <property-class>boolean</property-class>
      <display-name>Show link</display-name>
      <property-extension>
        <designer-extension>
          <editor>com.ibm.std.Boolean</editor>
        </designer-extension>
      </property-extension>
    </property>
    <property>
      <property-name>showCheckbox</property-name>
      <property-class>boolean</property-class>
      <display-name>Show checkbox</display-name>
    </property>
  </composite-component>
</faces-config>

faces-config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<faces-config>
  <managed-bean>
    <managed-bean-name>app</managed-bean-name>
    <managed-bean-class>starrow.xsp.App
        </managed-bean-class>
    <managed-bean-scope>application</managed-bean-scope>
  </managed-bean>
  <!--AUTOGEN-START-BUILDER: Automatically generated by IBM Domino Designer. Do not modify.-->
  <!--AUTOGEN-END-BUILDER: End of automatically generated section-->
</faces-config>
原文地址:https://www.cnblogs.com/keanuyaoo/p/3423931.html