JSF dropdown list inside a tab header - jsf

I'm using JSF and rich faces 4.5.5 and I'm trying to display a dropdown in the header of a tab panel. So far this is what I have:
<rich:tabPanel id="reportTabPanel" >
<a4j:repeat var="reportCategory" value="${workBean.categories}">
<rich:tab>
<f:facet name="header">
<h:panelGroup>
<h:selectOneMenu value="#{reportCategory.currentSelection}" style="background:none;border:none;width:15px">
<f:selectItems value="#{reportCategory.availableReports}" />
</h:selectOneMenu>
<h:outputText value="#{reportCategory.displayedTitle}" />
</h:panelGroup>
</f:facet>
<div id="reportContent" name="content" >
<h:outputText value="#{reportCategory.displayedContent}" escape="false" />
</div>
</rich:tab>
</a4j:repeat>
</rich:tabPanel>
It displays fine. I have the drop-down arrow displayed on the left and the tab's name on the right of each tab header. However the event handling is dodgy. When I click the dropdown, the list opens and closes as soon as I release the button (preventing me from making a selection in the list). In order to select anything from the dropdown list, I have to keep the mouse button pressed and release it outside of the header area so that the list does not close. Only then am I able to select my option in the dropdown zone.
I believe that the tab header is grabbing the release button event and using it to change tab if needed (which seems obvious).
What I would like is the dropdown to take priority over the tab header. Anyway of doing that?
Alternatively, is there a way of opening the dropdown when it is hovered over?
I'm not a huge expert in JSF. I've tried looking at implementing a custom Renderer but my issue is more to do with events than visual so not sure that is the right way to go. Any suggestion? Pointers?
Thanks
w.

Simply add onclick="event.stopPropagation()" to the h:selectOneMenu, that will prevent the click event reaching the tab.
(That said why do you need a select in the tab header? It's a navigation element.)

Related

Richfaces: rich:select click event fails

I am using a rich:select, which I want to repopulate when it is clicked on the page. I tried this using a4j:ajax listening for the onClick-Event, but it seems like it is never received. For testing purposes I added an alert to the control, that is shown after an unpredictable number of clicks. The code in my Backing Bean is never called.
If I change the control to h:selectOneMenu it works, but the list collapses immediately so that the users cannot select an item. Additionally the manual input is a required feature.
Code in my JSF-Page:
<rich:select id="auftragsIdsCombo" value="#{einsatzController.einsatz.auftrag.id}" enableManualInput="true" onclick="alert('hi')">
<f:selectItem itemLabel="" noSelectionOption="true" />
<f:selectItems value="#{einsatzController.auftragsIds}" />
<a4j:ajax event="click" render="auftragsIdsCombo" listener="#{einsatzController.loadAuftragsIds()}"/>
</rich:select>
Maybe there is another way of doing this, wich I am not aware of. I just want to load the items after clicking on the Dropdownbox, so that the users can either select one or use autocompletion by typing into the control.
Regards

Setting bean property before opening Primefaces dialog

I would like to achieve this functionality.
<p:column>
<p:commandLink value="prihlasit" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
</p:column>
I think is pretty clear what I am trying to do, I would like to display detail of the row in dataTable on which user have clicked. So my approach is to set property of current row to bean and then show the detail in dialog. But it is not working and I am feeling that I am doing something really wrong:-)
If the dialog component is supposed to display the selected item, then you need to ajax-udpate the dialog's content before opening it. Otherwise it will still display the old content as it was when the page is rendered for the first time.
<p:commandLink value="prihlasit" update=":dlg" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
...
<p:dialog id="dlg" ...>

Displaying read-only forms (values are shown as text instead of disabled input controls) with JSF?

I have a data entry form where user enters lots of data. When user comes to the page to view existing data, the page should be displayed in read-only mode (all values shown as text), when he clicks 'Edit' button, normal form with all input controls should be shown so that user can change and save data.
We are using JSF 2.0 with PrimeFaces library. It is easy to achieve above behavior for text box and text area but not for Checkbox, multi-select, radio,..... controls. Is there any easy way available to achieve above behavior rather than writing our own code (which may run into lot of lines thus making backing bean code ugly)
Thanks for your help...
I'm not sure why you think that you need additional backing bean code for this. You've all the needed values in the backing bean already. Your problem is more in the presentation of those values. Just display them in the desired format by writing the view code accordingly. Perhaps you were thinking it too the hard way.
Instead of a select boolean checkbox, you could display for example a "Yes" or "No" value.
<h:selectBooleanCheckbox value="#{bean.checked}" rendered="#{bean.edit}" />
<h:outputText value="#{bean.checked ? 'Yes' : 'No'}" rendered="#{not bean.edit}" />
Instead of a select one menu/radio, you could just display the value in an output text.
<h:selectOneMenu value="#{bean.selectedItem}" rendered="#{bean.edit}">
<f:selectItems value="#{data.availableItems}" />
</h:selectOneMenu>
<h:outputText value="#{bean.selectedItem}" rendered="#{not bean.edit}" />
Instead of a select many listbox/checkbox, you could just display for example all values comma separated in a loop.
<h:selectManyListbox value="#{bean.selectedItems}" rendered="#{bean.edit}">
<f:selectItems value="#{data.availableItems}" />
</h:selectManyListbox>
<h:panelGroup rendered="#{not bean.edit}">
<ui:repeat value="#{bean.selectedItems}" var="selectedItem" varStatus="loop">
#{selectedItem}#{not loop.last ? ', ' : ''}
</ui:repeat>
</h:panelGroup>
You could wrap it all in a tag file or a composite to minimize boilerplate and code repetition.
I've done this in my last project using composite components which has a "preview" attribute and in the implementation I render a text when this attribute is true and the real (editing) when the attribute is false. For checkbox in preview mode you could show the checkbox itself but disabled, for radio - show the selected item.
MyFaces Tomahawk library [1] contains an extended version of the standard components that adds displayValueOnly attribute for this purpose. This might help you (I haven't used them).
[1] - http://myfaces.apache.org/tomahawk-project/tomahawk20/index.html

How to fix extendedData selection change when not focused

We have a page in a seam application using richfaces that contains an extendedDataTable plus one or more list boxes. We've found that, once you select something in the extendedDataTable and then switch to one of the list boxes, the extendedDataTable keeps responding to the up and down arrow keys, so if you use them to change the selection in the currently highlighted list box, the selection in the extendedDataTable changes as well.
Is there a workaround to stop the extendedDataTable changing selection when it doesn't have focus?
Unfortunatly the code is rather complex, but the xhtml for the table is (without all the columns for simplicity):
<rich:extendedDataTable id="jobManJobListTable" enableContextMenu="false"
value="#{jobman_view.paginatedJobList}" var="job" rows="25" selectionMode="multi"
selection="#{jobman_view.jobListSelection}" height="">
<a4j:support event="onselectionchange" reRender="detailsDiv,customerDiv"
action="#{jobman_view.onJobSelectionChange()}"/>
<rich:column width="10%" sortable="true"
label="#messages['jobman.ui.joblist.table.column.heading.type']}">
<h:graphicImage value="../img/job_type_#{job.jobType.imageName}_16x16.png"/>
<rich:toolTip>
<span style="white-space: nowrap">
<strong>#{job.jobType.name}</strong>
</span>
</rich:toolTip>
</rich:column>
</rich:extendedDataTable>
Note the table is not included in any of the divs listed in the a4j:support Rerender.
As for the backing bean, the paginatedJobList is just a list of jobs, onJobSelectionChange changes job the backing bean thinks is selected so that the detail div's contain the correct data when reRendered, and jobListSelection is just a getter/setter for a SimpleSelection.
It seems to be related to the a4j:support, without it the selection doesn't apear to change when another control has focus.
You can write a smart JS function and attach it to onkeypress attribute of the extendedDataTable
This function could disable the scrolling when something is selected, and enable back to it when nothing is selected.

Opening a Rich Modal Panel on Button Click

I m trying to open a rich modal panel with populated data on a button click
tried
<h:commandButton id="btn_search" value="#{text['button.add']}"
action="#{cartBean.search}"
oncomplete="#{rich:component('dlg_results')}.show()">
</h:commandButton>
and
<h:commandButton id="btn_search" value="#{text['button.add']}"
action="#{cartBean.search}" immediate="true">
<rich:componentControl for="dlg_results" attachTo="btn_search" operation="show" event="onclick"/>
</h:commandButton>
This code opens the model panel on button click but when response is sent back from the server the whole page gets refreshed
can some one suggest a way to handle this ???
Use <a4j:commandButton> instead of h:commandButton.
Thanks, this was helpful information.
I used showWhenRendered tag in rich:modalpanel to solve my problem. I added a variable in my bean and set its value to true on click of button if records are found.

Resources