p:tabMenu activeIndex becomes 0 after form submit - jsf

Both pages contains the header:
<p:tabMenu activeIndex="#{param.i}">
<p:menuitem value="Overview" outcome="index" icon="ui-icon-star">
<f:param name="i" value="0" />
</p:menuitem>
<p:menuitem value="Demos" outcome="second" icon="ui-icon-search">
<f:param name="i" value="1" />
</p:menuitem>
</p:tabMenu>
The second page contains a form:
<h:form>
<h:inputText id="name" value="#{name}" a:placeholder="What's your name?" />
<h:commandButton value="Submit" outcome="second" />
<br/> <h:outputText value="Hello, #{name}" rendered="#{not empty name}" />
</h:form>
The problem is that activeIndex becomes 0 after the form submited. How to fix it?

it fixed by adding a <f:param name="i" value="1" /> to commnadButton

I personally use a #ViewAccessedScope for menu backingveans from DeltaSpike for this instead of passing params around.

Related

passing the selected object from list of objects that each one has its own button

I’m working on a web-app that displays list of objects, each object has its own modal when clicked inside the modal there are two dropdown menus and a button that is supposed to call a method add in a bean, to perform an action and add the selected object while taking three values, selected object, selected two items from the two drop downs and spinner’s value.
<ui:repeat value="#{ViewTeacher.teacherList}" var="teacher"
varStatus="status">
<h:panelGroup layout="block" styleClass="name">
<p>#{teacher.name}</p>
</h:panelGroup>
<br />
<br />
<a onclick="viewModal(#{status.index})" class="btn btn-success">view</a>
<h:panelGroup id="modal" layout="block" class="modal"
style="max-width: 44em;" tabindex="1">
<h:panelGroup class="modal-content" layout="block">
<span class="close" onclick="modClose()">×</span>
<h:outputText styleClass="description" value="#{teacher.name}" />
<br />
<br />
<br />
students
<h:selectOneMenu value="ok" class="form-control">
<f:selectItems value="#{teacher.students}" var="s"
itemValue="#{s.id}" itemLabel="#{s.name}" />
</h:selectOneMenu>
classes
<h:selectOneMenu value="ok" class="form-control">
<f:selectItems value="#{teacher.classes}" var="c"
itemValue="#{c.id}" itemLabel="#{c.name}" />
</h:selectOneMenu>
<br />
<h:panelGroup layout="block" styleClass="form-group">
<p:spinner min="1" max="10" />
</h:panelGroup>
<h:commandButton id="submitButton" styleClass="btn btn-success" value="ADD">
<!—-this is the button that is supposed to take the values
</h:commandButton>
<a onclick="modClose()" class="btn btn-success">CANCEL</a>
</h:panelGroup>
</h:panelGroup>
</ui:repeat>
I tried :
<f:param name="name1" value="China" />
But the fact that param’s name will get repeated, will make it the same all the time and might be set to the latest object retrieved,
Any recommendation?
UPDATE:
<p:commandLink styleClass="btn btn-success" process="#this"
onclick="viewModal(#{status.index});">
<h:outputText value="ADD" />
<f:setPropertyActionListener
value="#{teacher.id}" target="#{ViewTeacher.selectedTeacher}" />
</p:commandLink>
Made this change to pass the teacher's id but it's still null in the bean
First of all, having a separate modal for each object isn't a good idea. You can achieve (what you are trying) by:
1). Adding a property (with its getter and setter) in bean for selected object.
2). Place single modal (<p:dialog with id="modal" and widgetVar="modal" attributes) outside ui:repeat to display data from selected object.
3). Set selected object on clicking view link, update and display modal, using:
<p:commandLink styleClass="btn btn-success" process="#this" update="modal"
onclick="PF('modal').show();">
<h:outputText value="View" />
<f:setPropertyActionListener
value="#{teacher}" target="#{ViewTeacher.selectedTeacher}" />
</p:commandLink>
Here, f:setPropertyActionListener will be setting your selected modal in bean and thus it will become available in your action listener.
Update: Change the code as following:
<ui:repeat value="#{ViewTeacher.teacherList}" var="teacher" varStatus="status">
<h:panelGroup layout="block" styleClass="name">
<p>#{teacher.name}</p>
</h:panelGroup>
<p:commandLink styleClass="btn btn-success" process="#this" update="modal"
oncomplete="PF('modal').show();">
<h:outputText value="view" />
<f:setPropertyActionListener
value="#{teacher}" target="#{ViewTeacher.selectedTeacher}" />
</p:commandLink>
</ui:repeat>
<p:dialog id="modal" widgetVar="modal" header="Edit Teacher" modal="true"
showEffect="fade" hideEffect="fade" resizable="false" closeOnEscape="true"
styleClass="teachers-dialog">
<h:outputText styleClass="description" value="#{ViewTeacher.selectedTeacher.name}" />
<br />
<br />
<br />
students
<h:selectOneMenu value="#{ViewTeacher.selectedStudentId}" class="form-control">
<f:selectItems value="#{ViewTeacher.selectedTeacher.students}"
var="s" itemValue="#{s.id}" itemLabel="#{s.name}" />
</h:selectOneMenu>
classes
<h:selectOneMenu value="#{ViewTeacher.selectedClassId}" class="form-control">
<f:selectItems value="#{ViewTeacher.selectedTeacher.classes}"
var="c" itemValue="#{c.id}" itemLabel="#{c.name}" />
</h:selectOneMenu>
<br />
<h:panelGroup layout="block" styleClass="form-group">
<p:spinner value="#{ViewTeacher.spinnerValue}" min="1" max="10" />
</h:panelGroup>
<h:commandButton id="submitButton" styleClass="btn btn-success" value="ADD">
</h:commandButton>
</p:dialog>
Where selectedTeacher, selectedStudentId, selectedClassId, spinnerValue are properties from your ViewTeacher bean.

one requiredMessage for 2 "h:selectOneMenu"s

I want one requiredmessage for two h:selectOneMenu components, that is when a user submits the form if one of those selects values is not null, the bean method should be called, otherwise(both of them null) : I should tell him to select at least one, is it possible? or do I have to use JS.
Thanks in advance,
I'd use the OmniFaces validateOne validator for this or the validateOneOrMore if filling both is allowed too.
Code example from their site:
<h:form>
<h3>Please fill out only one of two fields</h3>
<o:validateOne id="one" components="foo bar" />
<h:panelGrid columns="3">
<o:outputLabel for="foo" value="Foo" />
<h:inputText id="foo" />
<h:message for="foo" />
<o:outputLabel for="bar" value="Bar" />
<h:inputText id="bar" />
<h:message for="bar" />
<h:panelGroup />
<h:commandButton value="submit">
<f:ajax execute="#form" render="#form" />
</h:commandButton>
<h:panelGroup>
<h:message for="one" />
<h:outputText value="OK!" rendered="#{facesContext.postback and not facesContext.validationFailed}" />
</h:panelGroup>
</h:panelGrid>
</h:form>

Invoking p:dataExporter in p:contextMenu

I want to use dataExporter as onclick action in my right-click contextMenu.
Sadly, I have no idea how to manage this :(
dataExporter(simple export table date to XLS) and contextMenu are binded to the same dataTable.
here's the code:
<p:contextMenu for = "tableForm">
<p:menuitem value="View" icon="ui-icon-search"/>
<p:menuitem value="Delete" icon="ui-icon-close" />
</p:contextMenu>
<p:commandLink ajax="false" width="24">
<p:graphicImage value="/resources/images/Excel-icon.png" />
<p:dataExporter type="xls" target="dataTable"
fileName="daneCentrumDataTable" />
</p:commandLink>
Anyone knows how to do this?
Following #Kukeltje idea something like this:
<p:contextMenu for="dataTable">
<p:menuitem value="View" icon="ui-icon-search"/>
<p:menuitem value="Delete" icon="ui-icon-close" />
<p:menuitem value="Export" onclick="$('#export').click()" />
</p:contextMenu>
<div style="display: none;">
<p:commandLink id="export" ajax="false" width="24">
<p:dataExporter type="xls" target="dataTable" fileName="daneCentrumDataTable" />
</p:commandLink>
</div>
P.S.: My h:form has prependId="false"

primefaces using components in menuitem

I want to use other primefaces components in p:menuitem. Components display in page but actionlistener doesn't work and inputtext's value doesn't push to bean's value1 attribute. Is there any way to handle this problem?
<p:commandButton id="dynaButton" value="Search" type="button" icon="ui-icon-extlink"/>
<p:slideMenu overlay="true" trigger="dynaButton" my="left top" at="left bottom" style="width:180px">
<p:submenu label="Search">
<p:menuitem>
<p:outputLabel value="Search by Id" />
<p:inputText value="#{bean.value1}" />
<p:commandButton value="save" actionListener="#{bean.method1}" />
</p:menuitem>
</p:submenu>
<p:submenu label="Search By Product">
<p:menuitem value="Delete" ajax="false" icon="ui-icon-close"/>
</p:submenu>
<p:submenu label="Location" icon="ui-icon-extlink">
<p:submenu label="Prime Links">
<p:menuitem value="Prime" url="http://www.prime.com.tr" />
<p:menuitem value="PrimeFaces" url="http://www.primefaces.org" />
</p:submenu>
<p:menuitem value="Mobile" />
</p:submenu>
</p:slideMenu>
Try change your code to the following:
<p:menuitem>
<p:outputLabel value="Search by Id" />
<p:inputText id="inputField" value="#{bean.value1}" />
<p:commandButton process="inputField #this" value="save" actionListener="#{bean.method1}" />
</p:menuitem>
Check these answers too:
Why to add process=“#this” explicitly to p:commandButton to get action invoked?
Understanding process and update attributes of PrimeFaces
You miss the update attribute.
Note that menuitems can be directly processed, but cannot be directly updated, you need to update the entire menu
<p:slideMenu id="menu" ...>
<p:submenu label="Search">
<p:menuitem id="item">
<p:outputLabel value="Search by Id" />
<p:inputText value="#{bean.value1}" />
<p:commandButton value="save" actionListener="#{bean.method1}" process="item" update="menu" />
<h:outputText value="#{bean.value1}" />
</p:menuitem>
</p:submenu>
</p:slideMenu>

<o:massAttribute> affects another components in same <h:panelGrid>

I'm using the new version of OmniFaces 1.8.1, and particullary I start to use the new tag: <o:massAttribute>. Basically, I have the following form with conditionally rendered and disabled fields:
<h:form id="formABMProducto">
<h:panelGrid id="datosProducto" columns="4">
<o:massAttribute name="rendered" value="#{cc.attrs.page != 'baja'}">
<h:outputLabel for="codigo" ... />
<h:inputText id="codigo" ... />
<rich:message for="codigo" />
<h:panelGroup />
</o:massAttribute>
<o:massAttribute name="rendered" value="#{cc.attrs.page eq 'baja'}">
<h:outputLabel for="codigo" .../>
<rich:autocomplete id="codigoProducto" ... />
<rich:message for="codigo" />
<h:panelGroup />
</o:massAttribute>
<o:massAttribute name="disabled" value="#{cc.attrs.disableComponents}">
<h:outputLabel for="nombre" ... />
<h:inputTextarea id="nombre" ... />
<rich:message for="nombre" />
<span />
<h:outputLabel for="descripcion" ... />
<h:inputTextarea id="descripcion" ... />
<rich:message for="descripcion" />
<span />
</o:massAttribute>
<h:outputLabel value="#{msgs['producto.abm.panel.proveedor.tipo']}" for="CmbTipoProveedor"/>
<rich:select id="CmbTipoProveedor" ... />
<rich:message for="CmbTipoProveedor" />
<a4j:commandButton ... />
</h:panelGrid>
</h:form>
However, when I open the page, the third <o:massAttribute> is also disabling another input fields codigo and codigoProducto. I think this isn't the expected behaviour.
Indeed, this was a bug. The <o:massAttribute> got applied on all children of the parent UIComponent instead of only those contained in the tag. It would theoretically have worked when you've wrapped each <o:massAttribute> in its own UIComponent like <h:panelGroup> or so. However, this is clearly not an option in case of a <h:panelGrid> wherein you'd like to put the children each in its own column.
I reproduced your problem, filled issue 51 about this bug and fixed it in the current 2.0 snapshot. Please give it a try and sorry for any inconvenience.

Resources