【问题标题】:JSF Panels positioningJSF 面板定位
【发布时间】:2013-03-29 21:43:19
【问题描述】:

我可以设置面板的位置然后更新它,但是在获取它的当前位置时我遇到了麻烦。

例如: 目前,我的面板位于 (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>

我通过拖动面板来更新它的位置。拖动它后,我按下一个持有此方法的按钮,打印“样式”的内容。

    //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"));

拖动面板并按下按钮后,“样式”不会更新。

那么如何在拖动后获取面板的当前位置?

编辑:顺便说一句,我使用的范围是@ViewScoped

【问题讨论】:

  • 它可能不应该有所作为,但您是否尝试将组件直接绑定到 bean?
  • @kolossus 可能确实有效并且容易得多。
  • @Francis 在您希望绑定的组件类型的支持 bean 中创建并初始化一个成员变量,例如Panel myPanel = new Panel()(不要忘记 getter 和 setter)。然后在您的视图侧组件上添加binding=#{myBean.myPanel}。您希望与支持 bean 中的组件进行的所有进一步交互现在都应该使用 myPanel 变量。

标签: java jsf primefaces


【解决方案1】:

默认情况下,PrimeFaces commandButton 组件使用 Ajax 功能运行,这意味着要让表单提交处理 ID 为 pane 的组件,您需要在 process 属性中声明它。

<p:commandButton id="press" action="#{sbean.press}" process="@this pane"
  update="@this pane" />

另一种选择是简单地处理和更新整个表单。

<p:commandButton id="press" action="#{sbean.press}" process="@form"
  update="@form" />

或者您可以简单地将 Ajax 功能设置为 Off,它将像典型的表单提交控件一样运行。

<p:commandButton id="press" action="#{sbean.press}" ajax="false" />

编辑:我看到 Primefaces 可拖动不会将组件的绝对位置更新为服务器的视图状态。这很不幸,但可以使用 hiddenInputs 和 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()" />

在提交之前,两个隐藏的输入组件将使用 pane 的当前 left 和 top 属性进行更新,然后这些值将更新为托管 bean 属性,您可以在其中获取值。

我知道这看起来很乱,但最终这确实是托管 bean 的优点,它就像一个视图控制器并包含表示逻辑。

【讨论】:

  • 我尝试了您的建议,但单击按钮后我的面板似乎回到了原来的位置。我在 press() 方法中打印的输出仍然是我的初始样式值position: absolute; left:50px; top:50px;
  • @Francis Ahh 我的印象是 Primefaces Draggable 负责更新服务器端样式属性,但显然不是。我在上面发布了一个编辑。
  • 请问inputHidden 是干什么用的?如果我将它与我的代码放在一起,我的按钮不会调用该方法,但如果我删除它,则该按钮会调用该方法。 leftPropertytopProperty 怎么样?只是要确定。 :)
  • inputHidden 组件是您单击按钮时将提交的附加表单字段。 leftPropertytopProperty 是您必须添加到代码中的附加托管 bean 属性。当您单击按钮时,新的托管 bean 属性将在调用 action 方法时分别具有相应的 left 和 top 值。
  • 哦,好的。现在很清楚了。这次真是万分感谢。这对我有很大帮助。 :D
猜你喜欢
  • 2012-03-14
  • 1970-01-01
  • 2011-06-13
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多