I am developing a JSF custom component. This component has the purpose of encapsulating another component (namely a PrimeFaces table) and adding customized behaviour to it.
The simple answer is: it is the other frameworks fault that is in use. This framework overwrites the state saving mechanism of JSF and replaces it with a custom mechanism. The implementation, however, was faulty and did not take care of the DynamicAddRemoveListener
s responsible for saving the actions of dynamic componants correctly. They fixed the bug, now it works fine.
However, there were several things that were necessary to fix my component that I want to point out:
First, @BalusC pointed me to the correct way of moving child components in a custom JSF component: it should be done using a PostAddToView
event listener.
@ListenerFor(systemEventClass=PostAddToViewEvent.class) public class YourComponent extends SomeUIComponent { @Override public void processEvent(ComponentSystemEvent event) { if (event instanceof PostAddToViewEvent) { targetParent.getChildren().add(componentToMove); } } }
This approach has the drawback, however, that the components attributes won't be set at this point. So if you need those, components can only be created/moved during render response phase.
Second, child components of a custom JSF component should not be saved in the StateHelper
. They should be recreated on every request so that JSF finds these components when replaying the dynamic actions.
Third, the ID of dynamically created child components (if set) should always be set when the component is created itself. My custom component set the ID of its children components only during render response phase, so when JSF tried to replay the dynamic actions, it could not find the respective components. This was the solution to the problem mentioned above in the section Partial state saving enabled.
So with all these adaptions and the fix for the other framework, now finally my component works as desired.