I am a new to jsf and primefaces.I want to implement that while clicking on button two link should be enable while clicking on the same button again that two link become disabled. I have created a example using <h:commandButton> and java bean to hide show but no idea with the <p:commandButton> and <p:outputPanel>.
I have achieved that while click on the link the 2 link will be enable.
Problem is but again clicking on that it has to be disable which was not working
If I understand you:
<h:form id="mainform">
<p:commandButton value="#{testBean.enabled ? 'Hide' : 'Show'}" action="#{testBean.toggle()}" update="links, #this"/>
<p:outputPanel id="links">
<p:link value="link1" href="http://www.stackoverflow.com" rendered="#{testBean.enabled}"/>
<p:spacer width="10"/>
<p:link value="link2" href="http://www.stackoverflow.com" rendered="#{testBean.enabled}"/>
</p:outputPanel>
</h:form>
Bean:
private Boolean enabled = false; // + getter/setter
public void toggle() {
enabled = !enabled;
}
Related
I cannot comprehend JSF lifecycle for this particular case.
I'm trying to develop a simple modal CRUD with Primefaces 6.0, and I'm having problems with the beheaviour of the add/edit modal.
What I'm trying to accomplish is:
Add
Click add button
Add/Edit dialog opens
InputText "field1" is disabled=false
Edit
Click edit button
Add/Edit dialog opens
InputText "field1" is disabled=true
So for this I linked "field1" disabled property to editMode variable on my bean.
When I click Add Button, linked action initAddRubro gets fired and sets editMode = false (let's say that by default is true).
The thing is when I click on Add button without immediate=true, validations gets fired for the Add/Edit modal window (Field1 is required=true).
If I use immediate=true on my Add Button then disabled property does not get refreshed.
Faces Bean
#Component
#Scope("session")
public class RubrosFacesBean implements Serializable{
private boolean editMode = true;
public String initAddRubro(){
editMode = false;
return null;
}
}
Page
<p:commandButton value="Add" icon="ui-icon-plusthick"
oncomplete="PF('addPanelDialog').show();" style="float: right"
immediate="true" ajax="true" action="#{rubrosFacesBean.initAddRubro}"/>
<p:dialog header="Rubro" widgetVar="addPanelDialog" height="200" style="margin-left: auto;" modal="true" id="addPanelDialog" >
<p:messages autoUpdate="true" />
<p:panelGrid columns="2" id="addPanel">
<h:outputLabel for="field1" value="Field 1: " />
<p:inputText id="field1" value="#{rubrosFacesBean.field1}" label="Field1" required="true" disabled="#{rubrosFacesBean.editMode}"/>
</p:panelGrid>
</p:dialog>
Any help is appreciated.
Thanks in advance.
Juan.-
You can keep immediate="true" on your Add Button and just add following attribute to it
update="addPanel"
or
you can set immediate="false" and add following attributes
process="#this" update="addPanel"
Whatever option you choose, after you press Add button validation will be skipped, Ajax will be executed and finally p:panelGrid will be updated refreshing disable property of p:inputText.
Do not forget to do the same with your Edit button.
I want only single Tab(not entire accordion panel) to be enabled or disabled dynamically.
I tried following approach, here is my code:
index.xhtml
<p:accordionPanel id="accordionPanelId" widgetVar="accordionPanelWidget">
<p:tab id="tab1" title="First Tab">
<h:outputText value="Contents of Tab1"/>
<h:form>
<p:commandButton value="Enable Tab2" action="#{tabBean.buttonAction}" update=":accordionPanelId:tab2"/>
</h:form>
</p:tab>
<p:tab id="tab2" title="Second Tab" disabled="#{tableBean.disableTab}">
<h:outputText value="Contents of Tab2"/>
</p:tab>
</p:accordionPanel>
TabBean.java
#ManagedBean
#ViewScoped
public class TabBean implements Serializable {
private boolean disableTab=true;
public boolean isDisableTab() {
return disableTab;
}
public void setDisableTab(boolean disableTab) {
this.disableTab = disableTab;
}
public void buttonAction()
{
disableTab = false;
}
}
With the above approach Tab2's content is showing but the Tab Header is still freezes,
May be this is not a god approach to achieve this...
Please suggest any other way or changes in this approach.
EDIT : The above approach is working fine if I update entire Accordion panel as follows:
<p:commandButton value="Enable Tab2" action="#{tabBean.buttonAction}" update=":accordionPanelId"/>
But I don't want to update all the tabs.
You need to bind the disabled attribute of the tab to the disableTab backing bean variable that you'll toggle on the server side. To reflect the changes you made on the server side, you then ajax-update the <p:accordionPanel/> on the client side. Using your current setup, the only changes you'll need to make is:
Bind the disabled attribute to the backing bean variable you've setup
<p:tab id="tab2" title="Second Tab" disabled="#{tabBean.disableTab}">
<h:outputText value="Contents of Tab2"/>
</p:tab>
Automatically switch to the tab after enabling it with the javascript API
<p:tab id="tab1" title="First Tab">
<h:outputText value="Contents of Tab1"/>
<h:form>
<p:commandButton value="Enable Tab2" oncomplete="accordionPanelWidget.select(2)" action="#{tabBean.buttonAction}" update=":accordionPanelId:tab2"/>
</h:form>
</p:tab>
You have to update all the accordionPanel in order to enable/disable tabs. In this case you'll have to update accordionPanelId. However, you can use dynamic="true" attribute in accordionPanel to avoid update the parts that aren't rendered.
I have checked around but I didn't found a clear example on how to submit the accordion using a single form.
The problem I find is when I want to process (validate) only fields of the opened tab.
The structure of my page is as follows:
<h:form>
<p:accordionPanel activeIndex="#{bean.selectedTab}">
<p:ajax event="tabChange" listener="#{bean.tabChangeListener}"/>
<p:tab title="Tab1" id="t1">
<p:inputText id="reqField1" required="true"/>
</p:tab>
<p:tab title="Tab2" id="t2">
<p:inputText id="reqField2" required="true"/>
</p:tab>
</p:accordionPanel>
<p:commandButton update="list" immediate="true" actionListener="#{bean.addRecord}"/>
</h:form>
method:
#SessionScoped
public class Bean{
public void tabChangeListener(AjaxBehaviorEvent evt){
AccordionPanel panel = (AccordionPanel) evt.getComponent();
// getLoadedTabs() returns an empty list
String currentlyLoadedTabId = panel.getLoadedTabs().get(this.selectedTab).getClientId();
}
}
Is there anyway to specify the id of the currently opened tab as part of the process attribute in p:commandButton tag?
UPDATE
When Tab1 is open, on submit, I want to be validated only reqField1 and not reqField2. Viceversa, when Tab2 is open, I want to be validated only reqField2 and not reqField1.
Try this.
Bind the activeIndex of the accordionPanel to a backing bean int attribute
activeIndex="#{myBean.selectedTab}"
Get the id of the currently selected tab using the bound activeIndex. To do this in your actionListener, get a handle on the accordion panel
EDIT: Since your actionListener has been set to immediate, the activeIndex and selectedTab will need to be updated via ajax. Add the following <p:ajax/> to your accordionPanel
<p:ajax event="tabChange" listener="#{bean.tabChangeListener}" />
In your backing bean, you'll now have
public void (AjaxBehaviorEvent evt){
AccordionPanel panel = (AccordionPanel) evt.getComponent();
String currentlyLoadedTabId = panel.getLoadedTabs().get(this.selectedTab).getClientId();
}
Using the the id you got from 2 above, you can include that in the JSF list of things to be rerendered using ajax on the server side. In the same action listener method:
FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(currentlyLoadedTabId);
Alternatively, you might just consider placing a command button in each of those tabs and having a form in each tab as well. This way, each command button processes only it's own parent form
This odd behavior only happen in Firefox (specifically Firefox 8). So I have a dataTable that I can do multiple selection. A submit button, that will display a list of selected items to a dataList and to a dialog. If the user did not select anything, then a error msg come up asking the user to select something. The dialog will not appear if the user select nothing. The below code does all that. However FireFox behaves oddly if you do these follow:
Click to select an item on the dataTable
Then refresh (F5 or Ctl + R) the page (you can see the selection got clear off)
Then click submit, it show whatever I just selected.
This is unexpecting, since the refresh should clear out whatever you just select due to nature of #ViewScoped bean. This behavior only happen in Firefox. IE 8 behave correctly for me. Is this a bug, or am I doing something wrong here?
Mojarra 2.1 + PrimeFaces3.0 Final + Tomcat 7
UPDATE: I did some debugging, when I refresh page, the value of the array selectedFoods become null, but for some odd reason, when it get to public void checkSelection(), it hold the value of the previous selection. So odd.
Here is my code.
<p:growl id="messages" showDetail="true" />
<p:messages id="msgs"/>
<h:form id="form">
<p:dataTable value="#{viewBean.foodList}" var="item"
selection="#{viewBean.selectedFoods}"
selectionMode="multiple"
rowKey="#{item}">
<p:column>
#{item}
</p:column>
<f:facet name="footer">
<p:commandButton value="Submit" update=":form:display :dataList"
action="#{viewBean.checkSelection}"/>
</f:facet>
</p:dataTable>
<p:dataList id="display" value="#{viewBean.selectedFoods}" var="item"
itemType="disc">
#{item}
</p:dataList>
</h:form>
<p:dialog id="dialog1" widgetVar="dialog1" dynamic="true" width="200">
<p:dataList id="dataList" value="#{viewBean.selectedFoods}" var="item"
itemType="disc">
#{item}
</p:dataList>
</p:dialog>
Here is my managed bean
#ManagedBean
#ViewScoped
public class ViewBean implements Serializable {
private List<String> foodList;
private String[] selectedFoods;
#PostConstruct
public void init() {
foodList = new ArrayList<String>();
foodList.add("Pizza");
foodList.add("Pasta");
foodList.add("Hamburger");
}
public void checkSelection(){
RequestContext requestContext = RequestContext.getCurrentInstance();
if(selectedFoods.length > 0){
requestContext.execute("dialog1.show()");
}else{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Error", "Please select"));
requestContext.addPartialUpdateTarget("messages");
}
}
//setter, getter
}
Your code is fine. What you're seeing is because of something that is supposed to be a feature of Firefox (I was able to reproduce this on FF4). The selection model for p:dataTable is implemented with a hidden form field. When reloading a page, Firefox tries to save and restore form field values that have changed so that you don't lose what you entered. You can observe this by adding a <h:inputText/> to your view, typing something in the input, and reloading.
I'm not sure that the Firefox team meant for this to apply to hidden form fields, but I figure there's a decent chance that they did. I plan to file a bug report with Primefaces to either initialize the hidden input or to read the input on load to make the p:dataTable selection match. Either solution should result in the rendered selection and the hidden selection model to be in sync.
How do I switch to a tab (<p:tab>) using a command button?
There is also a client side api method called selectTab(index);
<p:commandButton type="button" onclick="widgetvar.selectTab(2)" value="Show" />
p:tabView has an attribute activeIndex that is the "Index of the active tab" (Primefaces Documentation).
You could set this attribute from the action method of your p:commandButton:
<p:commandButton value="Switch tab" action=#{myBean.switchTab} />
Define an action method switchTab() in your backing bean and let it set a member activeTab.
Then use this member to set your active tab
<p:tabView activeIndex=#{myBean.activeTab}>
If your server supports EL 2.2 you can set the index of the active tab with the action method call:
<p:commandButton value="Switch tab" action=#{myBean.switchTab(2)} />
Then you can use the argument of your action method call to set the active index directly.
I use Primefaces 5.1 and what I did was bind my tabView in the ManagedBean and set the activeIndex there
In your JSF
<h:form prependId="false" id="form">
<p:tabView id="tabPanel" widgetVar="tabPanel" binding="#{managedBean.tabView}" dynamic="true">
<p:tab title="tab" >
<p:commandButton action="#{managedBean.getBla}"
icon="ui-icon-search" update=":form:tabPanel" immediate="true" >
...
In your ManagedBean
private TabView tabView;
public TabView getTabView() {
return tabView;
}
public void setTabView(TabView tabView) {
this.tabView = tabView;
}
And then in the method you call in your commandButton action you just do a
tabView.setActiveIndex(1);
Hope it works :)
To switch p:tab in the same form using a command button
At the Client side only you can use widgetVar to select/view tab as follow:
Note: tabIndex will start from 0 for the first tab.
<p:commandButton type="button" onclick="PF('tabWidgetVar').select(1)" value="Next" />
At the server side you can bind a integer variable with the activeIndex property of the p:tab and then excute method to set index.