Valores personalizados en 4D Ajax Framework

Este ejemplo muestra cómo utilizar valores personalizados en 4D Ajax Framework. El valor personalizado se envía desde la página Web (frontend) y se recibe en la base 4D (backend). La base 4D (backend) luego realiza una búsqueda y envía los valores personalizados de regreso a la página Web (frontend) la cual les da formato a los datos y los muestra en la página Web. El ejemplo está en el formulario de un sistema de cotizaciones interno de un concesionario de carros; está diseñado para permitir al usuario armar un vehículo con las opciones que quiera y mostrar el precio total en la página.


Marcas

La rejilla Marchas muestra una lista de fabricantes en la base.


Modelos

La rejilla Modelos muestra una lista de modelos de carros en la base. La rejilla de datos se carga inicialmente con una búsqueda ficticia para limitar la visualización a cero resultados. Cada vez que se hace clic en una marca, se realiza una búsqueda en la base y la rejilla Modelos se actualiza para mostrar sólo los modelos encontrados para la marca seleccionada.


Opciones

Las opciones div muestran una lista de opciones (y sus precios asociados) encontrados en la base para el modelo de carro seleccionado. El div se altera dinámicamente cada vez que el usuario hace clic en la rejilla Marcas o Modelos.


Llenar con datos

Las rejillas se llenan con la siguiente configuración:

Configuración de la rejilla Marcas:

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

Configuración de la rejilla modelos:

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


Eventos Click

Las siguientes funciones se disparan cuando se hace clic en la rejilla Marcas y Modelos:

Definición de la función 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

Definición de la función 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


Envío de valores personalizados al backend

La función ModelClicked() llama a la función prepOptions() que enviará los valores personalizados al backend:

Definición de la función 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


Recepción de valores personalizados en el backend

El método de proyecto DAX_DevHook_OnQuery se llamará después de que 4D recia los valores personalizados:

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


Recepción de la retrollamada de valores personalizados del backend

La función getOptionsValues() anteriormente fue definida como el manejador para el objeto myQuery que se utilizó para enviar los valores personalizados al backend; esta función se llama cuando los datos regresan desde 4D al frontend:

Definición de la función getOptionValues():

Código JavaScript:
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


Calculo del costo total

Cada vez que el usuario hace en cualquiera de las opciones, las siguientes funciones se utilizan para calcular el costo total:

Definición de la función 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

Definición de la función 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