JSF Panels positioning - java

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.

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();
});
});

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>

Cancellation of Ajax Request in RichFaces

I have issue with canceling Ajax Request. Our application interface is build in RF.
On the progress bar modal there should be cancel button - that interupt current operation,
for example cancel filling controls from database. How to make it?
I tried using reloading page, flags with "if" conditions on getters for controls and also using "bypassUpdates" with no positive effects.
Thanks in advance for your help
XHTML (Button):
<a4j:commandButton id="showData"
value="View" styleClass="hBtn"
disabled="#{events.isButtonsDisabled}"
oncomplete="if (#{facesContext.maximumSeverity==null})
{window.open('/seed/pages/data.jsf','DATA')};"
actionListener="#{events.actionShow}"/>
JAVA: (Button):
public void actionShow(ActionEvent evt) {
//Some logic, getting data from database
}
XHTML (Main Page - showing wait Popup)
<a4j:form>
<a4j:status id="ajaxStat"
onstart="Richfaces.showModalPanel('waitPanel');"
onstop="#{rich:component('waitPanel')}.hide()" />
</a4j:form>
XHTML (Popup):
<rich:modalPanel id="waitPanel" autosized="true" moveable="false"
minWidth="250" styleClass="popup">
<f:facet name="header">
<h:panelGroup>
<h:outputText value="Operation in progress"></h:outputText>
</h:panelGroup>
</f:facet>
<f:facet name="controls">
<h:panelGroup>
<h:graphicImage value="../images/icons/action_close.gif" styleClass="hidelink" id="hidelink"/>
<rich:componentControl for="waitPanel" attachTo="hidelink" operation="hide" event="onclick"/>
</h:panelGroup>
</f:facet>
<a4j:form id="msgFrm" ajaxSubmit="true">
<h:outputText value="Please wait..."/>
<h:graphicImage styleClass="progressBar" value="../images/indicatorbar.gif"/>
<a4j:commandButton value="Cancel" type="button"
onclick="#{rich:component('waitPanel')}.hide()"
action="#{main.cancelAction}"
bypassUpdates="true"/>
</a4j:form>
</rich:modalPanel>
JAVA (Popup):
public void cancelAction(){
//there was setter for true/false flag for actionShow() here, now there is nothing here (it was not working)
}
Reloading the page stops all current ajax requests. It does not stop the java backing beans from finishing the requests but I assume that is not the question.
c:if and the ajax render do not mix very well. Possibly you could use 'rendered' to disable updating the controls? Then split the control in two parts. One is shown with valid data and for example bright blue. The other is rendered without any data and has a grey picture.
But... I'm not sure I understand the question correctly.
Edit 23-1-2012: Seeing the code I would say that the cancelAction must set a flag that then finishes the action running inside actionShow(). Then the ajax request finishes and the popup is closed. Can't see why this won't work.

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

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!

Can't persist my input text

I have an input text area, inside a panel grid. This panel grid is only rendered when a check box is ticked. I'm using a value change listener to listen to the check box to render the text area. This rendering mechanism works, but the trouble is that I can't retrieve the value the user inputs in the text area. It always returns null. Any help appreciated.
// if box is checked, input text area is rendered
public void showURL(ValueChangeEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
boolean value = (Boolean) event.getNewValue();
setRenderURL(value);
context.renderResponse();
}
<h:panelGrid columns="2" >
<h:outputLabel value="Is position vacant?" />
<h:selectBooleanCheckbox valueChangeListener="#{formBean.showURL}"
onclick="submit()"
immediate="true" />
</h:panelGrid>
<h:panelGrid columns="2" rendered="#{formBean.renderURL}" >
<h:panelGroup>
<h:outputLabel value="Link: "/>
// trouble here: getURL always returns null
<h:inputText size="60" value="#{formBean.URL}" />
</h:panelGroup>
</h:panelGrid>
Add
<h:inputHidden value="#{formBean.renderURL}" />
to the same form so that the condition for the rendered attribute is retained during the request wherein input components are processed. JSF namely won't validate/convert/update an input component whenever the rendered attribute of it or one of it parents evaluates false.

Categories