How to center a ice:confirmationPanel within a modal ice:panelPopup (ICEfaces)? - java

If a (modal) ice:confirmationPanel within a modal ice:panelPopup is used, the confirmationPanel will not be centered; instead it seems to be centered relative to the panelPopups upper left edge.
This seems to be caused by the inline style of the panelPopup. It says position: absolute. Because it is rendered as inline style, I don't know how to change it to position: fixed which seems to solve the problem.
Additional information:
In my case it would be no solution to put the confirmation panel outside the panelPopup, because the confirmationPanel is part of a Facelets-Component (ui:composition). Whenever this component is used inside a panelPopup, this problem arises.
Any solution proposals?

Just place the panelConfirmation outside the panelPopup. This way the confirmation panel will be centered, and it will be over the popup panel.
<ice:panelPopup autoCentre="true" modal="true" draggable="true">
<f:facet name="header">
<ice:panelGroup>
<ice:outputText value="Edit" />
</ice:panelGroup>
</f:facet>
<f:facet name="body">
<ice:panelGroup>
<ice:commandLink value="Edit" panelConfirmation="editConfirm" actionListener="#{editor.edit}"/>
</ice:panelGroup>
</f:facet>
</ice:panelPopup>
<ice:panelConfirmation id="editConfirm" />

I ended up creating my own popup component, which uses position: fixed divs instead of iframes - works perfect!

Related

Floating p:calendar when scrolling

I am using PrimeFaces 5.0.5 with GlassFish server 3.1.2.2.
I added <p:calendar> inside a <ui:fragment> which is then included in another XHTML page.
When I open the select menu and scroll with the mouse wheel, the panel will float with the page.
I've already checked this question with a similar issue but not on the same component.
The same trick doesnt work for calendar. I've tried appending it to components around but none of them works.
Any feedback and comment are appreciated.
Many thanks.
<h:panelGrid columns="2" id="..." style="margin: 0px 0px 30px 15px;">
<h:outputText value="#{msg['startDate']}:"/>
<p:calendar
pattern="dd-MM-yyyy"
converterMessage="#{msg['ocs.invalidStartDateFormat']}"
value="#{cc.attrs.inputObject.usageHistoryStartDate}"
disabled="#{cc.attrs.inputObject.usageHistoryBillingPeriodOption != 'CUSTOM_DATE_RANGE'}"
showOn="button">
</p:calendar>
<h:outputText value="#{msg['endDate']}:" />
<p:calendar
pattern="dd-MM-yyyy"
converterMessage="#{msg['invalidEndDateFormat']}"
value="#{...}"
disabled="#{...}"
showOn="button">
</p:calendar>
</h:panelGrid>
Not sure if this would help you, but my workaround is to add a scroll event on the dialog or whatever container component you have. In the scroll event, you look for the datepicker element and hide it. Here is a snippet:
$(document).ready(function() {
var dialog1 = $('.ui-dialog .ui-dialog-content');
dialog1.scroll(function() {
$('#ui-datepicker-div').hide();
});
});

Primefaces datatable cell editing doesn't update

I have a primefaces datatable with cell editing which is toggled on a boolean variable in the view.
I have three issues:
In edit mode, I change a value and I click the save button on the page it doesn't keep the new value, If I click anywhere else first on the page then click save it will keep the value. I need it to keep the value if you click save first.
If I edit a cell which is an input text and I click out the field now is a output text until I click in there again. I want the field to look like a input text while in edit mode.
When the save button is clicked the backing method sets the editable boolean to false, and the rest of the page obeys, and the dataTable looks like it obeyed but if you click a cell it will let you edit it.
Here is the code:
<p:dataTable value="#{view.LineItems}" var="lineItem" rowKey="#{lineItem.lineItemId}"
resizableColumns="false" editable="#{view.editable}" editMode="cell"
editingRow="#{view.editable}" id="requestLineItemsTable">
<p:ajax event="cellEdit" listener="#{view.cellEdited}" immediate="true" update="#this" />
<p:column styleClass="centerColumnData" headerText="Item Name" style="width: 140px;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{lineItem.title}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{lineItem.title}"/>
</f:facet>
</p:cellEditor>
</p:column> ...
and this is the back end (not doing anything with this yet)
public void cellEdited(CellEditEvent event)
{
Object oldValue = event.getOldValue();
}
and here is the save and edit buttons on the same .xhtml page as datatable
<p:commandLink process="#this"
action="#{view.changeModeToEdit}"
update="#form"
rendered="#{!view.editMode">
<h:graphicImage library="images" name="edit20.png" title="#{__Common.edit}"
style="height: 15px; width: 15px;"/>
</p:commandLink>
<components:linkWithSpinner linkStyle="margin-right: 20px;" loadingImageStyle="margin-right: 20px;"
linkStyleClass="activeButton saveButtonRequestDetails" loadingImageStyleClass="saveButtonRequestDetails"
linkText="#{__CommonButton.save}"
process="#form" update="#form"
actionMethod="#{view.updateRequest()}"/>
view.updateRequest() sets the editable to false. I am using Primefaces 4.0
So I figured out a way around these issues. I was focused on using the built in edit table , but you can just have a normal datatable and the columns can contain input text fields. Then you don't have to worry about most of the issues in my question above. If you need to switch between edit and non-edit view then I still don't know how to fully fix it except have two datatables in your file with render tags, but then you are duplicating the table one with input text fields and one with output text fields, and that is not the best way to do it.

JSF Panels positioning

I am able to set my panel's position then update it however I have trouble when getting its current position.
For example:
Currently, my panel is positioned at (50, 50).
<h:form id="testForm">
<p:panel id="pane" style="position: absolute; left:50px; top:50px;">
<p:panelGrid columns=4>
<p:outputPanel id="ASlot3" styleClass="slot"/>
<p:outputPanel id="ASlot4" styleClass="slot"/>
<p:outputPanel id="ASlot5" styleClass="slot"/>
<p:outputPanel id="ASlot6" styleClass="slot"/>
</p:panelGrid>
</p:panel>
<p:draggable id="drg" for="pane"/>
<p:commandButton id="press" action="#{sbean.press}"/>
</h:form>
I update its position via dragging the panel. After dragging it, I press a button holding this method printing the contents of "style".
//press() method
UIViewRoot viewRoot = FacesContext.getCurrentInstance().getViewRoot();
UIComponent component = viewRoot.findComponent("testForm").findComponent("pane");
Panel p = (Panel) component;
System.out.println(p.getAttributes().get("style"));
The "style" does not update after dragging the panel and pressing the button.
So how can I get my panel's current position after dragging?
EDIT: BTW, the scope I'm using is #ViewScoped
By default the PrimeFaces commandButton component operates with Ajax functionality, meaning that for the form submit to process the component with id pane you would need to declare that in the process attribute.
<p:commandButton id="press" action="#{sbean.press}" process="#this pane"
update="#this pane" />
The other option is to simply process and update the whole form.
<p:commandButton id="press" action="#{sbean.press}" process="#form"
update="#form" />
Or you can simply set Ajax functionality to Off and it will operate like a typical form submit control.
<p:commandButton id="press" action="#{sbean.press}" ajax="false" />
EDIT: I see though that the Primefaces draggable does not update the absolute position of the component to the server's View State. This is unfortunate but it can be worked around using hiddenInputs and a Javascript.
<script type="text/javascript">
function updatePanelPosition() {
var panel = jQuery('#testForm\\:pane');
var hiddenLeftInput = jQuery('#testForm\\:hiddenLeft');
var hiddenTopInput = jQuery('#testForm\\:hiddenTop');
var left = panel.css('left');
var top = panel.css('top');
hiddenLeftInput.val(left);
hiddenTopInput.val(top);
}
</script>
<h:inputHidden id="hiddenLeft" value="#{viewScopedBean.leftProperty}" />
<h:inputHidden id="hiddenTop" value="#{viewScopedBean.topProperty}" />
<p:commandButton id="press" action="#{sbean.press}" process="#form"
update="#form" onstart="updatePanelPosition()" />
The two hidden input components will get updated with the current left and top property of pane just before the submit, and then those values will get updated to managed bean properties where you will be able to fetch the values.
I know it seems messy but in the end this is really what the managed bean is good for, acting like a view controller and containing presentation logic.

JSF p:commandLink and p:ajax have different behavior in update

I have a menu with list items and a p:commandLink inside. While using this for different pages I realized that I have problems updating form with a p:dataTable and p:columns inside. After clicking on the link, form2 which actually has some panels and the table inside should be updated. Now my problem: Only most of the content in form2 is updated correctly, but the p:columns have the old value. If I click again on the link, the correct values are shown.
The bean method public void selectProject(Project myProject) is called correctly and the values are correctly processed.
Now the strange thing: If I add a h:graphicImage with a p:ajax everything works fine!!
<h:form id="form1">
...
<li>
<p:commandLink update=":form2" actionListener="#{bean.selectProject(p)}">
<h:outputText value="#{p.name}" />
</p:commandLink>
<!-- Code below is for testing only, but works fine! -->
<h:graphicImage value="#{iconBean.icon(12,'clock')}">
<p:ajax event="click" update=":form2" listener="#{bean.selectProject(p)}"/>
</h:graphicImage>
</li>
...
</h:form>
Update This does not seem to be related to p:columns, a simplified test case shows the expected behavior of p:commandLink. In the original (still failing) setting the menu is implemented as a composite component.
As a workaround I use
<h:commandLink>
<h:outputText value="#{p.name}"/>
<p:ajax event="click" update=":form2" listener="#{bean.selectProject(p)}"/>
</h:commandLink>

Update component without specifying the absolute client id

The code fragment below represents an editor. In my application, a windows displays a group of editors in a tab panel, each tab containing a datatable with the editors as rows. When a node is selected, its text will be displayed in the organizationUnit input text. The editor shouldn't know about it's parents. Is it possible to update organizationUnit without using the absolute client id?
<p:tabView value="#{accountsBean.groups}" var="group">
<p:tab title="#{eval.getString(group.name)}">
<p:dataTable value="#{group.editors}"
var="editor">
<p:column>
<custom:include src="#{editor.component}">
<ui:param name="bean" value="#{editor.beanName}"/>
<ui:param name="mandatory" value="#{editor.mandatory}"/>
<ui:param name="name" value="#{editor.name}"/>
</custom:include>
</p:column>
</p:dataTable>
</p:tab>
</p:tabView>
<h:panelGrid id="containerEditor" columns="2">
<h:outputText value="#{name}: #{mandatory ? '*' : ''}" />
<p:tree value="#{bean.root}" var="node" selectionMode="single" selection="#
{selectedNode}">
<p:ajax event="select" listener="#{bean.onNodeSelect}"
update="update_organization_unit" immediate="true" />
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
<h:outputText />
<p:inputText id="organizationUnit" value="#{bean.selectedItemPath}"
disabled="true" />
</h:panelGrid>
The tab panel is inside a form called form with prependId="false"
When you have components inside different NamingContainers, and those are not nested**, you must use absolute client id.
In your case, if you don't use the separator character at the begining, the findComponent algorithm would search up until it finds a NamingContainer: this would be your p:tree. Then it would try to find the component inside the p:tree, since it's not there, the exception you mentioned is thrown.
On the other hand, If you do use the separator character at the begining, you must use the absolute client id.
Short answers: No. Unless you change the way your components are organized, you can't update organizationUnit without using the absolute client id.
** If NamingContainers are nested, components inside the outter NamingContainer may update ones inside an inner NamingContainer by referencing their id before the id of the actual component they want to update, for example: update="innerContainer1Id:componentId", or even update="innerContainer1Id:innerContainer2:componentId".
Algorithm is explained in the JavaDoc.
A common 'trick' I use to avoid refering to ids is to use binding.
Example:
<h:form>
<p:button binding="#{button}" ...
</h:form>
....
<p:button update=":#{button.clientId}" ...
Note: This doesn't work for some tags like h:outputText that don't generate an id.

Categories