読者です 読者をやめる 読者になる 読者になる

Challenge Java EE !

Java EEを中心に趣味や仕事における開発メモを書いています。

JSFにおいてJavaScriptで取得した値をBacking Beanへ渡す

PrimeFaces JavaScript JSF

現在、片足を突っ込んでいるプロジェクトの開発は(個人的には)チャレンジングな技術テーマが多いのでやりがいはあるのですが、如何せん割込み作業が多くて集中できないのが辛い…(ノД`)

という愚痴は置いておいて…。

……

ある機能が実現できるか検証しているのですが、ざっくり言うと

クライアントサイドで、あるコンポーネントの座標を取得してサーバサイドへ渡す

というものがありました。JSFで、という条件付き…。

そもそもWebで座標って何なん… (´;ω;`)とか思ったのですが、jQuery使うと意外と簡単に取得できるんですね…知らなかった。

ただしoffsetとpositionで少し違うようで、以下サイトが詳しそうです。
http://jquery-master.net/attrcss/offset.php

とりあえず、今回はpositionで簡単なサンプル作りました。

先に動きを書くほうがわかりやすいので、実行結果から。

実行すると以下のような画面が表示されます。

f:id:kikutaro777:20130813210248j:plain

で、ボタンを押すとJavaScriptというかjQueryで取得したラベルの座標を表示

f:id:kikutaro777:20130813210301j:plain

そのまま、BackingBeanへ!

f:id:kikutaro777:20130813210337j:plain

ラベルはドラッグ可能なようにしているので、左下に移動させてみます。

f:id:kikutaro777:20130813210456j:plain

で、ボタンで座標を確認するとそれっぽい値に。

f:id:kikutaro777:20130813210537j:plain

同じくBackingBean

f:id:kikutaro777:20130813210627j:plain

最後は左上に持っていきます。

f:id:kikutaro777:20130813210641j:plain

座標

f:id:kikutaro777:20130813210654j:plain

BackingBean

f:id:kikutaro777:20130813210705j:plain

このサンプルのように、jQueryJavaScriptを使ってクライアント(ブラウザ)で取得した値をBackingBean(管理対象Bean)へ渡したいことってあるよなぁと。

これは以下のサイトを参考に、Hiddenフィールドを利用して実現しています。

How To Pass New Hidden Value To Backing Bean In JSF
JSF Tag + JavaScriptという辺り

Core JavaServer Facesの本にも似たような記述がありました。

というわけで、コードは以下の通りです。
ドラッグ可能なラベルはPrimeFacesのOutputLabelとDraggableコンポーネントを利用しています。

JSFのビュー

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui">
    <h:head>
        <title>座標をサーバサイドへ渡すサンプル</title>
    </h:head>
    <h:body>
        <h:form id="frmDraggableComp">
            <!-- JavaScript実行とactionによるサーバ処理呼び出し -->
            <h:commandButton value="Bean確認" action="#{draggableCompBean.confirm()}"
               onclick="getPosition();" />
            
            <!-- 以下2つでドラッグ可能なラベルを生成 -->
            <p:outputLabel id="lblDraggable" value="移動可能なラベル" />
            <p:draggable id="drg" for="lblDraggable" />
            
            <!-- 座標を保持するHiddenフィールド -->
            <h:inputHidden id="txtHdnLeft" value="#{draggableCompBean.left}" />
            <h:inputHidden id="txtHdnTop"  value="#{draggableCompBean.top}" />
        </h:form>
        
        <script type="text/javascript">
            function getPosition(){
                var lblObj = $("#frmDraggableComp\\:lblDraggable");
                var position = lblObj.position();
                
                alert("左から,上から = " + position.left + "," + position.top);
                
                document.getElementById("frmDraggableComp:txtHdnLeft").value = position.left;
                document.getElementById("frmDraggableComp:txtHdnTop").value = position.top;
            }
        </script>
    </h:body>
</html>

BackingBean(管理対象Bean)

package jp.co.hoge.technicalconfirmation;

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import lombok.Getter;
import lombok.Setter;

@ManagedBean(name = "draggableCompBean")
@ViewScoped
public class DraggableCompBean implements Serializable{

    @Getter @Setter
    private String left;
    @Getter @Setter
    private String top;
    
    public void confirm(){
        System.out.println(left + top);
    }
}

シンプルなわりに強力な感じがしつつも、自分のJavaScript力のなさを痛感します……。

にほんブログ村 IT技術ブログへ
にほんブログ村
にほんブログ村 IT技術ブログ Javaへ
にほんブログ村