下面将详细介绍一个标准JSF组件的制作过程,其中选用了DOJO的部分JS小部件,例如GRID。其中传递数据的方式采用了JSON格式。
1. AJAX用户界面组件
DirectorySearch_DojoImp.java
package component; import javax.faces.component.UIInput; import javax.faces.component.ValueHolder; public class DirectorySearch_DojoImp extends UIInput implements ValueHolder { @Override public String getFamily() { return "DirectoryFamily"; } }
这里没有在组件内部渲染用户界面而是采用了在Renderer中渲染。
DirectorySearchRenderer.java
package renderer; import java.io.IOException; import javax.faces.component.UIComponent; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import javax.faces.render.Renderer; import phaselistener.DataProviderPhListener; /** * * @author Administrator */ public class DirectorySearchRenderer extends Renderer { public DirectorySearchRenderer() { } @Override public void encodeBegin(FacesContext context, UIComponent component) throws IOException { String clientId = component.getClientId(context); renderStyle(context, component); //渲染AJAX脚本 encodeAjaxJavascript(context, clientId + ":grid", component); //encodeInputField用来渲染核心用户界面元素. encodeInputField(context, clientId, component); } public void renderStyle(FacesContext context, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); writer.write("\n"); writer.startElement("style", component); writer.writeAttribute("type", "text/css", null); writer.write("\n"); writer.write("@import '../js/MyDojo/dojo/grid/_grid/Grid.css';\n"); writer.write("@import '../js/MyDojo/dojo/themes/tundra/tundra.css'';\n"); writer.endElement("style"); writer.write("\n"); } public void encodeInputField(FacesContext context, String clientId, UIComponent component) throws IOException { // render a standard HTML input field ResponseWriter writer = context.getResponseWriter(); writer.write("\n"); writer.startElement("p", component); writer.startElement("input", component); writer.writeAttribute("type", "text", null); writer.writeAttribute("id", clientId, "clientId"); writer.writeAttribute("size", "20", null); writer.writeAttribute("onkeyup", "lookup('" + clientId + "');", null); writer.endElement("input"); writer.endElement("p"); //同时在渲染一个DIV.<div id = "searchField:table"></div> 此div为table的插入位置 // writer.startElement("div", this); // writer.writeAttribute("id", clientId + ":table", null); // writer.endElement("div"); //<div id="commentww" dojotype="dijit.layout.ContentPane" style="width: 600px; height: 300px; // padding: 0px; font-size:12px;"> //</div> writer.startElement("div", component); writer.writeAttribute("id", clientId + ":grid", null); writer.writeAttribute("dojotype", "dijit.layout.ContentPane", null); writer.writeAttribute("style", "width: 600px; height: 300px; padding: 0px; font-size:12px;", null); writer.endElement("div"); } public void encodeAjaxJavascript(FacesContext context, String clientId, UIComponent component) throws IOException { ResponseWriter writer = context.getResponseWriter(); ExternalContext extContext = context.getExternalContext(); // render Ajax enabled Javascript only once if (!extContext.getRequestMap().containsKey("ajaxflag.ajaxScript")) { extContext.getRequestMap().put("ajaxflag.ajaxScript", Boolean.TRUE); writer.startElement("script", component); writer.writeAttribute("type", "text/javascript", null); writer.writeAttribute("src", DataProviderPhListener.RENDER_SCRIPT_VIEW_ID, null); writer.endElement("script"); writer.write("\n"); writer.startElement("script", component); writer.writeAttribute("type", "text/javascript", null); writer.writeAttribute("src", "../js/MyDojo/dojo/dojo.js", null); writer.endElement("script"); writer.write("\n"); writer.startElement("script", component); writer.writeAttribute("type", "text/javascript", null); writer.writeAttribute("src", "../js/MyDojo/dojo/mydojo.js", null); writer.writeAttribute("djconfig", "isDebug:true, parseOnLoad:true, bindEncoding:'UTF-8', parseWidgets:false, searchIds:['" + clientId + "']", null); writer.endElement("script"); writer.write("\n"); } } }
以上渲染器中并没有使用完整版的DOJO而是用DOJO的工具类实现了自定义的Mydojo。至于如何实现ingredients参考dojo-release-1.2.3-src\util\buildscripts下的build.bat
这里没有渲染JS脚本,而是把JS脚本放在独立文件中
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ function lookup(field) { writeloc = field + ":grid"; var searchField = document.getElementById(field); if(searchField.value!=''){ dojo.xhrGet({ url: 'directory.jsp', preventCache: true, load: renderGrid, error: callError, content: { ajaxreq: true, input: escape(searchField.value) } }); } } function callError(response, ioArgs) { alert('返回错误'); } function renderGrid(response,ioArgs) { comData=null; popStore=null; dataModel=null; layout=null; var isChild = dojo.byId(writeloc).childNodes.length; if(isChild > 0){ dojo.byId(writeloc).removeChild(grid.domNode); } var dataCom = response; if(dataCom !=null && dataCom != '') comData = dojo.fromJson(dataCom); else{ alert('dataCom is null !'); comData = null; } popStore = new dojo.data.ItemFileWriteStore({ data:comData }); dataModel = new dojox.grid.data.DojoData(null,null,{ store: popStore, rowsPerPage:'20', query:{ NAME : '*' }, sortFields:[{ attribute:0, descending:false }] }); layout = [ { type: 'dojox.GridRowView', width: '4px' }, { cells: [[{ name: 'NO', get: getRow, width: 3 }]], noscroll: true }, { cells: [[ { name: 'PERSONID', field: 4, width:8 }, { name: 'COMMENTER', field: 2, width:8 }, { name: '职务', field: 3, width:8 }, { name: 'LAST UPDATE', field: 0, width:8 } ]] } ]; var thisDate = new Date(); var randid = Math.floor(Math.random() * thisDate); var gridid = 'grid'+randid; grid = new dojox.Grid({ 'id': gridid, 'elasticView': 2, 'model': dataModel, 'structure': layout }); dojo.byId(writeloc).appendChild(grid.domNode); grid.render(); } function getRow(inRowIndex){ return ' ' + inRowIndex; }