How to fix extendedData selection change when not focused - jsf

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.

Related

How to build a dynamic grid and only show three columns in a row (JSF 2.2 and BootsFaces)

I am trying to layout a page with Bootsfaces and JSF 2.2. I like to show only three column in a row and then start new row but don't know, how to implement this.
<h:form>
<b:container>
<b:row>
<ui:repeat value="#{ClientBean4.custs}" var="custs">
<b:column col-md="4"><h:outputText id="output" value="#{ClientBean4.counter}" /> </b:column>
<h:panelGroup rendered="#{ClientBean4.counter == 0}">
</b:row><b:row>
</h:panelGroup>
</ui:repeat>
</b:row>
</b:container>
</h:form>
after a long time, I wrote above code, but it's givng error like 'h:panelgroup' should be properly closed. It's giving meaning, that I started panelGroup and then closing a row, starting a new row, and then close panelGroup.
So, Is anyone have idea, how to implement a layout, where a row will have three columns (showing customer's object details per column), then close the row and start a new row. obvisouly, I dont know, how many objects will be in the list.
BootFaces offers a component that handles this. More specifically you can use <b:panelGrid columns="3"> to achieve this. This will give you a dynamic grid system that will grow vertically as you populate it but retain the number of rows that you specify.
You can see the component in action here, https://showcase.bootsfaces.net/layout/panelgrids.jsf
PrimeFaces also has a component for this, but I assume you want to use BootFaces as your original code uses it. If you prefer PrimeFaces, you can use the <p:dataGrid> component, which does something similar. This component even handles pagination.

JSF dropdown list inside a tab header

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.)

Equivalent of RichFaces 4 <rich:popupPanel> for RichFaces 3

I am looking for something like <rich:popupPanel> in RichFaces 4, but then for RichFaces 3. I haven't found anything like in documenation. There is only <rich:modalPanel> which doesn't suit my needs, because it has problems displaying my datamodel in table. The selection doesn't work, it always returns no rows selected. If I put my table component in <rich:panel> or <rich:togglePanel>, then it works fine.
Is there any popup window excluding <rich:modalPanel> in RichFaces 3?
I dont have 50 reputation to ask you more details in a comment, so i will answer directly hoping this is what you're asking about.
I think you mean that your problem is that the content of the ModalPanel is not rerendered dynamically. but for this you can wrap your table (or the components you want to update) in an <a4j:outputPanel> with ajaxRendered="true"
Setting ajaxRendered="true" will cause the <a4j:outputPanel> to be updated with each Ajax response for the page, even when not listed explicitly by the requesting component. This can in turn be overridden by specific attributes on any requesting components.
http://docs.jboss.org/richfaces/latest_4_0_X/Component_Reference/en-US/html/chap-Component_Reference-Containers.html#sect-Component_Reference-Containers-a4joutputPanel
In my code I have something like :
<a4j:commandLink id="timelineBtn" action="#{timelineBean.doGenerateLog}"
oncomplete="Richfaces.showModalPanel('timelinePnl');return false;"
value="#{labels['timeline.button.lbl']}"/>
that opens the modalPanel :
<rich:modalPanel style="width:800;height:600;" id="timelinePnl">
<a4j:outputPanel id="dataPanel" ajaxRendered="true">
<!-- your components to be updated go here -->
</a4j:outputPanel>
</rich:modalPanel>
So my content is updated with the results of my timelineBean.doGenerateLog method each time i open the modalPanel .

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

<rich:datatable> and <rich:datascroller> problem

I am developing a Seam-Jsfv1.2-EJB3 web app.
I have a datatable and checkboxes in each row. Moreover, I have a datascroller at the bottom of my table as well.
My problem is when I click the next page number from the scroller, the selected checkboxes at the first page of the datatable is gone. I mean, even if they were selected, clicking the next page make them deselected. I see it by going back to the first page again by clicking the scroller.
Do you have any idea about that problem?
In order to clearify my case, I attached my code below:
<rich:dataTable
id="apiV2ProductList" rows="10" var="_apiV2Product"
value="#{apiV2ProductList.resultList}"
rendered="#{not empty apiV2ProductList.resultList}" reRender="ds">
<rich:column>
<f:facet name="header">
<h:selectBooleanCheckbox id="selectionCheckAll" onclick="selectAll()" />
</f:facet>
<h:selectBooleanCheckbox id="selectionCheck" onclick="increase(this)" value="#{_apiV2Product.selectValue}" >
</h:selectBooleanCheckbox>
</rich:column>
...
<f:facet name="footer">
<rich:datascroller id="ds" renderIfSinglePage="false">
</rich:datascroller>
</f:facet>
Many thanks in advance.
Baris
You can extend the org.richfaces.renderkit.html.DatascrollerTemplate
write your own DataScroller for your own styling by adding a component with the below configuration in faces-config.xml
<component>
<component-type>exCustHtmlDatascroller</component-type>
<component-lass>org.jsf.common.ui.EXCustHtmlDatascroller</component-class>
</component>
<render-kit>
<renderer>
<component-family>org.richfaces.Datascroller</component-family>
<renderer-type>exCustDataScrollerTemplate</renderer-type>
<renderer- class>org.jsf.common.ui.EXCustDataScrollerTemplate</renderer-class>
</renderer>
</render-kit>
Adding an a4j support tag between scroller has solved my problem:
<f:facet name="footer">
<rich:datascroller id="ds" renderIfSinglePage="false">
<a4j:support event="onpagechange"/>
</rich:datascroller>
</f:facet>
However the other thing is, I am using JQuery to style my table (ex. on mouse over and out), and this time, when I click the next page of my table, the style is gone.
Any help would be great, many thanks in advance.
**
PS: BTW the wierest thing to my mind is it comes me impossible to find a solution by yourself for this kind of problems. Your creation may not always be enough to solve (at least here in my example, adding a4j:support thing) I am asking experts, how can we handle that kind of things by ourselves...
**
You don't need jQuery for styling the datatable
<rich:dataTable id="dataTable" var="x"
onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'"
The problem you were seeing with the styles being removed is due to the nature of AJAX, and the way the table is reRendered.
Assuming you were firing the initial styling call based on some form of page onLoad, the first time the page is rendered, your styles will be applied. However, when you click the "next" button with the paginator, you are pulling a lot of new HTML down, and replacing the old HTML in the table with the newer, updated information. The proble you're seeing is that you saw styling because jQuery applied styles to the old nodes, upon reRender, those nodes are completely thrown away, along with their styling. You simply need to figure out the hook to call the "styling" method, and re-execute that call after the table is re-rendered.
Generally, I use an a4j:status tag, and set up the onstart or onstop to re-parse the table.

Resources