使用从数据库传递的 id 将文件上传链接到 table 中的按钮
Linking a file upload to a button in a table, using an id passed from the database
使用一些遗留代码,并试图附加一些功能。该页面用于配置上传。页面底部是 table 与处置相关的文件。这些文件(附件)保存在数据库的 table 中,每个文件都有自己的 ID。
客户希望在每个条目旁边的每一行上的 "replace" 添加一个 "replace" 按钮(已经有一个下载和删除按钮)。单击后,将显示一个文件上传表单。应该发生的是客户端上传的文件应该用 ID 替换 table 中的附件。但是,当我单击 "replace" 按钮时,它会显示用于替换 table 顶部附件的表单。
如何通过 ID(通过数据库 table)将按钮 link 到表单?
这是 table...
'''
<table class="table table-striped table-bordered table-hover table-hover table-full-width">
<thead>
<tr>
<th class="center hidden-xs"></th>
<th style="display:none;">ID</th>
<th>File Name</th>
<th>Figure Name</th>
<th>Date Uploaded</th>
<th>Rearrange Order</th>
</tr>
</thead>
<tbody>
<cfset loopCount = 1 />
<cfset ids = '' />
<cfset allowDown = #qAttachments.recordCount# />
<cfloop query = "qAttachments">
<cfset ID = "#qAttachments.id#">
<cfset fileName="#qAttachments.filename#">
<cfset fileExt=ListLast(fileName,".")>
<cfset filePath = "/secure/edFiles/edAttachments/ED_#session.module.id#/#url.edID#/#fileName#"><!---removed.pdf--->
<tr>
<div id="replaceAtt" style="display: none" >
<div class="col-md-6">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="input-group">
<div class="form-control uneditable-input">
<i class="fa fa-file fileupload-exists"></i>
<span class="fileupload-preview"></span>
</div>
<div class="input-group-btn">
<div class="btn btn-blue btn-file">
<span class="fileupload-new"><i class="fa fa-folder-open-o"></i> Select file</span>
<span class="fileupload-exists"><i class="fa fa-folder-open-o"></i> Change</span>
<input type="file" id="replaceEDFile" name="replaceEDFile" title="Select File to Replace #ID#">
</div>
<a href="" class="btn btn-blue fileupload-exists" data-dismiss="fileupload">
<i class="fa fa-times"></i> Remove
</a>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class = "btn btn-blue btn-block" value="#ID#" type = "submit" name ="replaceFile" onClick="location.href='edFormData.cfm?replaceFile=#ID#&m=#url.m#&edID=#url.edID#&#r#&ai=#url.ai#'">
Upload File <i class = "fa fa-arrow-circle-right" ></i>
</div>
</div>
</div>
</tr>
<tr>
<td class="center hidden-xs">
<a href="#filePath#"><button type = "button" class="fa" name="download" id="download" value="#ID#" onClick="location.href='edFormData.cfm?download=#ID#&m=#url.m#&edID=#url.edID##r#&ai=#url.ai#'"> <img src="../assets/Icons/viewdoc.png"></button></a>
<cfif readonly NEQ "readonly">
<button type = "button" class="fa" name="Delete" id="Delete" value ="#ID#" onClick="location.href='edFormData.cfm?del=#ID#&m=#url.m#&edID=#url.edID##r#&ai=#url.ai#'">
<img src="../assets/Icons/trash-o_ff0400_20.png"></button>
<button id="replace" type = "button" class ="replace" name="replace" value="#ID#" title="Replace attachment #ID#" >
<img src="../assets/Icons/file_replace_000000.png">
</button>
</cfif>
</td>
<td style="display:none;">#ID#</td>
<td id="file_#ID#">#qAttachments.filename#</td>
<td id="figure_#ID#">#qAttachments.figureName#</td>
<td id="uploaded_#ID#">#qAttachments.uploaded#</td>
<td>
<cfif loopCount NEQ 1>
<div class = "btn btn-green btn-block" id="moveUP_#ID#">Move Up</div><br />
</cfif>
<cfif loopCount NEQ allowDown>
<div class = "btn btn-blue btn-block" id="moveDown_#ID#">Move Down</div>
</cfif>
</td>
</tr>
<cfif loopCount NEQ allowDown>
<cfset ids = #ids#&"#ID#," />
<cfelse>
<cfset ids = #ids#&"#ID#" />
</cfif>
<cfset loopCount=(#loopCount#+1) />
</cfloop>
<input type="hidden" id="possibleIDs" value="#ids#" />
</tbody>
</table>
'''
这是 JavaScript...
'''
<script>
$(document).ready(function(){
$('.replace').click(function(e){
e.preventDefault();
$("#replaceAtt").slideToggle('fast');
});
});
</script>
'''
与完整答案相比,这是更多的代码审查/评论。这段代码中发生了很多事情。正如 James 所说,您的代码混合了表和 div,并抛出了一些 Bootstrap。有很多变量在那里浮动,但不清楚它们在哪个范围内(比如 readonly
),还有很多并不是真正需要的变量(比如 loopcount
和 allowDown
).还有一些不需要引号和磅的变量(比如 <cfset ID = "#qAttachments.filename#">
可以是 <cfset ID = qAttachments.ID>
)和一些直接使用 URL 变量的地方在代码中。还有其他一些事情。
这是遗留代码,所以我完全理解。它就是这样,如果它是 CF11 代码,那么自从它首次编写以来可能已经改进了很多东西。在这里成为周一早上的四分卫很容易。
也就是说,您可以在 tbody
标记之间显着减少您在此页面中所做的事情。
为了稍微简化一下,我省略了您正在循环播放的大部分 HTML。
由于您使用的是查询循环,因此无需跟踪循环计数,因为它已经是 currentRow
中查询结果的一部分。而且你不需要设置 allowDown
,因为你只引用它一次。您真正需要的唯一事情是初始化 ids
,这样您就可以 ListAppend()
而不是试图弄清楚如何处理尾随逗号。
<cfset ids="">
<cfoutput>
<cfloop query="qAttachments">
<!--- HTML Display Code In This Block --->
EXAMPLE: WE ARE ON ID = #id#
<!--- Move Buttons --->
<cfif currentRow NEQ 1> MOVE UP </cfif>
<cfif currentRow NEQ qAttachments.recordcount> MOVE DOWN </cfif>
<br>
<!--- --->
<!--- Build ID list for hidden form. --->
<cfset ids = ListAppend(ids,id)>
</cfloop>
<br>
< hiddenFormInput > possibleIDs = "#ids#" < /hiddenFormInput >
</cfoutput>
同样,这只是概念代码,可以更好地构建您的循环。请注意,因为这是 CF11,所以使用 cfscript 而不是 cftags 循环会更好。我建议将您的 CFML 代码与您的显示代码分开,也许使用可以 return 一组数据循环显示的 CF 函数。
我要评论的最后一件事是使用 ID
作为通用名称。在您的循环中,您使用了 3 个不同的 ID
变量:1) session.module.id
2) 来自您的查询的 ID
3) 和一个 ID
变量,基于您的循环查询ID
。在这种特定情况下,您将获得想要的值,但在页面上使用多个同名变量通常不是一个好主意,而 ID
是一个简单的方法。只需要改变求值顺序,就会让你头疼,难以调试。
我要感谢所有对此发表评论和提供帮助的人。我知道代码充其量是简陋的,但是当我开始弄乱循环中已有的内容时,其他地方的某些东西就会中断。但是我确实发现了问题(在一个比我聪明得多的同事的帮助下)为什么我不能 link div 的按钮并显示正确的上传表单对于 table 的那一行!那是图像……是的,图像。我决定让 JS 在按下按钮时发出 ID 名称的警报。经过一些黑客攻击后,我有时让它工作,而其他时候就输出 NaN 。好吧,通过一些 "Inspect Element" 魔法,我们发现它根据我点击按钮的位置输出 ID 或 NaN。这让我们意识到图像本身需要一个 id,因为它试图在单击时被拉出。
所以,这就是我对上面发布的代码所做的更改:
首先,我将保存上传表单的 div 拉出循环,这样我就不会填充多个表单,而且我可以切换附件替换而无需重新加载有一堆移动内容的页面在屏幕上。
其次,实际按钮本身:
<button type = "button" class ="replace" name="replace" id="replace_#ID#" value="#ID#" title="Replace #qAttachments.figureName#" >
<!--- Gave the image an ID, so if it is clicked it can still split properly. --->
<img id="replaceImg_#ID#" src="../assets/Icons/file_replace_000000.png">
</button>
三、JavaScript。
<script>
$('[id^="replace_"], [id^="replaceImg_"]').click(function(e){
// Split the ID to get the number (lines up with DB ID).
var replaceID = e.target.id.split("_")[1];
// Set this to let the user know which file is being replaced (by figure name).
var figNameRep = $('#figure_'+replaceID).text();
// If the upload replacement is not showing yet, make it show now.
if ($('#replaceAtt').css("display") == 'none'){
$('#replaceAtt').slideToggle("fast");
}
// Don't worry about hiding and unhiding, just switch the IDs around as needed.
$('#figNameReplace').text("Replacing file for Figure Name: " + figNameRep);
$('#replaceFile').val(replaceID);
});
</script>
再次感谢大家的意见。你们建议的想法我确实尝试过,虽然我无法让它们中的任何一个起作用(这更多是对我自己技能的评论),但它确实教会了我一些新的工具和方法。你们好棒!
使用一些遗留代码,并试图附加一些功能。该页面用于配置上传。页面底部是 table 与处置相关的文件。这些文件(附件)保存在数据库的 table 中,每个文件都有自己的 ID。
客户希望在每个条目旁边的每一行上的 "replace" 添加一个 "replace" 按钮(已经有一个下载和删除按钮)。单击后,将显示一个文件上传表单。应该发生的是客户端上传的文件应该用 ID 替换 table 中的附件。但是,当我单击 "replace" 按钮时,它会显示用于替换 table 顶部附件的表单。
如何通过 ID(通过数据库 table)将按钮 link 到表单?
这是 table... '''
<table class="table table-striped table-bordered table-hover table-hover table-full-width">
<thead>
<tr>
<th class="center hidden-xs"></th>
<th style="display:none;">ID</th>
<th>File Name</th>
<th>Figure Name</th>
<th>Date Uploaded</th>
<th>Rearrange Order</th>
</tr>
</thead>
<tbody>
<cfset loopCount = 1 />
<cfset ids = '' />
<cfset allowDown = #qAttachments.recordCount# />
<cfloop query = "qAttachments">
<cfset ID = "#qAttachments.id#">
<cfset fileName="#qAttachments.filename#">
<cfset fileExt=ListLast(fileName,".")>
<cfset filePath = "/secure/edFiles/edAttachments/ED_#session.module.id#/#url.edID#/#fileName#"><!---removed.pdf--->
<tr>
<div id="replaceAtt" style="display: none" >
<div class="col-md-6">
<div class="fileupload fileupload-new" data-provides="fileupload">
<div class="input-group">
<div class="form-control uneditable-input">
<i class="fa fa-file fileupload-exists"></i>
<span class="fileupload-preview"></span>
</div>
<div class="input-group-btn">
<div class="btn btn-blue btn-file">
<span class="fileupload-new"><i class="fa fa-folder-open-o"></i> Select file</span>
<span class="fileupload-exists"><i class="fa fa-folder-open-o"></i> Change</span>
<input type="file" id="replaceEDFile" name="replaceEDFile" title="Select File to Replace #ID#">
</div>
<a href="" class="btn btn-blue fileupload-exists" data-dismiss="fileupload">
<i class="fa fa-times"></i> Remove
</a>
</div>
</div>
</div>
</div>
<div class="col-md-2">
<div class = "btn btn-blue btn-block" value="#ID#" type = "submit" name ="replaceFile" onClick="location.href='edFormData.cfm?replaceFile=#ID#&m=#url.m#&edID=#url.edID#&#r#&ai=#url.ai#'">
Upload File <i class = "fa fa-arrow-circle-right" ></i>
</div>
</div>
</div>
</tr>
<tr>
<td class="center hidden-xs">
<a href="#filePath#"><button type = "button" class="fa" name="download" id="download" value="#ID#" onClick="location.href='edFormData.cfm?download=#ID#&m=#url.m#&edID=#url.edID##r#&ai=#url.ai#'"> <img src="../assets/Icons/viewdoc.png"></button></a>
<cfif readonly NEQ "readonly">
<button type = "button" class="fa" name="Delete" id="Delete" value ="#ID#" onClick="location.href='edFormData.cfm?del=#ID#&m=#url.m#&edID=#url.edID##r#&ai=#url.ai#'">
<img src="../assets/Icons/trash-o_ff0400_20.png"></button>
<button id="replace" type = "button" class ="replace" name="replace" value="#ID#" title="Replace attachment #ID#" >
<img src="../assets/Icons/file_replace_000000.png">
</button>
</cfif>
</td>
<td style="display:none;">#ID#</td>
<td id="file_#ID#">#qAttachments.filename#</td>
<td id="figure_#ID#">#qAttachments.figureName#</td>
<td id="uploaded_#ID#">#qAttachments.uploaded#</td>
<td>
<cfif loopCount NEQ 1>
<div class = "btn btn-green btn-block" id="moveUP_#ID#">Move Up</div><br />
</cfif>
<cfif loopCount NEQ allowDown>
<div class = "btn btn-blue btn-block" id="moveDown_#ID#">Move Down</div>
</cfif>
</td>
</tr>
<cfif loopCount NEQ allowDown>
<cfset ids = #ids#&"#ID#," />
<cfelse>
<cfset ids = #ids#&"#ID#" />
</cfif>
<cfset loopCount=(#loopCount#+1) />
</cfloop>
<input type="hidden" id="possibleIDs" value="#ids#" />
</tbody>
</table>
'''
这是 JavaScript... '''
<script>
$(document).ready(function(){
$('.replace').click(function(e){
e.preventDefault();
$("#replaceAtt").slideToggle('fast');
});
});
</script>
'''
与完整答案相比,这是更多的代码审查/评论。这段代码中发生了很多事情。正如 James 所说,您的代码混合了表和 div,并抛出了一些 Bootstrap。有很多变量在那里浮动,但不清楚它们在哪个范围内(比如 readonly
),还有很多并不是真正需要的变量(比如 loopcount
和 allowDown
).还有一些不需要引号和磅的变量(比如 <cfset ID = "#qAttachments.filename#">
可以是 <cfset ID = qAttachments.ID>
)和一些直接使用 URL 变量的地方在代码中。还有其他一些事情。
这是遗留代码,所以我完全理解。它就是这样,如果它是 CF11 代码,那么自从它首次编写以来可能已经改进了很多东西。在这里成为周一早上的四分卫很容易。
也就是说,您可以在 tbody
标记之间显着减少您在此页面中所做的事情。
为了稍微简化一下,我省略了您正在循环播放的大部分 HTML。
由于您使用的是查询循环,因此无需跟踪循环计数,因为它已经是 currentRow
中查询结果的一部分。而且你不需要设置 allowDown
,因为你只引用它一次。您真正需要的唯一事情是初始化 ids
,这样您就可以 ListAppend()
而不是试图弄清楚如何处理尾随逗号。
<cfset ids="">
<cfoutput>
<cfloop query="qAttachments">
<!--- HTML Display Code In This Block --->
EXAMPLE: WE ARE ON ID = #id#
<!--- Move Buttons --->
<cfif currentRow NEQ 1> MOVE UP </cfif>
<cfif currentRow NEQ qAttachments.recordcount> MOVE DOWN </cfif>
<br>
<!--- --->
<!--- Build ID list for hidden form. --->
<cfset ids = ListAppend(ids,id)>
</cfloop>
<br>
< hiddenFormInput > possibleIDs = "#ids#" < /hiddenFormInput >
</cfoutput>
同样,这只是概念代码,可以更好地构建您的循环。请注意,因为这是 CF11,所以使用 cfscript 而不是 cftags 循环会更好。我建议将您的 CFML 代码与您的显示代码分开,也许使用可以 return 一组数据循环显示的 CF 函数。
我要评论的最后一件事是使用 ID
作为通用名称。在您的循环中,您使用了 3 个不同的 ID
变量:1) session.module.id
2) 来自您的查询的 ID
3) 和一个 ID
变量,基于您的循环查询ID
。在这种特定情况下,您将获得想要的值,但在页面上使用多个同名变量通常不是一个好主意,而 ID
是一个简单的方法。只需要改变求值顺序,就会让你头疼,难以调试。
我要感谢所有对此发表评论和提供帮助的人。我知道代码充其量是简陋的,但是当我开始弄乱循环中已有的内容时,其他地方的某些东西就会中断。但是我确实发现了问题(在一个比我聪明得多的同事的帮助下)为什么我不能 link div 的按钮并显示正确的上传表单对于 table 的那一行!那是图像……是的,图像。我决定让 JS 在按下按钮时发出 ID 名称的警报。经过一些黑客攻击后,我有时让它工作,而其他时候就输出 NaN 。好吧,通过一些 "Inspect Element" 魔法,我们发现它根据我点击按钮的位置输出 ID 或 NaN。这让我们意识到图像本身需要一个 id,因为它试图在单击时被拉出。
所以,这就是我对上面发布的代码所做的更改:
首先,我将保存上传表单的 div 拉出循环,这样我就不会填充多个表单,而且我可以切换附件替换而无需重新加载有一堆移动内容的页面在屏幕上。
其次,实际按钮本身:
<button type = "button" class ="replace" name="replace" id="replace_#ID#" value="#ID#" title="Replace #qAttachments.figureName#" >
<!--- Gave the image an ID, so if it is clicked it can still split properly. --->
<img id="replaceImg_#ID#" src="../assets/Icons/file_replace_000000.png">
</button>
三、JavaScript。
<script>
$('[id^="replace_"], [id^="replaceImg_"]').click(function(e){
// Split the ID to get the number (lines up with DB ID).
var replaceID = e.target.id.split("_")[1];
// Set this to let the user know which file is being replaced (by figure name).
var figNameRep = $('#figure_'+replaceID).text();
// If the upload replacement is not showing yet, make it show now.
if ($('#replaceAtt').css("display") == 'none'){
$('#replaceAtt').slideToggle("fast");
}
// Don't worry about hiding and unhiding, just switch the IDs around as needed.
$('#figNameReplace').text("Replacing file for Figure Name: " + figNameRep);
$('#replaceFile').val(replaceID);
});
</script>
再次感谢大家的意见。你们建议的想法我确实尝试过,虽然我无法让它们中的任何一个起作用(这更多是对我自己技能的评论),但它确实教会了我一些新的工具和方法。你们好棒!