ColdFusion - Creating column names dynamically with CFLOOP

前端 未结 2 779
时光说笑
时光说笑 2021-01-22 02:45

I have a table that records the name of uploaded documents, up to 14 per record. The columns are named thus:

TABLE tblDocuments
COLUMNS documentID (int, not nu         


        
相关标签:
2条回答
  • 2021-01-22 03:14

    (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>
    
    0 讨论(0)
  • 2021-01-22 03:20

    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>
    
    0 讨论(0)
提交回复
热议问题