JSFs: commandLink as a parameter for outputFormat

为君一笑 提交于 2019-12-05 13:16:41

The h:outputFormat tag will (as far as I know) only use f:param children as parameters.

If the message was a link (instead of a h:commandLink), you could use HTML literals:

<h:outputFormat escape="false" 
    value="...seconds, please &lt;a href='etc..." />.

I would not recommend trying to emulate h:commandLink by doing this. It might be possible to find a richer version of h:commandLink in a third party library that does exactly what you want.

Just splitting the string into two is possible, but makes life difficult for translators and the quality of translation may suffer (especially if you're doing this a lot).

I'd look at using a custom function like this:

<f:loadBundle basename="i18n.I18n" var="bundle" />
<h:outputText value="#{i18n:fragment(bundle.scheduleUpdateLink, 0)}" />
<h:commandLink>
  <h:outputText value="#{bundle.update}" />
</h:commandLink>
<h:outputText value="#{i18n:fragment(bundle.scheduleUpdateLink, 1)}" />

The rendered output is of the form:

After waiting a few seconds, please <script type="text/javascript"><!--
    /*JavaScript elided*/
//-->
</script><a href="#"
      onclick="return oamSubmitForm('someClientId');">update</a> the page.

The function is backed by a static method that splits the string and returns the requested fragment:

public static String fragment(String string, int index) {
  // TODO: regex probably not complete; ask stackoverflow!
  // see http://java.sun.com/javase/6/docs/api/java/text/MessageFormat.html
  final String regex = "\\{\\d.*?\\}";
  String[] fragments = string.split(regex, index + 2);
  return fragments[index];
  // TODO: error handling
}

Depending on your view technology (Facelets or JSP), the function declaration is slightly different:


EDIT: based on more info

JSF takes a declarative approach to building interfaces. You want a dynamic UI with children ordered according to the order they appear in a translated string. These two things are at odds, but all is not lost.

There are a few ways to approach this.

  • Redesign the UI to use text above, input/control table below (the popular form approach). This is the simplest solution, but might not make your UI designer happy.
  • Use the binding attribute on a panel to create and programmatically order everything. This might mean a lot of repetitive code in your backing beans.
  • Write a reusable custom control which might look like this:

.

<ed:formatPane string="click {0} after filling in forename {1} and surname {2}">
   <h:commandLink value="#{bundle.linkMsg}" />
   <h:inputText value="#{bean.prop1}" />
   <h:inputText value="#{bean.prop2}" />
</ed:formatPane>

It is probably possible (and less work) to just replace the renderer for h:outputFormat to support arbitrary children instead of creating a full custom control, but I'd argue against it because it may lead to confusion during long-term maintenance.

Someone may have already written a custom control that does what I suggest (it can hardly be an original idea).

In order for plain texts to be rendered correctly by JSF, it must be generated by <html:outputText ... > (there is some obscure technical reason). I would do this with an outputText, a commandLink and an outputText.

In general, when dealing with JSF everything must be a tag, no plain text.

A handy reference: http://exadel.com/tutorial/jsf/jsftags-guide.html

Chris Dale

To solve your problem you can use the <h:outputText> instead like Thorbjørn said.

Basicly your code and properties file become like this:

<h:outputText value="#{adminMsgs.scheduleUpdateLink1}" />
<h:commandLink value="#{adminMsgs.update}" action="refresh" />
<h:outputText value0"#{adminMsgs.scheduleUpdateLink2}" />

and the properties file like this:

scheduleUpdateLink1 = After waiting a few seconds, please
update = update
scheduleUpdateLink2 = the page.

Tbh I dont think outputFormat works with UiComponents, but only text.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!