ColdFusionカフェテリア
SAMURAIZ

 

| ↑トップへ戻る |

ColdFusionをサーバーロジックのコアとした多彩な連携について

2. CFAjaxProxyを用いたColdFusionと jQueryの連携事例

作成日: 2014年3月31日
作成者: 株式会社構造計画研究所 大塚健太
公開日: 2014年4月9日

1.はじめに

 前回の記事からすっかり時間が経ってしまい、申し訳ありません。構造計画研究所の大塚でございます。前回は、ColdFusion + Flexの連携事例を書きましたが、今回は、CFAjaxProxyを使ったシステムを開発した際のことを書きます。
 初めてColdFusionをお使いになる方もご覧になるかもと思いますので、最初に用語の説明をしてから、サンプルソースの解説を行います。

 

■CFAjaxProxy
 CFAjaxProxyは、cfcで定義したクラスから、対応するインタフェースを持つJavascriptのオブジェクトを自動で生成してくれるColdFusionの仕組みです。Javascriptとサーバ処理の間のギャップ(たとえば、パラメータをURL変数にしてサーバに渡すなど)を埋めてくれている感じがして、個人的には使っていて気持ちのよい機能です。仕様は以下のページにあります。
(http://help.adobe.com/ja_JP/ColdFusion/10.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-79f9.html)
最初に知ったときは、なんと大胆な機能だろうかと思いましたが、今では愛用しています。

■jQuery
  特に説明は必要ないかと思われますが、javascriptの大変すばらしいライブラリです。
 (http://jquery.com/)

2.CFAjaxProxyを用いたColdFusionと jQueryの連携事例

 今回の記事は、某住設メーカー様の浴室選定システムを作った際の事例を基にしています。
 弊社で、コンフィグレータという組み合わせ管理エンジンを取り扱っているご縁で、機会を頂いたものでした。コンフィグレータの役割は、[部品Aと部品Bは一緒に選べない] [部品Cと部品Dは必ず一緒でなければならない] などと言った制約を管理することなのですが、そのエンジンのUIをColdFusionで作成することになったのでした。
 コンフィグレータに入っているデータに基づいて、部品を選択していくと、リアルタイムにイメージ画像が更新されて、同時に価格もわかる、というようなUIが要求されました。浴槽の色が変わった、形が変わった、など小さな変更のたびにPOST処理を実行すると画面がちらついて大変だ、ということで、Ajaxを使ってイメージ画像内の変更された部材だけを描き直すようにしよう、ということになりました。


システム構成は図1のような感じでした。

 



図1 商品選定システムの構成


 コンフィグレータとブラウザの間でやり取りをして、浴室の仕様を決めると結果がXMLファイルに出力され、そこからいろいろな成果物(図面や帳票や完成イメージ図など)が生成されるイメージです。
 作図を伴うシステムは、目に見えて動いているのを感じるので、テストのときもちょっと楽しかったのを覚えています。

3.疑似コードご紹介

 ざっと雰囲気が伝わるように、疑似コードを作りましたので、内容を簡単に紹介します。

 view.cfmが選定画面です。選ばれているラジオボタンのID配列を渡すと、次に選択できるラジオボタンが分かるようなプログラムで、ピザ屋でピザを選ぶシーンを想定して作りました。実際には、コンフィグレーションエンジンと連携して動くのですが、今回は、cfcで「コンフィグレータもどき」を作りました。

 



図2 サンプルコードの構成

 


 

 ラジオボタンで生地・ソース・トッピングを選択するたびに、チェックボタンを押下すると、選択肢と金額が更新されていく仕組みです。最後に、XML表示ボタンを押下すると、画面が遷移して、結果のXMLが表示されます。

 


 

次にコードの説明です。

 

■cfmのサンプル

<cfajaxproxy cfc="simpleconfigurator.logic.configurator" jsclassname="simpleconfig">
<cfprocessingdirective pageencoding="utf-8">

<cfoutput>

<html>


<head>
    <title>サンプルページ</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
    <script type="text/javascript" src="js/script.js"></script>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
    <div style="width:400px; background-color:##f5deb3; margin-left:auto; margin-right:auto; padding:5px; ">
        <p>■生地を選択</p>
        <input type="radio" name="base" id="r_0">ふんわり
        <br>
        <input type="radio" name="base" id="r_1">サクサク
        <hr>
        <p>■ソースを選択</p>
        <input type="radio" name="source" id="r_2">トマトソース
        <br>
        <input type="radio" name="source" id="r_3">ホワイトソース
        <br>
        <input type="radio" name="source" id="r_4">バジルソース
        <br>
        <hr>
        <p>■トッピングを選択</p>
        <input type="radio" id="r_5">サラミ
        <br>
        <input type="radio" id="r_6">ソーセージ
        <br>
        <input type="radio" id="r_7">あさり
        <br>
        <input type="radio" id="r_8">ポテト
    </div>
    <p/>
    <div style="width:400px; background-color:##f0e68c; margin-left:auto; margin-right:auto; padding:5px; ">
        <input type="button" value="チェック" id="btnChk">
        <br>
        金額は
        <label id="price">\0</label>
        円です
        <br>
        <input type="button" value="XML表示" id="btnXml">
    </div>
</body>

</html>

</cfoutput>

 

 重要なのは、先頭のcfajaxproxyタグです。ajax的に利用したいロジックを持つcfcのクラス名と、javascriptのプロキシクラスの名称を指定します。 ロジック類は、読み込まれているscript.jsというファイルに記述しています。

 

■cfcのサンプル

<!---
* 計算
* 価格と次の状態を含むStructを返す
--->

<cffunction name="doCalc" access="remote" returntype="Struct" returnformat="JSON">
<cfargument name="lst" required="true" type="string" >

<cfif initialized EQ false>
    <cfset this.init()>
</cfif>

<cfscript>
    var stRet = structNew();
    stRet.IsError = false;
    stRet.Price = 0;
    stRet.NextState = ArrayNew(1);
</cfscript>

<cftry>

    <!--- 価格を計算 --->
    <cfset var arraySelected = ListToArray(#lst#)>
    <cfscript>
        var price = 0;
        var cnt = 0;
        var len = arraylen(arraySelected);
        for(cnt = 1; cnt<=len; cnt++)
        {
            var key = arraySelected[cnt];
            price = price + s_MapPrice[key];
        }
    </cfscript>
    <cfset stRet.Price = price>

    <!--- 次の状態を取得 --->
    <cfset stRet.NextState = s_MapState[#lst#]>

<cfcatch type="any">
    <cfset stRet.Price = 0>
    <cfset stRet.IsError = TRUE>
    <cfset stRet.NextState =s_MapState[""]>
</cfcatch>
</cftry>

<cfreturn stRet>
</cffunction>

 

 <cffunction>タグの access="remote" returntype="Struct" returnformat="JSON"
 という指定がポイントです。これらの指定によって、Javascriptのインタフェースが生成され、ColdFusionの構造体がJavascriptのオブジェクトになってブラウザに届くことになります。

 

■javascriptのサンプル

$('#btnChk').click(
    function()
    {
        // 選択されている要素を集める
        var radios = $('input[type="radio"]:checked');
        var params = "";
        currentParams.length = 0;
        for(var nCnt = 0; nCnt<radios.length; nCnt++)
        {
            var tgt = radios.eq(nCnt);
            var num = tgt.attr("id").substring(2);

            params = params + num;
            currentParams.push(num);

            if(nCnt != radios.length-1)
                params = params + ",";
        }

        var conf = new simpleconfig();
        conf.setCallbackHandler(callbackOK);
        conf.setErrorHandler(callbackError);
        conf.doCalc(params);
    }
);

 

 チェックボタンの押下処理です。simpleconfigオブジェクトを生成して、正常終了時のコールバック関数とエラー時のコールバック関数を設定し、インタフェースの処理を呼び出しています。

 

var callbackOK = function(result)
{
    if(result.ISERROR == true)
    {
        alert("選択できない組み合わせです。");
        $('input[type="radio"]').attr('checked', false);
    }
    else
    {
        // 金額を更新
        $('#price').text("\\" + result.PRICE.toString().replace(".0", ""));
    }

    //ラジオボタンを更新
    var radios = $('input[type="radio"]');
    var nCnt = 0;
    for(nCnt = 0; nCnt<radios.length; nCnt++)
    {
        var tgt = radios.eq(nCnt);
        var num = tgt.attr("id").substring(2);
        if( containes( result.NEXTSTATE, num) )
        { // 選択可能
            tgt.attr('disabled', false);
        }
        else
        {
            // すでに選択されているものは除く
            if( containes( currentParams, num) )
                continue;

            // 選択不可
            tgt.attr('checked', false);
            tgt.attr('disabled', true);
        }
    }
}

var callbackError = function(statusCode, statusMsg)
{
    trace(statusMsg);
}

 

 コールバック処理です。結果を受け取って、画面を更新しています。

 

 長いことメンテナンスを続けているColdFusionのソースで、cfmファイルにロジックがモリモリ記述されていて、読むのに苦労する、といった経験をされている方がたくさんいるのではないかと思います(…私もです)が、cfajaxproxyを利用すると、MVCの役割分担を明快にしやすいので、よりよいコードが書けるようになるのでは??などと個人的には期待しています。

 

4.ダウンロード

以下のColdFusionプロジェクトファイルに、今回のサンプルCFM, CFC, JSが含まれています。

  ファイル名 ファイルサイズ  
Download simpleconfigurator.zip 7kb ・ColdFusion Builder用プロジェクトファイル
 (CFM, CFC, JS)

5.終わりに

 ColdFusionをUI以外の部分に活用する方法について、2回に分けてご紹介いたしましたが、いかがでしたでしょうか?少しでも、何かのお役に立てたならば幸いなのですが…。
 ColdFusionの新しいバージョンの話も耳に入るようになり、phonegapとの連携など、大胆で面白い機能が今後も増えていくようなので、きちんとキャッチアップせねば、と思っている次第です。ではまたどこかで。

ColdFusionの各種情報の配信


最新情報
■2017/3/27
ColdFusion 2016 対応
インストール セットアップ情報
CFサーバーのインストール
CFビルダーのインストール

■2016/9/20
『ColdFusion 2016 リリース
Enterprise Edition 活用資料』
記事一覧

■2016/3/30
『ColdFusion 実験室』
実験4、実験5

■2015/8/10 〜
『ColdFusion クリニック』
記事一覧(随時更新中)

■2015/4/8
『JasperReportsによる帳票出力』
2. JasperReportsによる帳票出力【後編】

■2015/3/12
アップクロス株式会社
西元 貞昭様
『JasperReportsによる帳票出力』
1. JasperReportsによる帳票出力【前編】


■2015/2/25
『ColdFusionでエクセルを使いこなそう!』
4. 【上級】ColdFusionのエクセル機能を利用したPDF帳票の紹介

ColdFusionトレーニング


ColdFusionユーザーグループ
ColdFusionユーザーグループ
Copyright 2012 Samuraiz Corporation. All Rights Reserved.