我想在不使用xhtml的情况下在纯java中编写自定义jsf组件。
我使用Mojarra 2.2和Primefaces 5.1。
到目前为止。
import java.io.IOException;
import java.util.Date;
import javax.faces.component.FacesComponent;
import javax.faces.component.UIComponentBase;
import javax.faces.component.UINamingContainer;
import javax.faces.component.html.HtmlPanelGroup;
import javax.faces.context.FacesContext;
import javax.faces.event.FacesEvent;
import org.primefaces.behavior.ajax.AjaxBehavior;
import org.primefaces.component.autocomplete.AutoComplete;
import org.primefaces.component.commandbutton.CommandButton;
import org.primefaces.component.inputtext.InputText;
@FacesComponent(createTag = true, tagName = "picker", namespace = "http://jsdfdemo")
public class Picker extends UINamingContainer {
private String text;
public Picker() {
}
@Override
public void processRestoreState(FacesContext context, Object state) {
super.processRestoreState(context, state); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
if (!context.isPostback()) {
HtmlPanelGroup rootPanel = new HtmlPanelGroup();
rootPanel.setLayout("block");
rootPanel.setId("root_panel");
InputText autoComplete = new InputText();
autoComplete.setId("autocomplete");
autoComplete.setValue(this.text);
CommandButton clearButton = new CommandButton();
clearButton.setId("clear");
clearButton.setValue("Clear");
CommandButton pickButton = new CommandButton();
pickButton.setAjax(true);
pickButton.setUpdate("@form");
pickButton.setId("pick");
pickButton.setValue("Pick");
AjaxBehavior pickClickBehavior = new AjaxBehavior();
pickClickBehavior.setUpdate(autoComplete.getId());
pickClickBehavior.setProcess("@this");
pickButton.addClientBehavior(pickButton.getDefaultEventName(), pickClickBehavior);
rootPanel.getChildren().add(autoComplete);
rootPanel.getChildren().add(clearButton);
rootPanel.getChildren().add(pickButton);
this.getChildren().add(rootPanel);
}
super.encodeBegin(context); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void decode(FacesContext context) {
super.decode(context); //To change body of generated methods, choose Tools | Templates.
}
@Override
public void queueEvent(FacesEvent event) {
super.queueEvent(event);
if (event.getComponent().equals(this.getPickButton())) {
this.getAutoComplete().setValue(new Date());
}
}
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
public HtmlPanelGroup getRootPanel() {
return (HtmlPanelGroup) this.findComponent("root");
}
public InputText getAutoComplete() {
return (InputText) this.findComponent("autocomplete");
}
public CommandButton getClearButton() {
return (CommandButton) this.findComponent("clear");
}
public CommandButton getPickButton() {
return (CommandButton) this.findComponent("pick");
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
我希望选择按钮更改autoComplete的值(实际上是一个InputText)。我在自定义组件的queueEvent
方法中执行此操作。我不知道这是否适合这样做。
我也不确定encodeBegin
是构建组件树的正确位置。 if(!context.isPostback())
确保组件仅在初始GET上创建一次,但不能用于回发请求。
这是呈现给客户的内容。
<div id="j_idt43:j_idt44:root_panel">
<input id="j_idt43:j_idt44:autocomplete"
name="j_idt43:j_idt44:autocomplete"
type="text"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all"
role="textbox"
aria-disabled="false"
aria-readonly="false">
<button id="j_idt43:j_idt44:clear"
name="j_idt43:j_idt44:clear"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
onclick="PrimeFaces.ab({s:'j_idt43:j_idt44:clear'});return false;"
type="submit"
role="button"
aria-disabled="false">
<span class="ui-button-text ui-c">Clear</span>
</button>
<button id="j_idt43:j_idt44:pick"
name="j_idt43:j_idt44:pick"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
onclick="PrimeFaces.bcn(this,event,[function(event){PrimeFaces.ab({s:'j_idt43:j_idt44:pick',e:'click',p:'j_idt43:j_idt44:pick',u:'j_idt43:j_idt44:autocomplete'});},function(event){PrimeFaces.ab({s:'j_idt43:j_idt44:pick',u:'j_idt43'});return false;}]);"
type="submit"
role="button"
aria-disabled="false">
<span class="ui-button-text ui-c">Pick</span>
</button>
</div>
这里的问题是,单击选择按钮时会触发两个AJAX请求,尽管只注册了一个AjaxBehavior
。第一个表现得像预期的那样。视图已更新,我可以在输入文本组件中看到当前日期。但随后会触发第二个AJAX请求(在第一个完成之后)并清除输入文本。
第一个请求的参数是。
javax.faces.partial.ajax:true
javax.faces.source:j_idt43:j_idt44:pick
javax.faces.partial.execute:j_idt43:j_idt44:pick
javax.faces.partial.render:j_idt43:j_idt44:autocomplete
javax.faces.behavior.event:click
javax.faces.partial.event:click
j_idt43:j_idt43
j_idt43:j_idt44:autocomplete:
javax.faces.ViewState:3283049963151483162:-8986718217282610712
第二个是。
javax.faces.partial.ajax:true
javax.faces.source:j_idt43:j_idt44:pick
javax.faces.partial.execute:@all
javax.faces.partial.render:j_idt43
j_idt43:j_idt44:pick:j_idt43:j_idt44:pick
j_idt43:j_idt43
j_idt43:j_idt44:autocomplete:Mon Jan 25 11:17:05 CET 2016
javax.faces.ViewState:3283049963151483162:-8986718217282610712
有什么建议吗?