I have a tabview on page and add tabs with javascript dynamically. At the same time add the opened tab names to a list(lstOpenedPages). But close a tab, I can't get name of this tab which is closed for delete from the list. Now I want to read remain tabs of tabview because I can find which tab is closed from the list (lstOpenedPages).
How to I get remain tabs of tabview in Javascript?
xhtml code
<p:tabView id="tw" widgetVar="tw">
<p:ajax event="tabClose" listener="#{MenuBean.onTabClose}"/>
</p:tabView>
<p:menuitem value="#{itemMenu.menuAck}"
action="#{MenuBean.OpenPage(itemMenu.pageName)}"
ajax="true"
oncomplete="handleTabViewEvent(args);"
/>
<script type="text/javascript">
function handleTabViewEvent(args) {
alert('Add tab here..');
}
</script>
bean
public void OpenPage(String pageName) {
lstOpenedPages.add(pageName);
}
public void onTabClose(TabCloseEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
TabView tw = (TabView)context.getViewRoot().findComponent("centerForm:tw");
String s = "I must delete tab here from lstOpenedPages which closed. But event does not give me tab information. It is always null. So I must be delete from javascript";
}
Related
This question already has answers here:
How to dynamically add and remove a tab in p:tabView component
(2 answers)
Closed 7 years ago.
I am programmatically add a new tab whenever a menu item is clicked. I have googled for all the questions on dynamic Tab creation and found a lot of unanswered queries. So my question is, is it possible to create tabs dynamically? Below is the code I am working on for the past week and not a tab in sight..
I am using Primefaces 5.0, JSF 2.2 Mojarra
Dynamic menu -
DefaultMenuItem windowItem = new DefaultMenuItem(node);
windowItem.setCommand("#{windowContainer.add}");
windowItem.setImmediate(true);
WindowContainer Backing Bean
#ManagedBean
#ViewScoped
public class WindowContainer implements Serializable {
private List<Window> windows;
#PostConstruct
public void init() {
windows = new ArrayList<Window>();
windows.add(new Window("window"+windows.size(),"first tab"));
}
public void add() {
windows.add(new Window("window" + windows.size(), "some content"));
RequestContext req = RequestContext.getCurrentInstance();
req.update("WindowContainer");
}
public void remove(Window window) {
windows.remove(window);
}
public List<Window> getWindows() {
return windows;
}
public void setWindows(ArrayList<Window> windows) {
this.windows = windows;
}
Windows is simple tab with only outputtext .
The View
<p:tabView id= "WindowContainer" value="#{windowContainer.windows}" var="window">
<p:tab title="#{window.title}">
<p>#{tab.content}</p>
<p:commandButton value="Close" action="#{windowContainer.remove(window)}" />
</p:tab>
</p:tabView>
<p:menu>
<p:submenu label="Ajax">
<p:menuitem value="Add Tab" actionListener="#{menuView.addTab}" update="WindowContainer" />
</p:menu>
Try like this update="WindowContainer" .Inside quotes give tabview id.
I'm using a ace:dataTable to display a list. When the user clicks a row, a detail popup is shown. What I'm trying to achieve is that the click has no effect on the selection of rows.
This is my code:
public void rowSelected(SelectEvent event) {
DataTable dataTable = (DataTable)event.getComponent();
dataTable.getStateMap().setAllSelected(false);
// Show Popup etc
// Prints an empty list
System.out.println(dataTable.getStateMap().getSelected());
}
The popup is shown, but the selection ist still there. Any Ideas?
<ace:dialog id="dialogid"
header="Header" widgetVar="nodeDialog"
modal="true" draggable="false" showEffect="true" hideEffect="true"
relativePosition="center center">
---dialog contnent---
</ace:dialog>
public void rowSelected(SelectEvent event) {
DataTable dataTable = (DataTable)event.getComponent();
dataTable.getStateMap().setAllSelected(false);
// Show Popup etc
JavascriptContext.addJavascriptCall(facesContext(), "nodeDialog.show();");
// Prints an empty list
---writwe to the dialog contnent---
System.out.println(dataTable.getStateMap().getSelected());
}
I use JSF + Primefaces 3.2.1.
There is an p:datatable on the page, in each row I have button "Edit". When I click that button, in the footer of the page renders a form for editing that row. Then I need to scroll down there to change values..
But I need the browser to scroll there automatically after clicking on "Edit" button like Anchors in basic HTML work.
I found this decision:
FacesContext.getCurrentInstance().getExternalContext().redirect("pProvidersPriceAppointment.xhtml#anchor1");
It works, but with that my update="#form" not working.. So the form in the bottom not renders. It renders after refreshing page.
How can I do it with p:commandButton or h:commandButton ?)
My button:
<p:commandButton id="providerEdit" actionListener="#{providersPriceAppointment.setEditProvider(provider.id)}" icon="iconEdit" update="#form"/>
Bean method:
public void setEditProvider(int id) throws IOException {
for (int i = 0; i < providersList.size(); i++) {
ProvidersExt p = providersList.get(i);
if (p.getId() == id) {
providerForEdit = p;
break;
}
}
enableEdit = true;
FacesContext.getCurrentInstance().getExternalContext().redirect("pProvidersPriceAppointment.xhtml#anchor1");
}
Form in the footer:
<a name="anchor1"/>
<p:fieldset id="editFieldset" legend="blablabla" rendered="#{providersPriceAppointment.enableEdit}"/>
...
</p:fieldset>
There isn't something like this implemented in JSF or Primefaces yet. But since you have the jQuery Framework running in your application (Primefaces), you could use the jQuery Animate features.
To get a Hint on how to realize something like this, you could check out this answer:
jQuery scroll to Element
For your application that would be somehow like that:
Add this to your <head> element:
function scrollToAnchor() {
jQuery('html, body').animate({
scrollTop: jQuery("#editFieldset").offset().top
}, 2000);
}
And this would be the Button Part:
<p:commandButton id="providerEdit"
actionListener="# {providersPriceAppointment.setEditProvider(provider.id)}"
icon="iconEdit" onComplete="scrollToAnchor();" update="#form"/>
Use PrimeFaces RequestContext with scrollTo to target a component id:
https://www.primefaces.org/showcase/ui/misc/requestContext.xhtml
public void save() {
RequestContext context = RequestContext.getCurrentInstance();
...
//scroll to panel
context.scrollTo("form:panel");
Simple decision that I found on PrimeFaces ShowCase:
<p:fieldset id="edit" legend="Here you can edit.." rendered="#{providersPriceAppointment.enableEdit}">
<p:focus context="panel"/>
</p:fieldset>
When this fieldset is rendered, browser simply jump to this place)
https://www.primefaces.org/showcase/ui/misc/focus.xhtml
Hope, somebody will find this helpful (",)
I am using an accordion panel with three tabs.
Each tab has required fields and <p:ajax> tags for accordionPanel:
<p:ajax event="tabChange" update=":contentForm:growl"/>
<p:ajax event="tabClose" update=":contentForm:growl"/>
By default all tabs are closed. When I click to open any tab, it performs vaidation of all inputs in all tabs.
How do I skip field validation and do ajax query during open/close tab?
(I need an Ajax query to save opened tabs indexes to Bean: activeIndex="#{tabBean.activeTabs}")
I have resolved this problem. I have created saver-class:
import javax.faces.event.AjaxBehaviorEvent;
import org.primefaces.component.accordionpanel.AccordionPanel;
public class ActiveIndexSaver {
private String activeTabs = "-1,0";
public String getActiveTabs() {
return activeTabs;
}
public void setActiveTabs(String activeTabs) {
this.activeTabs = activeTabs;
}
public void saveIndexes(AjaxBehaviorEvent abe){
AccordionPanel accordion = (AccordionPanel)abe.getComponent();
activeTabs = accordion.getActiveIndex();
}
}
After that I wrote Inject of the bean above to page-bean and getter for him:
#Inject
private ActiveIndexSaver activeIndexSaver;
....
public ActiveIndexSaver getActiveIndexSaver() {
return activeIndexSaver;
}
And finally, html:
<p:accordionPanel ... activeIndex="#{tabBean.activeIndexSaver.activeTabs}">
<p:ajax event="tabChange" immediate="true" listener="#{tabBean.activeIndexSaver.saveIndexes}"/>
<p:ajax event="tabClose" immediate="true" listener="#{tabBean.activeIndexSaver.saveIndexes}"/>
......
I have Primefaces TabView with two Tab like:
<p:tabView dynamic="true" cache="false"
onTabShow="scrollBottom(#{stanzaBean.activeIndex})"
tabChangeListener="#{messaggioBean.onTabChange}"
activeIndex="#{stanzaBean.activeIndex}" >
it works fine, except that when I change the Tab the activeIndex isn't updated on the Server and it returns always the default value.
I'm using primefaces 2.2.1.
Thank you.
Going by the PrimeFaces ShowCase example, if you give each tab an id:
<p:tabView tabChangeListener="#{indexBean.onTabChange}" >
<p:tab title="tab 0" id="tab0"></p:tab>
<p:tab title="tab 1" id="tab1" ></p:tab>
<p:tab title="tab 2" id="tab2"></p:tab>
</p:tabView>
you can get that tab id in the tabChangeListener.
public void onTabChange(TabChangeEvent event) {
System.out.println("tab id = " + event.getTab().getId());
}
Then you'll know which tab was selected.
Edit:
There is an open PrimeFaces issue 1640 TabView: Wrong activeIndex in TabChangeListener, always 0 on the problem you are having.
Edit 2:
With PrimeFaces 5.0 and up the tabChangeListener is no longer available on the tabView element but should be used via an explicit ajax tag with a tabChange event.
<p:tabView id="analysisSections" value="#{analysisBean.analysis.sections}" var="section" activeIndex="#{analysisBean.activeIndex}">
<p:ajax event="tabChange" listener="#{analysisBean.onTabChange}"/>
Also you can directly get index of tab:
public void onTabChange(TabChangeEvent event) {
activeIndex = ((TabView) event.getSource()).getIndex();
}
with all these changes, activeIndex works properly.
this worked for me:
public void onTabChange(TabChangeEvent event) {
Tab activeTab = event.getTab();
tabPanelIndex = ((TabView)event.getSource()).getChildren().indexOf(activeTab);
}
Although the question was related to PrimeFaces 2.2.1, I like to mention that in modern PrimeFaces versions (tested with version 6.2) there is no need to trigger a separate event when attribute dynamic is set to true and cache is set to false. By using this attribute combination the active index is automatically updated on the server when another tab is selected.
Facelet:
<p:tabView activeIndex="#{stanzaBean.activeIndex}"
cache="false"
dynamic="true">
Bean:
#Named
#ViewScoped
public class StanzaBean implements Serializable {
private int activeIndex;
public int getActiveIndex() {
return activeIndex;
}
/**
* Automatically called whenever a tab changes and dynamic="true"
* and cache="false".
*/
public void setActiveIndex(int activeIndex) {
this.activeIndex = activeIndex;
// do other stuff when tab changes
}
}