ColdFusion - Creating column names dynamically with CFLOOP

♀尐吖头ヾ 提交于 2019-12-02 01:05:44

(The original question was already answered. But just to illustrate ...)

A more flexible structure is to store the documents as rows. So basic table might be:

TABLE:    tblDocuments
COLUMNS:  DocumentID  (unique record id)
          UserID
          DocumentName

Using this structure, you could retrieve all existing documents for a single user with a simple query

<cfquery name="qryGetDocs" datasource="#dsn#">
     SELECT documentID, documentName
     FROM   tblDocuments
     WHERE  userID = <cfqueryparam name="#SomeUserIDVariable#" cfsqltype="cf_sql_integer">
</cfquery>

.. and display them with a simple output loop. (Note, I added "documentID" as hidden field to identify existing documents ..)

<cfoutput query="qryGetDocs">
   ...
   <input type="file" name="document#CurrentRow#" size="50" >
   <input type="hidden" name="documentID#CurrentRow#" value="#documentID#" >
   (current file name: <a href="#vars.file_path#/#documentName#">#documentName#</a>)
</cfoutput>

If the query contains less than 14 files (or whatever your maximum is..), you can use the query.recordCount to determine how many additional file inputs to display.

<cfset nextInputNumber = qryGetDocs.recordCount + 1>
<cfoutput>
<cfloop from="#nextInputNumber#" to="#MaximumNumberOfDocs#" index="counter">
   <input type="file" name="document#counter#" size="50" >
   <input type="hidden" name="documentID#counter#" value="0" >
</cfloop>
</cfoutput>

Queries can be accessed (like structs) with a string index and square brackets, but only if you also include the desired row number (!). This works like a two-dimenisonal array.

<cfloop from="1" to="14" index="i">
   <input type="file" name="document#i#" size="30">
   <cfif qryGetDocs["document#i#"][qryGetDocs.CurrentRow] IS NOT ''>
     (current file name: <a href="HTMLEditFormat("#vars.file_path#/#qryGetDocs["document#i#"][qryGetDocs.CurrentRow]#")#">#HTMLEditFormat(qryGetDocs["document#i#"][qryGetDocs.CurrentRow])#</a>)
   </cfif>
</cfloop>

Note the HTMLEditFormat() to protect yourself against cross site scripting attacks. This is important! Never ever output data to HTML without properly escaping it. (I admit that filenames are an improbable attack vector because they usually cannot contain pointy brackets, but a) you can't be too cautious, b) it's a good habit to get into, and c) no one knows what security holes will pop up when the code gets re-factored at some point in the future. Not HTML-escaping data is inexcusable sloppiness.)

A more idiomatic and much more readable version would be:

<cfloop from="1" to="14" index="i">
   <cfset RowNum  = qryGetDocs.CurrentRow>
   <cfset ColName = "document#i#">
   <cfset DocName = qryGetDocs[ColName][RowNum]> 
   <cfset DocPath = "#vars.file_path#/#DocName#">
   <input type="file" name="#ColName#" size="30">
   <cfif FileExists(ExpandPath(DocPath))>
     (current file name: <a href="#HTMLEditFormat(DocPath)#">#HTMLEditFormat(DocName)#</a>)
   </cfif>
</cfloop>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!