Question

I have a form with the utility to attach documents and it uses a cfm file display them as below:

<cfsilent>
<cfparam name="request.ID" type="numeric" default="0">
<cfparam name="request.filename" type="string" default="">

<cfscript>  
    local = structNew();
</cfscript> 

<!--- get the request data --->
 <cfinvoke 
    component="#application.config.CFCOMPONENTS_PREFIX#com.mycompany.request_manager.responseEntity"
    method="get" 
    returnvariable="local.responses">
    <cfinvokeargument name="ID" value="#request.ID#"/>
</cfinvoke> 


<cfscript>
    local.fileName = request.filename;
    local.pathToFile = application.virtualPaths.APPROOT&"library/investigations/"&local.responses.report_number&"/"&local.fileName;
</cfscript>
</cfsilent>

<cfheader name="content-type" value="application/download">
<cfheader name="Content-Disposition" value="attachment; filename=#local.fileName#">
<cfcontent type="application/download" file="#ExpandPath(local.pathToFile)#" deletefile="No">

<cfabort> 

I need the ability to delet a file on the server, using a similar cfm file. I have a remove link which has a reference to the below page called redirect-delete.cfm. I want the files to delete on the form itself and the user staying on the form page.

<cfsilent>
<cfparam name="request.ID" type="numeric" default="0">
<cfparam name="request.filename" type="string" default="">

<cfscript>  
    local = structNew();
</cfscript> 

<!--- get the request data --->
 <cfinvoke 
    component="#application.config.CFCOMPONENTS_PREFIX#com.mycompany.request_manager.responseEntity"
    method="get" 
    returnvariable="local.responses">
    <cfinvokeargument name="ID" value="#request.ID#"/>
</cfinvoke> 


<cfscript>
    local.fileName = request.filename;
    local.pathToFile = application.virtualPaths.APPROOT&"library/investigations/"&local.responses.report_number&"/"&local.fileName;
</cfscript>
</cfsilent>

<cffile action="delete" file="#ExpandPath(local.pathToFile)#">

<cfabort> 

What should I add to the redirect-delete.cfm file for the user to get a pop-up saying are you sure you want to delete. If the user presses yes, the attachment should get deleted but the user should still stay on the form.

Was it helpful?

Solution

So you have a form plus a link. If the user selects the link, you want an alert to come up and if the user accepts, a file gets deleted on the server, but the user stays on the form? My approach would be:

  1. Put a 1 pixel iframe on your form page that contains the code to delete the file.
  2. For your anchor tag, have it link to javascript so that you can use the confirm popup.
  3. In the page that deletes the file, add some extra code that uses javascript to do something about the link on the form page. You can get rid of it completely, or replace it with a statement saying the file has been deleted.

Note that step 3 will be easier if you have your link inside a <div>.

OTHER TIPS

If you can, I would abstract both those cfm files into cfc.methods. From the tags used, I am guessing you are using CF7 or so...

In CF, create this cfc something like this:

<cfcomponent displayName="ManageAttachment">

<cffunction name="attachFile" access="public" >
    <cfargument name="ID" type="numeric" default="0">
    <cfargument name="filename" type="string" default="">
    <cfscript>
        local = structNew();
    </cfscript>
     <cfinvoke
        component="#application.config.CFCOMPONENTS_PREFIX#com.mycompany.request_manager.responseEntity"
        method="get"
        returnvariable="local.responses">
        <cfinvokeargument name="ID" value="#Arguments.ID#"/>
    </cfinvoke>
    <cfscript>
        local.fileName = Arguments.filename;
        local.pathToFile = application.virtualPaths.APPROOT&"library/investigations/"&local.responses.report_number&"/"&local.fileName;
    </cfscript>
    <cfheader name="content-type" value="application/download">
    <cfheader name="Content-Disposition" value="attachment; filename=#local.fileName#">
    <cfcontent type="application/download" file="#ExpandPath(local.pathToFile)#" deletefile="No">
    <cfreturn true>
</cffunction>

<cffunction name="detachFile" access="remote" >
    <cfparam name="request.ID" type="numeric" default="0">
    <cfparam name="request.filename" type="string" default="">
    <cfscript>
        local = structNew();
    </cfscript>
     <cfinvoke
        component="#application.config.CFCOMPONENTS_PREFIX#com.mycompany.request_manager.responseEntity"
        method="get"
        returnvariable="local.responses">
        <cfinvokeargument name="ID" value="#Arguments.ID#"/>
    </cfinvoke>
    <cfscript>
        local.fileName = Arguments.filename;
        local.pathToFile = application.virtualPaths.APPROOT&"library/investigations/"&local.responses.report_number&"/"&local.fileName;
    </cfscript>
    <cffile action="delete" file="#ExpandPath(local.pathToFile)#">
    <cfreturn Arguments>
</cffunction>

Then in your display you might do something like this:

<div>
  <h3> Your List of Attached Files For This Report</h3>
  Here is file 1. <img src='delete.png' fileName="prebuiltFileNameGoesHere1"><br />
  Here is fiel 2. <img src='delete.png' fileName="prebuiltFileNameGoesHere2"><br />
</div>

Then, in js, using jQuery (sub your own library tools if not using jQuery):

// Assuming you use jQuery:  if not, swap out with your favorite library
$(function() {
    // Bind clicks on delete images
    $('img.deleteLink').on('click', function(event) {
        if(confirm('Are you sure want to remove this attachment?') {
            detachThisFile(this.getAttribute('fileName'));
        });
    }
});

function detachThisFile(filename) {
    $.ajax({
        url : 'pathtocomponent.ManageAttachment.cfc',
        cache : false,
        success : function( result, textStatus, jqXHR) {
                yourCallBackMethod(result);
            },
        data : {
                method: 'detachFile', returnFormat: 'json', argumentCollection: $.toJSON({filename: filename})
            }, // You might need the toJSON plug in or rewrite to be simple value
        error : function(jqXHR, textStatus, errorThrown) {
                console.log('ERROR OC detachThisFilenme(): ' +  errorThrown);
            }
    });
}

function yourCallBackMethod(result) {
    // Maybe you hide the link after you delete it or something to let user know it worked
    // Pass an id token through to the call back as an overloaded argument so you know which element to delete 
    // (This is why detachFile returns arguments, so you can overload it in a useful manner) 
}

I am not sure where your ID is coming from. If you need it from the link (this seems likely), add it in as another attribute and pass it along just like the filename...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top