4D Ajax Framework中のカスタム値

この例題では、4D Ajax Frameworkでカスタム値を使用する方法をお見せします。カスタムチデータはWebページ (フロントエンド) から送信され、4Dデータベース (バックエンド) で受信されます。そして4Dデータベース (バックエンド) はクエリを実行し、カスタム値をWebページ (フロントエンド) に送り返し、データはフォーマットされ表示されます。例題はカーディーラーの内部見積もりシステムの形になっていて、ユーザがオプション等を設定すると、自動車の総料金がページに表示されます。


ブランド

ブランドグリッドには、データベース中の自動車メーカーが表示されます。


モデル

モデルグリッドには、データベース中のモデルリストが表示されます。グリッドは、0件の結果を表示するためにダミーのクエリを使用して表示されます。ブランドがクリックされるたびにデータベースが検索され、選択されたブランドのモデルがモデルグリッドに表示されます。


オプション

オプションdiv要素には、選択された自動車モデルのオプションリスト (と関連する料金) が表示されます。このdiv要素はユーザがブランドやモデルをクリックするたびに動的に変更されます。


データの埋め込み

グリッドは以下の設定でデータが埋め込まれます:

ブランドグリッド設定:

JavaScript Code:
var BrandsGrid = new dax_dataGrid('Brands',$('CarBrandDiv'), 0, 0, false);   BrandsGrid.go(); // go   BrandsGrid.disableAutoRefresh(); // disable auto refreshing the grid   BrandsGrid.hideColumn(0); // ID column   BrandsGrid.setColumnWidth(1,80); // Name   BrandsGrid.onDataRowClick = BrandClicked; // call BrandClicked on row click
End JavaScript Code

モデルグリッド設定:

JavaScript Code:
var ModelsGrid = new dax_dataGrid('Models',$('CarModelsDiv'), 0, 0, false);   ModelsGrid.go(); // go   ModelsGrid.disableAutoRefresh(); // disable auto refreshing the grid   ModelsGrid.setColumnWidth(0,110); // Model Name   ModelsGrid.hideColumn(1); // model ID   ModelsGrid.newQuery(); //start a new query   ModelsGrid.addQuery('brandID', '=', 0); // query to get 0 results   ModelsGrid.runQuery(); // run the query   ModelsGrid.onDataRowClick = ModelClicked; // set on clicked event
End JavaScript Code


クリックイベント

ブランドとモデルグリッドがクリックされると、以下の関数が実行されます:

BrandClicked() 関数定義:

JavaScript Code:
function BrandClicked(row, column, recordId, fieldReference){   $totalPrice = 0;   $lastColorPrice = 0;   $('CarOptionsDiv').innerHTML = "Please select a model";   var BrandID = BrandsGrid.getCellValue(row, 0); // get field 0 value of selected row   ModelsGrid.newQuery(); // start a new query   ModelsGrid.addQuery('brandID', '=', BrandID); // Query based on BrandID   ModelsGrid.runQuery(); // run the query } // end BrandClicked
End JavaScript Code

ModelClicked() 関数定義:

JavaScript Code:
function ModelClicked(row, column, recordId, fieldReference){   $totalPrice = 0;   $lastColorPrice = 0;   $('CarOptionsDiv').innerHTML = "Getting options from backend";   var ModelID = ModelsGrid.getCellValue(row, 1); // get cell value from field 3 of the selected row   prepOptions(ModelID); } //end ModelClicked
End JavaScript Code


カスタム値をバックエンドに送信する

ModelClicked() 関数はバックエンドにカスタム値を送信する prepOptions() 関数を呼び出します:

PrepOptions() 関数定義:

JavaScript Code:
function prepOptions(modelID){   myQuery = new dax_query('Models');   myQuery.clearCustomValues();   myQuery.addCustomValue('modelID', modelID);   myQuery.handler = getOptionValues;   myQuery.runQuery(); } // end prepOptions
End JavaScript Code


バックエンドでカスタム値を受け取る

4Dがカスタム値を受け取ると、DAX_DevHook_OnQuery プロジェクトメソッドが予備ださ得ます:

DAX_DevHook_OnQuery method (custom modification in BOLD):

4D Code:
C_LONGINT($1;$selectionNumber_l;$size_l;$i) C_POINTER($2;$3;$4;$5;$6;$tableNumbers_p;$fieldNumbers_p;$queryValues_p;$queryComparators_p;$queryLineLinks_p) C_BOOLEAN($7;$0;$queryInSelection_b;$queryDone_b) C_TEXT($tableName_t;$selectionName_t;$operator_t;$value_t) C_POINTER($table_p;$field_p) ` variable declarations for modelID custom value query C_TEXT($modelID_t;$colorsSpan_t) C_LONGINT($modelCount_li;$i;$colorCount_li) C_REAL($basePrice_r) ` end variable declarations for modelID custom values query $selectionNumber_l:=$1 $tableNumbers_p:=$2 $fieldNumbers_p:=$3 $queryValues_p:=$4 $queryComparators_p:=$5 $queryLineLinks_p:=$6 $queryInSelection_b:=$7 $queryDone_b:=False ` Change to True if you handle the Query ` *** This is an advanced feature - you'll need to be comfortable with building complex ` queries using pointers and text values ` *** To handle the queries yourself ` Convert the passed parameters to tables, fields, and values, and perform the queries $modelID_t:=DAX_Dev_GetWebVar ("modelID") If ($modelID_t#"")   $queryDone_b:=True   ALL RECORDS([Options])   QUERY([Options];[Options]modelID=$modelID_t)   $modelCount_li:=Records in selection([Options])   ARRAY TEXT(customVarName_at;($modelCount_li+2))   ARRAY TEXT(customVarValue_at;($modelCount_li+2))   ALL RECORDS([Models])   QUERY([Models];[Models]ID=$modelID_t)   $basePrice_r:=[Models]basePrice   customVarName_at{1}:="Base Price"   customVarValue_at{1}:=String($basePrice_r)   FIRST RECORD([Options])   For ($i;1;$modelCount_li)     customVarName_at{($i+1)}:=[Options]name     customVarValue_at{($i+1)}:=String([Options]price)     NEXT RECORD([Options])   End for   ` compose HTML for colors and send as name="Colors" and value="composedHTML"   ALL RECORDS([Colors])   QUERY([Colors];[Colors]modelID=$modelID_t)   $colorCount_li:=Records in selection([Colors])   FIRST RECORD([Colors])   $colorsSpan_t:="<table border=0 cellpadding=0 cellspacing=0 border=0 width=100%>\r"   $colorsSpan_t:=$colorsSpan_t+"<tr><td rowspan="+String($colorCount_li+1)+" valign=top align=left>Colors:</td></tr>"   For ($x;1;$colorCount_li)     If ([Colors]Color="White")       $colorsSpan_t:=$colorsSpan_t+"<tr><td align=left><input type=\"radio\" id=\"White\" checked=true onclick=\"calcColor(this);\" value=\""+String([Colors]Price)+"\" name=\"color\">"+[Colors]Color+"</td><td align=right>$"+String([Colors]Price)+"</td></tr>\r"     Else       $colorsSpan_t:=$colorsSpan_t+"<tr><td align=left><input type=\"radio\" onclick=\"calcColor(this);\" value=\""+String([Colors]Price)+"\" name=\"color\">"+[Colors]Color+"</td><td align=right>$"+String([Colors]Price)+"</td></tr>\r"     End if     NEXT RECORD([Colors])   End for   $colorsSpan_t:=$colorsSpan_t+"</table>"   customVarName_at{($modelCount_li+2)}:="Colors"   customVarValue_at{($modelCount_li+2)}:=$colorsSpan_t   DAX_Dev_SetCustomVariables (->customVarName_at;->customVarValue_at) End if +If (False) End if ` *** Return True if you have performed the query ` Return False to have 4DAF perform the query $0:=$queryDone_b
End 4D Code


バックエンドからのカスタム値コールバックを受け取る

getOptionsValues() 関数はmyQueryオブジェクトのハンドラとして事前に設定され、バックエンドにカスタム値を送信する前に使用されます。これは4Dからフロントエンドにデータが戻された際に呼び出される関数です。

getOptionValues() 関数定義:

JavaScript Code:
function getOptionValues(){   myCustomValues = myQuery.getCustomValuesFrom4D();   var len = myCustomValues.length;   if(len!=0){     $optionsHTML = "<form><table border=0 cellspacing=0 cellpadding=0 width=100%>\r";     for(var i = 0; i<len;i++){       if(myCustomValues[i].name == "Base Price"){         $basePrice=myCustomValues[i].value;         $optionsHTML = $optionsHTML + "<tr><td style=\"padding: 3px\">Base Price:</td>\r<td align=right style=\"padding: 3px\">$"+ $basePrice +"</td></tr>\r";         $optionsHTML = $optionsHTML + "<tr height=1 bgcolor=#000000><td colspan=2></td></tr>\r";       }else{ // end if / start else         $name = myCustomValues[i].name;         $value = myCustomValues[i].value;         if($name=="Colors"){           $spanForColors = $value;         }else{ // end COLOR           $optionsHTML = $optionsHTML + "<tr>\r";           $optionsHTML = $optionsHTML + "<td><input type=checkbox value=\""+ $value +"\" ID=\"DaxCarOption\" name=\""+ $name +"\" onclick=\"calcTotal(this);\">"+ $name +"</td>\r";           $optionsHTML = $optionsHTML + "<td align=right style=\"padding: 3px\">$"+ $value +"</td>\r";           $optionsHTML = $optionsHTML + "</tr>\r";         } // end COLOR else       } // end BASE PRICE else     } // end for loop     $optionsHTML = $optionsHTML + "<tr height=1 bgcolor=#000000><td colspan=2></td></tr>\r";     $optionsHTML = $optionsHTML + "<tr><td valign=top colspan=2 style=\"padding: 3px\"><span ID=\"ColorsDropDown\"></span></td></tr>\r";     $optionsHTML = $optionsHTML + "<tr height=1 bgcolor=#000000><td colspan=2></td></tr>\r";     $optionsHTML = $optionsHTML + "<tr><td><b style=\"padding: 3px\">Total Price:</b></td>\r<td align=right style=\"padding: 3px\"><b><div ID=\"TotalPrice\"></div></b></td></tr>\r";     $optionsHTML = $optionsHTML + "</table>\r</form>";     $('CarOptionsDiv').innerHTML = $optionsHTML;     $('ColorsDropDown').innerHTML = $spanForColors;     $totalPrice = $basePrice;     $('TotalPrice').innerHTML = "$"+$totalPrice;   $('White').click();   } // end IF len # 0 } // end getOptionValues
End JavaScript Code


総計の計算

ユーザがオプションをクリックするたびに、以下の関数を使用して総計が再計算されます:

calcTotal 関数定義

JavaScript Code:
function calcTotal(item){   if(item.checked==true){     $totalPrice = parseInt($totalPrice) + parseInt(item.value);     $('TotalPrice').innerHTML = "$"+$totalPrice;   }else{     $totalPrice = parseInt($totalPrice) - parseInt(item.value);     $('TotalPrice').innerHTML = "$"+$totalPrice;   } }
End JavaScript Code

calcColor 関数定義:

JavaScript Code:
function calcColor(item){   $totalPrice = parseInt($totalPrice) + parseInt(item.value) - parseInt($lastColorPrice);   $('TotalPrice').innerHTML = "$"+$totalPrice;   $lastColorPrice = parseInt(item.value); // update the price of the last color used for the next calculation }
End JavaScript Code