Put new component inside existent composition - jsf

I'm new in Java Web, and I'm just learning english...
I have multiples composite component, that works fine, like, for example, this code
<composite:interface>
<composite:attribute name="usernameValue" />
</composite:interface>
<composite:implementation>
<h:form>
<h:outputText id="username" value="#{cc.attrs.usernameValue}" />
</h:form>
When I need to use this component, I just do:
<myComposite:myComponent usernameValue="My user name value"/>
this works ok.
But, how to do if I need put more components inside this previously created component, like:
<h:form>
<h:outputText id="username" value="My text 1" />
<p:commandButton value="New button 2"/>
<p:commandButton value="New button 3"/>
<p:commandButton value="New button 4"/>
<h:form/>
Is there any way to do something like:
<myComposite:myComponent usernameValue="This will render default inside composite output text">
<p:commandButton value="New button 1 to render inside my composite"/>
<p:commandButton value="New button 2 to render inside my composite"/>
<p:commandButton value="New button 3 to render inside my composite"/>
<myComposite:myComponent/>
I'm learning, and this time I recreate all composite that I need to use with attribute render="true or false" according the components that I will use, but this is like XGH.
Sorry for my english, I know that i need to improve it...
Thanks in advance...

If I understood your question correctly, what your trying to achieve is what the tag insertChildren does.
In your example, it would be like:
<composite:implementation>
<h:form>
<h:outputText id="username" value="#{cc.attrs.usernameValue}" />
<composite:insertChildren />
</h:form>
</composite:implementation>
and then use the component like you intended:
<myComposite:myComponent usernameValue="This will render default inside composite output text">
<p:commandButton value="New button 1 to render inside my composite"/>
<p:commandButton value="New button 2 to render inside my composite"/>
<p:commandButton value="New button 3 to render inside my composite"/>
<myComposite:myComponent/>
And the commandButtons will be placed where the insertChildren tag was defined.
Here is another example of its usage.

Related

Draggable input components PrimeFaces

I tried to use draggable component https://www.primefaces.org/showcase/ui/dnd/draggable.xhtml for inputTextArea component but it does not work for me. Do you know any workarounds for making input components draggable?
My code:
<p:outputPanel>
<p:inputTextarea id="test">
</p:inputTextarea>
</p:outputPanel>
<p:draggable for="test" containment="parent" />
I don't have any errors in console. But drag function does not work as it work for p:panel, for example.
try to wrap the component in a panel and assign "for" to that panel.
<p:outputPanel>
<p:panel id="test">
<p:inputTextarea />
</p:panel>
<p:draggable for="test" containment="parent"/>
</p:outputPanel>

Keep primefaces tooltip visible until its manually closed

I wanted to create a tooltip with dynamic content on a button hover and show a data table inside it. After a little bit of googling i managed to get that working but with a small issue. I am not able to keep the tooltip visible until its manually closed and primesfaces tooltip options do not seem to have any property to achieve something like that.
Code for tooltip:
<h:panelGroup>
<h:outputLink id="lnk" value="#">
<h:outputText value="Sample Tooltip"/>
</h:outputLink>
<p:tooltip for="lnk" position="right" />
<p:dataTable var="car" value="#{preOrderController.cars}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.name}" />
</p:column>
</p:dataTable>
</h:panelGroup>
The tooltip works fine, what I want to do is once the mouse is hovered over the button and tooltip is shown, I want to keep it visible until the user manually clicks the close button at the top right corner or somewhere else on the screen. It is not necessary that I use tooltip, if primefaces has something else that can used to get similar functionality I am open to suggestions.
The solution is here
<h:form>
<h:panelGrid>
<h:panelGroup>
<p:commandButton value="Hide" type="button" onclick="PF('tooltip').hide();"/>
</h:panelGroup>
<h:panelGroup>
<p:commandLink id="focus" value="link" onmouseover="PF('tooltip').show()"/>
<p:tooltip value="This is a tooltip" for="focus" hideEvent="blur" widgetVar="tooltip"/>
</h:panelGroup>
</h:panelGrid>
</h:form>
Try this:
<h:form onclick="PF('tooltip').hide()">
<p:commandLink id="focus" value="link" onmouseover="PF('tooltip').show()"/>
<p:tooltip value="This is a tooltip" for="focus" hideEvent="blur" widgetVar="tooltip"/>
</h:form>
Take note that you need to click inside the <h:form> in order to hide the tooltip

RichFaces a4j:commandButton. first click does not work the action, it works in the secon click

I have a problem that a I couldn't solve. When I click first time on a a4j:commandButton there is not action. The second and following time it works perfectly. I have read about this problem however I have not clear the solucion.
I am new, and I have find this solucion: (h:commandButton/h:commandLink does not work on first click, works only on second click) however I do not know where should I introduce the script code.
I have found this: however I think is an old jsf version:
(https://community.jboss.org/thread/165031)
And I have tried to repare it with: https://community.jboss.org/wiki/ProgrammaticControlOfPartialProcessingInRichFaces4. However, I have not been success
If someone could explain me the #BalusC solution step by step, it could be really hepful
Thanks very much:
My code is: (everything in the same file)
<ui:define name="table">
<h:form id= "formListCompanies">
<a4j:outputPanel id="tablePaneRegion">
<rich:extendedDataTable ....
<rich:column sortable="false" width="100%">
...
<a4j:commandLink id="editCmd" styleClass="no-decor" render="editGrid, editPane"
execute="#this" oncomplete="#{rich:component('editPane')}.show()">
<a4j:param value="#{it.index}" assignTo="#{myBean.currentIndex}" />
<f:setPropertyActionListener target="#{myBean.selected}" value="#{mypojo}" />
</a4j:commandLink>
....</rich:column>
....
<rich:popupPanel id="editPane" header="#{...}" domElementAttachment="body"
moveable="true" modal="true" resizeable="false" autosized="true"
onshow="focus(#{rich:component('name')});">
....
<!-- h:Inputtext ..-->
<h:panelGrid columns="2">
<a4j:commandButton value="#{'save'}" action="#{myBean.edit}"
render="dataTable" execute="editPaneRegion" />
<a4j:commandButton value="#{...}"
onclick="#{rich:component('editPane')}.hide(); return false;" />
</h:panelGrid>
</h:form>
</a4j:outputPanel>
</rich:popupPanel>
What I have already tried is to take out the h:form id= formListCompanies, and put there a h:panelgrid and a h:panelgroup
Is the problem related to the doble clicking issue? Am i in the right way?
rerender panel and form (form state lost error in jsf spec)... render="richPanelMantenimientoTipoVisualAjaxWebPart,frmMantenimientoTipoVisual"

<h:commandButton> is not refreshing page after actioned

hi we are using along with a4j tag.
here we are retrieving data from database after a click of button. even though the data is available in server, it will not display over view. After manual refresh of web page will lead to data diplay.
here is code snippet
.... some code here
<rich:tab id="menu5" label="Recall">
<ui:include src="/pages/mctrans/reCallMcifTrans.xhtml" />
</rich:tab>
reCallMcifTrans.xhtml contains below code
<h:commandButton type="button" id="reCallbutton1" value=" Search "
styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';"
action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
</h:commandButton>
It looks like you're working with RichFaces 3.3. So, you don't need a <h:commandButton with <a4j:support> because you can use <a4j:commandButton> that already does this. You can refactor your code to this:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1"
oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" />
Make sure your reCallgrid1 component is available in the same <h:form> of the <a4j:commandButton>.
Since you also want to add a Wait while searching the data behavior when the button is clicked, you can use <a4j:status> along with the <a4j:commandButton> as shown in the <a4j:status> demo. Here's a basic example:
<a4j:commandButton type="button" id="reCallbutton1" value="Search"
styleClass="commandExButton"
action="#{mcifRecallTransBean.reCallSearch}"
reRender="reCallgrid1" />
<!-- Note that there's no oncomplete in this case -->
<a4j:status for="reCallbutton1">
<f:facet name="start">
<h:graphicImage value="/res/images/wait.gif"/>
</f:facet>
</a4j:status>
At last but not least, you should switch your managed bean to request scope and use RichFaces powerful <a4j:keepAlive> in order to simulate JSF 2 #ViewScoped. You can even use it in form of annotation on your managed bean (no additional configuration):
#KeepAlive
public class McifRecallTransBean {
//managed bean code here...
}
When you are using request parameters inside the bean, you need to pass them again with your action :
<h:commandButton type="button" id="reCallbutton1" value="Search" styleClass="commandExButton">
<a4j:support event="onclick" id="ajsf12" oncomplete="javascript:alert('Search Completed');javascript:document.body.style.cursor='default';" action="#{mcifRecallTransBean.reCallSearch}" reRender="reCallgrid1" />
<f:param name="param1" value="#{param['param1']}" />
<f:param name="param2" value="#{param['param2']}" />
</h:commandButton>

form within form: skip validation of parent form

<h:form prependId="false" id="parentForm">
...
<h:form prependId="false" id="commentForm">
...
add comment
</h:form>
save
</h:form>
Doesn't work...
Without the inner form the parent's elements get validated when I just want to add a comment.
"add comment" should just validate the comment and when "save" is clicked the parent should be validated.
Nesting forms is illegal in HTML, so also in JSF since all it does is just generating HTML. You need to put them next to each other.
If you have multiple buttons in the same form of which you'd like to skip certain validation on certain button press, then add immediate="true" to the button in question. This way all input fields which do not have immediate="true" will be skipped.
See also:
What is the immediate attribute used for?
Update: OK, you want two physically separate forms inside a single form. If splitting the "God Form" in multiple forms with each its own responsibility is not an option, then there are several ways to go around this:
If you don't use Ajax and you just have a required="true" on an input element which you actually want to make non-required when you press a certain button, then do:
<h:form>
...
<h:commandButton value="Submit form but but do not validate comment" />
...
<h:inputTextarea id="comment" required="#{not empty param[foo.clientId]}" immediate="true" />
<h:commandButton binding="#{foo}" value="Submit and validate comment" immediate="true" />
</h:form>
If you actually use Ajax, then just specify the execute region in execute attribute.
<h:form>
<h:panelGroup id="other">
....
<h:commandButton value="Submit form but but do not validate comment">
<f:ajax execute="other" render="other" />
</h:commandButton>
</h:panelGroup>
<h:panelGroup id="comments">
<h:inputTextarea required="#{not empty param[foo.clientId]}" />
<h:commandButton value="Submit and validate comment by ajax">
<f:ajax execute="comments" render="comments" />
</h:commandButton>
</h:panelGroup>
</h:form>

Resources