Link to home
Start Free TrialLog in
Avatar of Quack
QuackFlag for United States of America

asked on

Is it possible to confirm someone has attached a document to a form using Cold Fusion before they can submit the form?

Is it possible to confirm someone has attached a document to a form using Cold Fusion before they can submit the form?

I have a form that requires a pdf to be attached to the form before submitting and allowing the information to be placed into a database table.

I need to prevent the user from submitting the file w/o a document being attached. I need to use Cold Fusion if possible or html. No javascript as this is to be used as a preventive measure when the user is able to disable javascript.

Thanks
Avatar of gdemaria
gdemaria
Flag of United States of America image

Well, you can't prevent them from submitting the form without javascript, but you can keep from accepting the form (that is, you don't have to process the form submission) unless everything checks out.   This is server-side validation.  

When the user submits the form, you can check any form variable to see if it is populated; maybe the name or email address is required.  Same thing with the form upload field.   Simply check to see if it has a value using ColdFusion before you process it to the database.  If your requirements are not met, then do not save the information and return the user to the form with an error message.

<cfif len(form.lastName) eq 0>
     --- process error message - last name is required

<cfif len(form.fileUpload) eq 0>
    --- process error - file is required

If you want to be sure the file is a pdf, go ahead and use cffile to upload it and then check the extension on the uploaded file.  Using cffile.extension (or similar, you may have to check the exact name).    If it is not what you want, do not save the contents, just return an error to the user and redisplay the form.
Avatar of Quack

ASKER

I'm fairly new to  CF ... can you elaborate a little on the code to use for the cffile upload?
Avatar of Quack

ASKER

would I need to set a cfparam up for the form.fileUpload?
This code has a list of acceptable file extensions, after the upload, first the upload is verified and then the extensions are checked.   If there is a problem, it throws an error.   But you need to handle the error however you typically do.  In this case, the code is inside of a cftry / cfcatch so the thrown error is caught and handled gracefully.  Just do your normal error handling..

<cfset extList = "pdf,gif,jpg,jpeg,doc,docx,xls,xlsx,png,zip">

<CFFILE action="upload" filefield="upload" destination="#tempDir#" result="fileUpload" nameconflict="MAKEUNIQUE">

<cfif NOT fileUpload.fileWasSaved> <!--- Determine whether the image file is saved. --->
   <cfthrow message="Upload file failed">
</cfif>
<cfif listFindNoCase(extList, fileUpload.clientFileExt) eq 0>
   <cfthrow message="Invalid file type.  File extension must be one of these: #extList#">
</cfif>

Open in new window

Sorry, I left out the answer to your last post.   You can test to see if the upload exists using this..

<cfif isDefined("form.upload") and len(form.upload)>
   ... a file is selected to upload
<cfelse>
  ... no file has been selected for upload
</cfif>
whatever @gde has told you, only that will work if javascript is not an option

also you can use html5 required attribute which wil force user to upload a file [as far as i know browser forces the html5 attributes to be followed in this case]
Avatar of Quack

ASKER

do you have a link or examples of the html5 required attribute? I'll research that but not sure I've used that. thanks
Avatar of Quack

ASKER

are you referring to the required=true/false attribute?
I'm probably overthinking this
just do it like

<iput type="file" required name="name" id="myid">
Avatar of Quack

ASKER

here's the code I'm trying to use:

<!--- Check PDF file size. Do not insert record or save PDF file if too large.--->
<CFIF isdefined ("FORM.UPLOAD")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
      <CFABORT>
    </CFIF>
</CFIF>

<!--- Check PDF is attached. Do not insert record or save if no PDF file selected.--->
<cfif NOT Len("FORM.UPLOAD")>
 <cflocation addtoken="no" url="nopdf.htm">
 <CFABORT>
</cfif>

the first check is working fine but the last check to confirm there's a pdf is attached isn't...I'm clueless as to why...anyone have any ideas?
ASKER CERTIFIED SOLUTION
Avatar of gdemaria
gdemaria
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Quack

ASKER

thanks a ton gdemaria!!! that fixed it
Avatar of Quack

ASKER

not so fast gdemaria...:-)

That's working however now when I attach a pdf the form sends me to the nopdf.htm file even if there's an attached pdf:

<!--- Check PDF file size. Do not insert record or save PDF file if too large or pdf isn't attached.--->
<CFIF isdefined ("FORM.UPLOAD")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
    <cfelse>
      <cflocation addtoken="no" url="nopdf.htm">
    </CFIF>
</CFIF>

help please!! Thanks for the help up to this point.
You have the CFIF CFELSE in the wrong places... please check my example and compare to yours.   Look at the CFIF CFELSE /CFIF placements
Avatar of Quack

ASKER

Ok you were correct: I changed it to :

<CFIF isdefined ("FORM.UPLOAD")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
        <cflocation addtoken="no" url="filetoolarge.htm">
      </CFIF>
         <cfelse>    
          <cflocation addtoken="no" url="nopdf.htm">
      </CFIF>

However now its back to not directing to the nopdf.htm if not pdf is attached
that's interesting.. .do you have a cfpararm for form.upload?  (if so, you can remove it)

Ty changing the first line to this..
<CFIF isdefined ("FORM.UPLOAD") and len(form.upload)>
Avatar of Quack

ASKER

darn...didn't work
can you display what value is in that field?   I don't understand how the field is not empty if no file is attached.

Right before your <CFIF ... you could put something like..

<cfoutput><h2>Upload=[#form.upload]#</h2></cfoutput>
<cfabort>
Avatar of Quack

ASKER

its just a browse button to find the pdf to attach
Sorry, I don't understand your reply.
When the user does not choose the browse button and does not specify a file, but hits submit.  That form field called "upload" should either have a file in it or be empty/undefined.  I would like to determine what is in that form field's value since you are saying you did not select a file.

Therefore, in the action that handles the file upload, you want to show to the screen what that variable contains.
Let me know what you see on the screen when you submit your form without selecting a file.

<cfoutput><h2>Upload=[#form.upload]#</h2></cfoutput>
<cfabort>
Avatar of Quack

ASKER

<CFIF isdefined ("FORM.UPLOAD")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
    <cfelse>
      <cflocation addtoken="no" url="nopdf.htm">
    </CFIF>
</CFIF>

that's what I'm using now...when a user submits the form without selecting a file it goes to the nopdf.htm file which says there's no pdf ...that works...also when a pdf is too large that catch works as well...however when I submit with a valid pdf w/in the correct size constraint it still sends me to the nopdf.htm page even though a valid pdf has been attached.
That is the old code where you made a mistake.. you are giving them two choices (1) Redirect with the too-large error or (2) redirect with the not found error

<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>    ------ IS IT TOO LARGE?
      <cflocation addtoken="no" url="filetoolarge.htm">
<cfelse>   -------------------  EVERYTHING ELSE GOES HERE -  ANYTHING NOT TOO LARGE goes to NO PDF
      <cflocation addtoken="no" url="nopdf.htm">
</CFIF>

Please see my above code and fix your CFELSE statements so they are correct.
Then add the CFOUTPUT / ABORT clause so we can see what is in your FORM.UPLOAD field when it is supposed to be empty
Avatar of Quack

ASKER

where do I place this within the code or does it matter:

<cfoutput><h2>Upload=[#form.upload]#</h2></cfoutput>
 <cfabort>
Avatar of Quack

ASKER

I get an error saying - The page cannot be displayed because an internal server error has occurred. That's when I add the abort code. I've placed it at the end of the cfif section we've been working on and at the end of the code w/in the cfm file...same issue.
Avatar of Quack

ASKER

I've updated the code again:

<!--- Check PDF file size. Do not insert record or save PDF file if too large or pdf isn't attached.--->
<CFIF isdefined ("FORM.UPLOAD")>
<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
</CFIF>
  <cfelse>
     <cflocation addtoken="no" url="nopdf.htm">
</CFIF>


Also...the previous page which attaches the pdf has this for the browse to select the pdf button for the attributes:

<input name="UPLOAD"type="hidden" value="Y"> <INPUT NAME="UploadPDF" TYPE="File" SIZE="50">
                              <font size="1" color="navy" title="Attach invoice file">(help)</font>
                              <br>Please be patient while your file uploads...<br><br></font></td>
Avatar of Quack

ASKER

this what's being called to for the browse to select a pdf in the previous file before getting to the confirmation page:

<input name="UPLOAD" type="hidden" value="Y"> <INPUT NAME="UploadPDF" TYPE="File" SIZE="50">

would I change the code to use UploadPDF in the snippet  you sent earlier?
Here is the problem....

The input field UPLOAD is just a "Y" - it is not the file to upload, since it always passes a Y then testing it for a file is useless
<input name="UPLOAD" type="hidden" value="Y">

This is the name of the upload file... UploadPDF, this is what we want to test for..
<INPUT NAME="UploadPDF" TYPE="File" SIZE="50">


<CFIF isdefined ("FORM.UploadPDF")>
       <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
           <cflocation addtoken="no" url="filetoolarge.htm">
       </CFIF>
<cfelse>
      <cflocation addtoken="no" url="nopdf.htm">
</CFIF>

Open in new window


Please be sure the CFIF CFELSE statements are correct as shown here
Avatar of Quack

ASKER

I now have this:

<CFIF isdefined ("FORM.UploadPDF")>
<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">           
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

The size catch is working...valid pdf is uploading...submit w/o a pdf and I get a page not found error. ugggg

here's the code for my browse input field when attaching a pdf:

<input name="UPLOAD" type="hidden" value="Y"> <INPUT NAME="UploadPDF" TYPE="File" SIZE="50">

what would I use to dump that out? <cfdump var="#upload#"> <cfdump var="#uploadPDF#">
<cfdump var="#hidden#">

maybe that would help figure this out...I'm missing something somewhere
I hope this was just a type-o on the post, but you are missing a /CFIF statement

<CFIF isdefined ("FORM.UploadPDF")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
        <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF> <!------- THIS WAS MISSING -------->
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

Open in new window



If you are getting a page not found error when no PDF was uploaded, then the nopdf.htm file is not found... perhaps you need to add the path to that file?     url="/somefolder/nopdf.htm"   ??
Avatar of Quack

ASKER

<!--- Check PDF file size. Do not insert record or save PDF file if too large or pdf isn't attached.--->
<CFIF isdefined ("FORM.UploadPDF")>
<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
      </CFIF>           
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

<!--- 10/17/11 - assign transaction id at confirmation (FINWEB 003129) --->

that's what I have now...still throwing somehow to a 404 page...the filetoolarge.htm is working fine...the nopdf.htm works but doesn't allow you to attach a pdf when I adjust that.
You need to do some trial and error to locate where the problem is.  If you remove that entire CFIF block shown above, do you get the error?   If you remove just the CFLOCATION to nopdf.htm do you still get the error?   Is the 404 error happening AFTER the above CFIF block?    Maybe you could show more code..
Avatar of Quack

ASKER

only happening when I add the cflocation to nopdf.htm
Avatar of Quack

ASKER

Is there a CGI value for a file type the way the CGI is setup for the filesize? maybe that's what's missing? see below:

<CFIF isdefined ("FORM.UPLOAD")>
	<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
<CFABORT>
    </CFIF>
</CFIF>	 

 <CFIF isdefined ("FORM.UploadPDF")>
     <CFIF VAL(CGI.CONTENT_TYPE) VAL PDF><!---this is where I was wondering if there's something I could add here?--->
      <cflocation addtoken="no" url="nopdf.htm"> 

    </CFIF>
 </CFIF>

Open in new window

No, there is no content type cgi variable that I know of.   The way to test the file type is to upload the file and then check the file.

But that will not solve your current problem of file-not-found.   It seems it cannot find your nopdf.htm file.   I think you should add a relative path to that file so you are sure to locate it...  <cflocation url="/somefolder/nopdf.htm" addToken="no">
Avatar of Quack

ASKER

Ok...I've trial and error...here's the code that finds the nopdf.htm file but won't allow a valid pdf to be uploaded:

<CFIF isdefined ("FORM.UploadPDF")>
<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">
      <cfelse> 
     <cflocation addtoken="no" url="nopdf.htm">  
      </CFIF>   	  
</CFIF>

Open in new window


here's the code that allows for a pdf to be attached/submitted but send the user to the 404 page after submit is clicked:

<CFIF isdefined ("FORM.UploadPDF")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
        <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF> 
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

Open in new window


Is it possible I'm missing a cfif tag or something?
I've already explained this code block.. it gives you two routes... the file is either Too Big or the File is Not Found.   There is NO PATH to a successful result.   Your CFIF and CFELSE  BOTH lead to errors... you need to throw out this example and never look back.

<CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">  <=== the FILE IS TOO BIG
<cfelse> 
     <cflocation addtoken="no" url="nopdf.htm">    <===== the FILE IS NOT FOUND
</CFIF>
==== IT WILL ENVER REACH HERE, SUCCESS IS IMPOSSIBLE

Open in new window



here's the code that allows for a pdf to be attached/submitted but send the user to the 404 page after submit is clicked:
What happened when you just removed the line:
   <cflocation addtoken="no" url="nopdf.htm">    and changed nothing else?  Did you still get the error?


<CFIF isdefined ("FORM.UploadPDF")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
             <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF> 
<cfelse>
     NO PDF FOUND... IS THERE STILL AN ERROR?
</CFIF>

Open in new window


What happened when you added the relative path to the URL /somefolder/nopdf.htm  ?   Did that fix it...

<CFIF isdefined ("FORM.UploadPDF")>
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
        <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF> 
<cfelse>
     <cflocation addtoken="no" url="/nopdf.htm">     <==== add the relative path to the location... what FOLDER is it IN?
</CFIF>

Open in new window


what about showing me the rest of the code?
Avatar of Quack

ASKER

nope...the file is inside the inetpub/wwwroot/centralinv/nopdf.htm along w/ all the other files associated w/ this...Its located in the same area as the filetoolarge.htm...its finding the file
Avatar of Quack

ASKER

attached are 2 files...one is the verify page of the invoice form...the other is the confirm page. hopefully this will help...I've had suggestions to add a parameter for the form.UploadPDF but I'm not sure...add it into which file? I thought paraming that would be a nono?
inv_contr_verify-.txt
inv_contr_verify-.txt
looks like both files uploaded are the same file... I don't see the validation part we're discussing in this file
Avatar of Quack

ASKER

Sorry...attached are the 2 files which are cfm files but of course you can't add a cfm file. I'm going to try adding a form.UploadPDF parameter to see if that helps.
inv_contr_confirm-.txt
inv_contr_verify-.txt
Avatar of Quack

ASKER

Got it!

parammed it:
<cfparam name="form.UploadPDF" 	default="">

Open in new window


added this:
<CFIF isdefined ("FORM.UploadPDF") AND Form.UploadPDF IS NOT "" > 
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
        <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF>
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

Open in new window


Thanks for all your help with this...made a huge leap in understanding how CF handles certain things. Getting there slowly but surely...whoop!!! gonna be a great Wednesday!! load off my mind!
Avatar of Quack

ASKER

ok...that's working but now its giving a 404 if anything besides a pdf is attached...how can I add server side validation to this to allow only a pdf to be attached? let me know if you can help w/ that...i'll start researching...thanks again
check your other question , i pasted an answer as to what you need
Avatar of Quack

ASKER

Are you referring to this code:

   
<cfif isdefined ("url.Action")>
   <!---
   Test the file size 
   --->
   <cfif val(cgi.content_length) gt 1024000>
      <!--- 
      the file size is over the limit of 1mb.  Refuse to upload it 
      --->
      <cfset variables.Success="Too Big!  No dice.">
   <cfelse>
      <!--- 
      the file is within the limit specified.  Define the accepted 
      MIME types. this example accepts plain text files and zip 
      files.
      --->
      <cfset request.AcceptPDF=
        "application/pdf">
      <!--- 
      now try to upload the file 
      --->
      <cftry>
      <cffile 
         action="Upload" 
         filefield="FileContents" 
         destination="c:\cfusionmx\wwwroot\" 
         nameconflict="OVERWRITE"
         accept="#request.AcceptImage#">
      <cfset variables.Success="Uploaded.">
      <cfcatch type="Application">
         <!--- 
         something went wrong.  Was it a mime type failure? 
         --->
         <cfif isdefined("cfcatch.MimeType")>
             <!--- 
             yes it was.  show the friendly error message. 
             --->
             <cfif not ListContains
                (request.AcceptImage,cfcatch.MimeType)>
                <h1>Fool!</h1>
                This type of file is not allowed for upload.<br>
                All that user training really paid off.</p>
                <p>Try again...</p>
             <cfelse>
                <!--- 
                Hmmm.  the mimetype is there but the file was on the   
                list.  Better dump out the whole error message.
                --->     
                <cfoutput>
                <b>Error</b><br>
                #cfcatch.Message#
                #cfcatch.Detail#
                </cfoutput>
            </cfif>
         <cfelse>
             <!--- 
             Hmmm.  No mimetype error in the catch scope. 
             Better dump out the whole error message.
             ---> 
             <cfoutput>
             <b>Error</b><br>
             #cfcatch.Message#
             #cfcatch.Detail#
             </cfoutput>
         </cfif>
         <cfabort>
      </cfcatch>
      <cfcatch type="Any">
         <cfoutput>
         <b>Error</b><br>
         #cfcatch.Message#
         #cfcatch.Detail#
         </cfoutput>
         <cfabort>
      </cfcatch>
      </cftry>
   </cfif>
</cfif>
<!--- 
Display the form 
--->
<html><head><title>Uploader Test</title></head><body>
<cfif isdefined ("url.Action")>
   <cfoutput>
   Your file was #variables.Success#
   </cfoutput>
</cfif>
<cfoutput>
<form 
   action="#cgi.script_name#?Action=Y" 
   method="post" 
   enctype="multipart/form-data">
</cfoutput>
Source File Name:<BR>
<input 
   name="FileContents" 
   type="FILE" 
   size="45"><br>
<input 
   type="submit" 
   value="Upload File">
</form>
</body></html> 
        

Open in new window

Avatar of Quack

ASKER

I'm trying something like this to prevent anything but a pdf from being attached:

<CFIF isdefined ("FORM.UploadPDF") AND Form.UploadPDF IS NOT "" > 
      <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
       <cfif IsPDFFile("#Form.UploadPDF#")> yes
<cfelse>
no
</cfelse>
        <cflocation addtoken="no" url="filetoolarge.htm">           
      </CFIF>
<cfelse>
     <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>

Open in new window


It's not working of course but I think I'm on the right track...maybe my cfelse statements are in the wrong place?
ok, After Uploading, You can always use the file.clientFileExt to check if the Uploaded file is PDF file or not

like this

<cfif file.clientFileExt EQ 'PDF'>
Process Code
<cfelse>
<cfif fileexists(expandpath('#file.serverfile#'))>
<cffile action="delete" file="#expandpath('#file.serverfile#')#">
</cfif>
<cflocation url="nopdf.cfm">
</cfif>

Open in new window

You can also use
file.serverFileExt

Open in new window

to make a double check
Gurpreet is correct, you check the type after upload.   I said this also earlier.

But just to keep things in the correct order, you check for missing file and file size before uploading, then check the type..

<CFIF isdefined ("FORM.UploadPDF") AND Form.UploadPDF IS NOT "" > 
   <CFIF VAL(CGI.CONTENT_LENGTH) GT 4000000>
      <cflocation addtoken="no" url="filetoolarge.htm">           
   </CFIF>
<cfelse>
   <cflocation addtoken="no" url="nopdf.htm">    
</CFIF>
<cffile action="UPLOAD".....> <!--- upload the file --->
<cfif file.clientFileExt is not "PDF">
  <cffile action="DELETE"... >  <!---- remove the uploaded file because it is the wrong type ---->
  <cflocation addtoken="no" url="notTypePdf.htm">    <!---- redirect to the error page for this ----->
</cfif>
... keep processing...

Open in new window