Cannot get itemDescription on f:selectItems to have an effect - jsf

The doc says:
"itemDescription: evaluates to a String that will serve as the description to be shown for the item."
http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/selectItems.html
http://docs.oracle.com/javaee/6/javaserverfaces/2.1/docs/vdldocs/facelets/f/selectItem.html
I'm not getting any title attribute added to the resulting option element in the DOM or anything, not even when setting a literal String as its value (neither on f:selectItem nor f:selectItems, each tried seperately, the latter with a c:forEach over the list items which showed up correctly with their labels).
Some forum posts seemed to suggest people use it for tooltips.
The doc isn't being entirely clear, is the itemDescription attribute on the component even meant to be rendered as a tooltip/title? And if not, what's it good for?

I think BalusC already answered it in https://stackoverflow.com/a/25512124/3280015, which I initially overlooked.
"While creating the custom renderer, you could make use of the unused(!) description property of the UISelectItem class."
So it is currently simply unused and left for potential use by developers. Maybe that's what the Doc means by:
"for use in development tools."

Related

How to know when a property has been updated from it's connected attribute?

Given:
#property({type: Boolean, attribute: 'some-attr'}) someAttr = false;
I was expecting to see updated being fired once 'some-attr' value gets updated in the DOM.
However, updated doesn't get fired at all.
Is my expectation wrong, or should I set things up differently?
Looking at Elm's discussion of properties vs attributes, the documentation of the Html.Attributes module's attribute function, and the Elm documentation on custom elements, I am pretty sure, that this is caused by simply binding an elm expression to attribute some-attr of the LitElement based custom element. I.e. the DOM attribute will always be present and hence the corresponding property always be true.
The default converter for Boolean (activated by providing type:Boolean to the decorator) mimicks the behaviour of HTML attributes used as flags (e.g. disabled on an <input> element): If the attribute is present (no matter the value), the flag is set (true). The implementation is really straight forward, if you want to look at it in the sources: https://github.com/Polymer/lit-element/blob/master/src/lib/updating-element.ts#L163
I see these options for your problem:
Implement some extra logic in Elm to add / remove the presence of the attribute.
Create your own attribute converter for the LitElement based custom element.
Use another default converter (e.g. for String, the "default" default converter) and implement the custom logic inside the LitElement (e.g. using a derived value).
Of these 3 options, I would generally recommend the first one, as your custom element then still behaves naturally, i.e. if some-attr should be a flag (boolean attribute), then following which HTML semantics, it should be defined by its presence, not its value. This allows you to re-use it in other projects without surprising other developers.
That being said, there may of course be project-specific requirements, that are more important. E.g. if you only use this custom element in this one project with Elm, your road to success may be faster going for options 2 or 3.

How exactly does p:panelGrid extends h:panelGrid

I'm using Primefaces and I know that p:panelGrid extends h:panelGrid as it's clearly stated in the documentation.
However I can't see the exact difference between them. What extra functionalities does p:panelGrid provide? In which cases should I prefer using the Primefaces version over the HTML Basic one?
Although p:panelGrid extends h:panelGrid, it actually lacks many of the attributes that h:panelGrid contains. Which ultimately got me confused.
I can't speak for PrimeFaces' actual intention (I'm no PrimeFaces developer), but based on my observations so far, I can only conclude that they omitted attributes which only invite bad practices in HTML perspective (mainly HTML-deprecated attributes — use CSS instead) or makes no sense otherwise (and are better at its place in a parent or child component). I can only say that it's a Good Thing.
Upon further inspection in the source code I can also confirm that it doesn't technically extend from <h:panelGrid> (HtmlPanelGrid class), but from the UIPanel superclass (which is also used by a.o. <h:panelGroup>). This design decision is most likely done to have more flexibility in the rendered output as shown in the showcase.
Generally, you should only prefer an enhanced component whenever you start to actually need the enhanced/new feature. This usually only happens once you figure out you actually need such one feature and discover that it is missing in the standard component. You'd then usually already know the keywords you're looking for and simply start exploring the component libraries using those keywords if they haven't already implemented it.

Primefaces autocomplete enter key behavior

when we type into autoComplete, primefaces automatically highlighted first shown item. so when we press enter key that item will be selected. how can i change the behavior of enter key, so when it pressed, just entered text be submitted in backing bean property.
I know we can hit ESC button then continue but but user don't like it.
I am using primefaces 5.0 & jsf 2.1.11
What helped me to solve the same issue where the answers here and here. Basically, you have to override 2 different behaviours.
First one is the default selection of the first result, that can be achieved adding this to your autocomplete (as stated by the accepted answer in the first link, available in primefaces for versions 5.1.5, 5.0.14 and 5.2):
autoHighlight="false"
The second thing you want to override is the behaviour when Enter is pressed, as you want the form that contains the autocomplete to be submitted. For doing so, just add this code to either the containing form or the autocomplete:
onkeyup="if (event.keyCode == 13) {
document.getElementById('[searchFormId]:[submitButtonId]').click();
return false; }"
Change the ids between square brackets for your own ones and it's done.
PS: I know this is a rather old question but it still applies to the current version of primefaces (6.1 when this question was answered). And I also think it can help to have both changes combined in one answer.
Truth be told, this feels like a bug. Richfaces do that implicitly (submit on enter while suggesting). I haven't found an official fix so I did some research and turns out the simplest way is to override the JS function that resolves key presses. The whole autocomplete js is here. You just need to override the bindKeyEvents function so you declare it likewise:
PrimeFaces.widget.AutoComplete.prototype.bindKeyEvents = function () {
Then add the rest of the code for this specific function from the JS I mentioned before. I've omitted that code so it's more readable. Then you want to find a switch that resolves different keys that have some behavior mapped to them. And under the code:
case keyCode.ENTER:
case keyCode.NUMPAD_ENTER:
Add something like:
if (highlightedItem.length == 0) {
document.getElementById("<your_form_id>").click();
_self.hide();
} else {
highlightedItem.click();
}
Also, make sure that you got forceSelection and the autohighlight off on the autocomplete component.
The problem in the JS is that even though you haven't selected any item from the suggestions it still triggers the event that tries to click the item... which doesn't even exist.
This is the simplest way as I said... you can also create your own autocomplete implementation and override the behavior there. But that's a lot of work and if you only need this one feature I suggest overriding the JS function.
In order to override the original JS with your custom one you need to make sure yours is loaded after the original one. To do that you can either use h:outputScript or simply just load the javascript like you're used to... but in the body (not the head).
Also there's probably a fancier way than having to specify the form id. But I just wasted too much time searching for a solution that I had to get it done real fast.

RichFaces 3 to RichFaces 4 migration

I am currently working on a project that I would like to migrate over to RichFaces 4 from version 3.3.3.Final. I was wondering...
is there anything major I should think about or know or think about before migration?
(might be a silly question but...) can you "mix" richfaces 3 with richfaces 4?
One of the main reasons I wanted to make the switch is to use richfaces 4 autocomplete, is there a way to do something like this useing richfaces 3 or would migrating over be the easiest?
I am using JSF.
TLDR: RichFaces reached a richly merited end of life in June 2016. It was a poorly managed catastrophe of a project that deserved no better.
Noting here that the official migration guide is no better than about 30% complete. As a metric on that, I wrote an XSLT stylesheet of 378 lines in 2011 based on the migration guide. I then left the project in abeyance until June 2015 and based on further investigations and getting it working it is already up to 1090 lines. Bearing in mind that any XSLT stylesheet has some overhead, 378/1090 = about 35%.
After you've done what it says in the Migration Guide:
Open the TLD/VLD generated documentation for each component you use in adjacent browser tabs, one for each version, and compare them carefully. There are dozens of undocumented changes in attribute names and purposes, and some attributes have been moved from parent containers to child containers.
There are also important things that have just been arbitrarily removed, such as rich:page and rich:layout.
I'll provide a list of some of the extra things I have discovered at the end of this.
You will then be confronted with the unpleasant realization that they have also changed large numbers of their own style class names, so if you've defined styles for any of those in your own style sheet you have yet more work to do.
You will also discover that their claim that you can define your own style classes and specify them in the rich components to implement your own styles is simply untrue. Your style classes are applied at a containing level but in many cases such as table cells they have seen fit to define fonts etc at the table cell level, where the only way you can override them is by redefining their cells styles by name.
You also have to ensure that your stylesheet is included after the Rich Faces ones. In 3.3 this was automatic, as theirs were included first. Theirs are now included last, so you have to use h:outputStylesheet and do so as late as possible, to ensure it is generated afterwards.
I used an XSLT transform to implement the Migration Guide and accomplish 1-2 above. It presently has over 1000 lines and I have by no means finished yet. Why they couldn't have provided such a thing themselves is a mystery to me.
Why it was deemed necessary to make such major changes between release 3 and 4 is another and deeper mystery. It is a very poorly managed product. I won't be migrating it again, or deploying it anew.
EDIT Undocumented changes I have found (using XPath syntax for brevity):
a4j:status
The documentation is vague on the point, but the for= attribute has been removed: it now operates by default within the nearest parent a4j:region, unless there are tie-ups to specific widgets via the status= attributes. So if you have multiples within the same region they will now all fire.
If you want it to apply to a specific widget via status= you have to change the corresponding a4j:status/#id to an #name attribute.
After you fix all that, it still doesn't work:
An a4j:status with #for (removed) attribute won't stop
with an #name attribute and no #id won't do anything
and with both #name and #id won't stop.
rich:column/#breakBefore now breakRowBefore
rich:page removed.
rich:layout removed.
rich:column/#sortOrder now must be lowercase.
rich:dropDownMenu/#value now rich:dropDownMenu/#label
rich:dropDownMenu/#direction and rich:dropDownMenu/#jointPoint
The values for these have been changed from {top-left, top-right, bottom-left, bottom-right} and {tl, tr, bl, br} respectively to {topLeft, topRight, bottomLeft, bottomRight}.
rich:contextMenu/#submitMode, rich:dropDownMenu/#submitMode, rich:menuItem/#submitMode
These are now all now rich:<whatever>/#mode, and the value "none" needs to be changed to "client".
rich:isUserInRole
This has simply ceased to work, at least for me, with Mojarra 2.2.08 and EL 2.2. Fortunately with EL 2.2 you don't need it any more and can use request.isUserInRole(...).
rich:menuGroup/#value now rich:menuGroup/#label.
rich:tab/#label now rich:tab/#header.
rich:tab/f:facet/#name[.='label'] now rich:tab/f:facet/#name[.='header'].
rich:tabPanel/#activeTabClass, rich:tabPanel/#contentStyle, rich:tabPanel/#disabledTabClass, rich:tabPanel/#inactiveTabClass, rich:tabPanel/#tabClass
Now tabActiveHeaderClass, tabContentClass, tabDisabledHeaderClass, tabHeaderClass, tabInactiveHeaderClass, tabContentClass respectively.
rich:tree/#adviseNodeOpened
This has been removed and rich:treeNode/#expanded added. This is not well documented: it must be an EL, e.g. "#{true}", not "true", and it can be a bean property of the tree node, e.g. "#{node.expanded}", or of any other bean; must be a boolean. (The same is true of the new rich:collapsibleSubTable/#expanded attribute.)
rich:tree/#nodeFace now rich:tree/#nodeType.
rich:tree/#switchType now rich:tree/#toggleType and possibly rich:tree/#selectionType.
rich:tree/#treeNodeVar now var, or possibly just removed.
rich:treeNodesAdaptor
now rich:treeModelAdaptor, and no longer handles arrays, nodesets, ... or anything not a Map or Iterable. It has also lost its var attribute, which as far as I can see breaks it completely for nested use. The only var attribute now available is that of the ancestor rich:tree. So for example if you wanted the parent node and the current child node at the same time, they are simply not available. This change entails either a non-trivial rewrite, or the following kludge.
OLD:
<rich:tree>
<rich:treeNodesAdapter var="vm_host">
<rich:treeNode .../>
<rich:treeNodesAdapter var="vm_guest">
<rich:treeNode .../>
</rich:treeNodesAdapter>
</rich:treeNodesAdapter>
</rich:tree>
NEW:
<rich:tree ... var="node"> <!-- Add a 'var' attribute -->
<rich:treeModelAdapter>
<c:set var="vm_host" value="#{node}"/>
<rich:treeNode .../>
<rich:treeModelAdapter>
<c:set var="vm_guest" value="#{node}"/>
<rich:treeNode .../>
</rich:treeModelAdapter>
</rich:treeModelAdapter>
</rich:tree>
You could also use <ui:param> instead of <c:set>.
The conversion process is made a lot more difficult by RichFaces' refusal to error-check attribute names. You can continue to use the old names, but they just don't work. Silently.
is there anything major I should think about or know or think about before migration?
Their recommendation is to follow their own RichFaces 3.3.x - 4.x Migration Guide — which appears to be far from complete, see EJP's answer below for the real experience.
(might be a silly question but...) can you "mix" richfaces 3 with richfaces 4?
No, you can't. It would conflict with itself.

XPages disableOutput tag issue

Has anyone experienced an issue with disableOutputTag property where if you disable output tag for a computed field control inside a repeat control and have ssjs computed content inside that tag, it won't compute the content? Is disableOutputtag property only meant to work with static content inside a repeat control or is it a bug?
I don't know whether its a bug or not, but you can emulate the behavior of disableOutputTag by removing the ID attribute from and setting the disableTheme attribute to true. Maybe this helps you in short term.
EDIT: You can refer here for more information.
Not only does this happen when placing the xp:Text control inside a repeat but in also when you create a new XPage, add a xp:text onto it and define its value like:
<xp:text value="This is a test" disableOutputTag="true"/>
In the above example the xp:text will disappear. This is not what you would have expected. I would expect that only the value would be visible on the rendered page. But I think I can explain why this happens. Since there are no tags defined (disableoutputtag) somewhere in the rendered of this component it states that it should not generate anything. Because it can not bind its id to 'nothing' and so on.
Anyway, I could not think of a scenario where I would like to render plain text without any surrounding tags. It should at least be surrounded by a span or paragraph (<p>) tag so you can style it. And an ID would be nice so I can change the contents with a partial refresh.

Resources