現在、片足を突っ込んでいるプロジェクトの開発は(個人的には)チャレンジングな技術テーマが多いのでやりがいはあるのですが、如何せん割込み作業が多くて集中できないのが辛い…(ノД`)
という愚痴は置いておいて…。
……
…
ある機能が実現できるか検証しているのですが、ざっくり言うと
クライアントサイドで、あるコンポーネントの座標を取得してサーバサイドへ渡す
というものがありました。JSFで、という条件付き…。
そもそもWebで座標って何なん… (´;ω;`)とか思ったのですが、jQuery使うと意外と簡単に取得できるんですね…知らなかった。
ただしoffsetとpositionで少し違うようで、以下サイトが詳しそうです。
http://jquery-master.net/attrcss/offset.php
とりあえず、今回はpositionで簡単なサンプル作りました。
先に動きを書くほうがわかりやすいので、実行結果から。
実行すると以下のような画面が表示されます。
で、ボタンを押すとJavaScriptというかjQueryで取得したラベルの座標を表示
そのまま、BackingBeanへ!
ラベルはドラッグ可能なようにしているので、左下に移動させてみます。
で、ボタンで座標を確認するとそれっぽい値に。
同じくBackingBean
最後は左上に持っていきます。
座標
BackingBean
このサンプルのように、jQueryやJavaScriptを使ってクライアント(ブラウザ)で取得した値を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' ?>
<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">
<h:commandButton value="Bean確認" action="#{draggableCompBean.confirm()}"
onclick="getPosition();" />
<p:outputLabel id="lblDraggable" value="移動可能なラベル" />
<p:draggable id="drg" for="lblDraggable" />
<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力のなさを痛感します……。