2

CFC でフォームのデフォルト値を動的に宣言する方法を探しています。AJAX 経由で呼び出しています。現在の CFC は注文を送信しますが、これをサブ注文に分解する必要があります。

私はこれを使用していました:

 <!--- static defaults --->
 <cffunction name="Defaults" access="public" returntype="struct" output="false" 
    hint="Assign default values to instance">
    <cfscript>
        var formDefaults = {
              versenden=""
            , speichern="" 
            ...
        }
    </cfscript>
    <cfreturn formDefaults />
</cffunction>

<cffunction name="Commit" access="public" returntype="struct" output="false" hint="database handler">

 <!--- add dynamic form fields --->
 <cfscript>             
    var LOCAL = {};
    variables.defs = THIS.Defaults();
 </cfscript>
 <cfloop collection="#VARIABLES.Instance.FormData#" item="formField">
    <cfscript>
        if (   LEFT(formField, 5) EQ "MENGE" 
            OR LEFT(formField, 3) EQ "EAN" 
            OR LEFT(formField, 12) EQ "BESTELL_TEXT" 
            OR LEFT(formField, 10) EQ "BESTELLTYP" 
            ...
          ) {
          variables.defs[formField]="";
        }
    </cfscript>
</cfloop>
<cfscript>
    structAppend(variables.defs, VARIABLES.Instance.FormData);                  
    LOCAL.Basket = variables.defs;  
</cfscript>

...

そのため、最初に静的フォーム フィールドを宣言し (単一インスタンスのみ)、動的フォーム フィールドを配列に動的に追加しようとします。これは複数回転送される可能性があります (MENGE38, MENGE39, MENGE40など) 。

これは問題なく機能しますが、フォーム名に別のカウント要素を追加する必要があるため、またはMENGEのようなものに変更する必要があり、次のようなフォーム値を送信します。counter.MENGEMENGE.counter

MENGE.1.38
MENGE.1.40
MENGE.1.41
MENGE.2.37

サブオーダーを示すカウンタでは、このフィールドが使用されます。

問題は、これが動的フォーム フィールドの宣言を壊し、その理由がわかりません。次のエラーが表示されます。

Diagnose: Element MENGE.1 is undefined in a CFML structure referenced as part of an expression.

質問:
何が問題なのかヒントを教えてもらえますか? HTML ページのフォーム フィールドもパラメーター化する必要がありますか (する必要はありません)?

ありがとう!

編集:
問題は検証機能にありました。上記で行った変更も宣言する必要があります。新しい関数は次のようになります。

<cffunction name="Validate" access="public" returntype="array" output="false" hint="validate form inputs and return an array of faulty field names.">
   <cfscript>
     var LOCAL = {};
     var double = structNew();
     double.form = VARIABLES.Instance.FormData;
     double.criteria = VARIABLES.Instance.Validation;
  </cfscript>

  <!--- add dynamic form fields for validation... I FORGOT TO UPDATE THIS--->
  <cfloop collection="#VARIABLES.Instance.FormData#" item="formField">
     <cfscript>
        if (   LEFT(formField, 5) EQ "MENGE" 
            OR LEFT(formField, 10) EQ 'BESTELLTYP'
            OR LEFT(formField, 3) EQ "EAN" 
            OR LEFT(formField, 12) EQ "BESTELL_TEXT" 
            ...
        ) {
           VARIABLES.Instance.Validation[formField]="pass";
        }
     </cfscript>
  </cfloop>
  <!--- Get error names and type --->
  <cfinvoke component="form_validate" method="validate_fields" double="#double#" returnvariable="validation_errors"></cfinvoke>
  <cfset LOCAL.ErrorMessages = validation_errors />
  <cfreturn LOCAL.ErrorMessages />

この関数で新しく更新された if 句を追加しなかったため、エラーが発生していました。

4

1 に答える 1

3

Dan Bracukの回答に基づいて作成するには、アンダースコアを使用します(ただし、「BESTELL_TEXT」の名前を変更する必要があります)。これをlistFirst、listGetAt、およびlistLastと組み合わせて使用​​し、アンダースコアを区切り文字として使用して、フィールド名の構造を決定します。リスト関数を使用して、大きなIFを少しクリーンアップした方法に注意してください。書かれたこのコードはおそらくあなたが必要とすることをしませんが、あなたのビジネスニーズを理解する必要なしに概念を説明したかったのです。

<cfscript>
var orders=structNew();
item=listFirst(formField,'_');
orderNames = "MENGE,EAN,BESTELLTEXT,BESTELLTYPE";
if (listFindNoCase(orderNames,item,'_')){
    if (!structKeyExists(orders,item)){
        // initialize item
        orders[item]=structNew();
    }
    orderID="";
    subOrderId="";
    if (listLen(formField,'_') gt 1) {
        orderID=listGetAt(formField,2,'_');
    }
    if (listLen(formField,'_') eq 2) {
        orders[item][orderId]=formData[formField];
    }
    if (listLen(formField,'_') eq 3) {
        subOrderId=listLast(formField,'_');
        orders[item][orderId][subOrderId]=formData[formField];
    }

}
</cfscript>
于 2013-02-24T15:16:25.830 に答える