Eug*_*vas 2 java primefaces jsf-2
我们开始使用PrimeFaces 3.4,JSF 2.0和Tomcat 7.0进行开发.我们面临的问题是,当我们制作表单页面时,我们可以使用所有PrimeFaces输入组件上的选项卡按钮进行导航<p:selectBooleanButton>.例如,
<h:form id="formId">
<p:inputText id="inputId1" />
<p:inputText id="inputId2" />
<p:selectBooleanButton id="buttonId" onLabel="Yes" offLabel="No" />
<p:inputText id="inputId3" />
<p:inputText id="inputId4" />
</h:form>
Run Code Online (Sandbox Code Playgroud)
按下选项卡inputId2直接进入inputId3.这是预期的行为吗?有没有解决方法?
这是因为<p:selectBooleanButton>PrimeFaces实际呈现了表示状态的复选框的方式SelectBooleanButtonRenderer:
<div id="formId:buttonId" type="button" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only">
<input id="formId:buttonId_input" name="formId:buttonId_input" type="checkbox" class="ui-helper-hidden">
<span class="ui-button-text">no</span>
</div>
Run Code Online (Sandbox Code Playgroud)
该复选框完全被类中的CSS display:none属性隐藏,.ui-helper-hidden因此永远不会获得焦点.
如果我们看一下对应的复选框<p:selectBooleanCheckbox>,这也是由视觉上更吸引人的部件取代了复选框是实际上可成为焦点,那么我们看到的复选框没有完全被隐藏CSS,只是不可见的被包裹在一个<div>这是绝对由CSS定位position:absolute在.ui-helper-hidden-accessible类中,因此只是被复选框小部件覆盖:
<div id="formId:checkboxId" class="ui-chkbox ui-widget">
<div class="ui-helper-hidden-accessible">
<input id="formId:checkboxId_input" name="formId:checkboxId_input" type="checkbox">
</div>
<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
<span class="ui-chkbox-icon"></span>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
我不会认为这<p:selectBooleanButton>是不可聚焦的"预期"或"直觉"行为,如果我是你,我肯定会向PrimeFaces 报告这个用户体验问题.
同时,你最好的解决方法是创建一个自定义渲染器,它覆盖encodeMarkup()PrimeFaces 的方法,SelectBooleanButtonRenderer如下所示,以便class="ui-helper-hidden"从复选框中删除它并将其包装在一个中<div class="ui-helper-hidden-accessible>,完全如下<p:selectBooleanCheckbox>:
public class MySelectBooleanButtonRenderer extends SelectBooleanButtonRenderer {
@Override
protected void encodeMarkup(FacesContext context, SelectBooleanButton button) throws IOException {
ResponseWriter writer = context.getResponseWriter();
String clientId = button.getClientId(context);
boolean checked = Boolean.valueOf(ComponentUtils.getValueToRender(context, button));
boolean disabled = button.isDisabled();
String inputId = clientId + "_input";
String label = checked ? button.getOnLabel() : button.getOffLabel();
String icon = checked ? button.getOnIcon() : button.getOffIcon();
//button
writer.startElement("div", null);
writer.writeAttribute("id", clientId, "id");
writer.writeAttribute("type", "button", null);
writer.writeAttribute("class", button.resolveStyleClass(checked, disabled), null);
if(disabled) writer.writeAttribute("disabled", "disabled", null);
if(button.getTitle()!= null) writer.writeAttribute("title", button.getTitle(), null);
if(button.getStyle() != null) writer.writeAttribute("style", button.getStyle(), "style");
//input
writer.startElement("div", null); // <-- Added.
writer.writeAttribute("class", "ui-helper-hidden-accessible", null); // <-- Added.
writer.startElement("input", null);
writer.writeAttribute("id", inputId, "id");
writer.writeAttribute("name", inputId, null);
writer.writeAttribute("type", "checkbox", null);
// writer.writeAttribute("class", "ui-helper-hidden", null); <-- Removed.
if(checked) writer.writeAttribute("checked", "checked", null);
if(disabled) writer.writeAttribute("disabled", "disabled", null);
if(button.getOnchange() != null) writer.writeAttribute("onchange", button.getOnchange(), null);
writer.endElement("input");
writer.endElement("div"); // <-- Added.
//icon
if(icon != null) {
writer.startElement("span", null);
writer.writeAttribute("class", HTML.BUTTON_LEFT_ICON_CLASS + " " + icon, null);
writer.endElement("span");
}
//label
writer.startElement("span", null);
writer.writeAttribute("class", HTML.BUTTON_TEXT_CLASS, null);
writer.writeText(label, "value");
writer.endElement("span");
writer.endElement("div");
}
}
Run Code Online (Sandbox Code Playgroud)
(看看这个//input部分,我添加了<--注释来解释我添加/删除了哪些行已经被复制的原始源代码)
要使其运行,请按以下方式注册faces-config.xml:
<render-kit>
<renderer>
<component-family>org.primefaces.component</component-family>
<renderer-type>org.primefaces.component.SelectBooleanButtonRenderer</renderer-type>
<renderer-class>com.example.MySelectBooleanButtonRenderer</renderer-class>
</renderer>
</render-kit>
Run Code Online (Sandbox Code Playgroud)
(component-family和renderer-type值从SelectBooleanButton组件中提取)
这对我有用,嗯,有点.在<p:selectBooleanButton>获得焦点,您可以使用空格键切换布尔状态.但是,焦点在任何方面都不会在视觉上可见.这需要在JavaScript方面解决.该<div class="ui-button">代表按钮应该得到一个.ui-state-focus类时隐藏复选框获得焦点.以下jQuery实现了:
$(".ui-button input[type=checkbox]").focus(function() {
$(this).closest(".ui-button").addClass("ui-state-focus");
}).blur(function() {
$(this).closest(".ui-button").removeClass("ui-state-focus");
});
Run Code Online (Sandbox Code Playgroud)
在真正的PrimeFaces源代码中,这应该根据文件init()的PrimeFaces.widget.SelectBooleanButton功能来解决forms.js.
| 归档时间: |
|
| 查看次数: |
1908 次 |
| 最近记录: |