One Form with multiple submit buttons with ColdFusion!

You can access all the files for this tutorial by going to the GIT repository for this tutorial at:
https://bitbucket.org/easycfm/tutorials/src/master/form-multiple-submits-example/

A user of the EasyCFM Facebook Page requested we create an example of handling multiple submit buttons with ColdFusion. This tutorial will walk you through how to create a web form that requests multiple pieces of data and then depending on which button the user clicked; process specific items from the form accordingly.

Step 1. Create the form page that will allow users to select a file to upload from their machine and display two buttons to tell the system what to do with it!

For this example we will begin with a Bootstrap html page skeleton. We can save this as “form-example.cfm” in the root of your ColdFusion site.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiple Form Buttons Example</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
    

    <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
</body>
</html>

The example above is basically a clean canvas bootstrap html page saved as a ColdFusion template that we will begin to build the form into. I opted to include bootstrap so you could see that you can handle a ColdFusion page like an HTML page. When all the ColdFusion tags and logic is finished processing, that you are left with is basically HTML so by including the bootstrap content inside of it it will end up displaying to the user as an HTML page with bootsrap and jquery capabilities. Pretty neat, huh?

So the next thing that we need to do is create a form that will contain multiple form buttons within it. The buttons will each do something different; and we can determine that one of two ways.

The easiest method is to name all the submit buttons that same name, but each will contain a different value. So on the processing page (what happens when you submit the form) we can write logic to check the field and see which one you pressed based on the value. (Note: The other method is to name the fields differently and then change your logic to process if a particular field exists, but that gets more complicated.. so let’s go with the simplest solution!)

So let’s get that logic in place… In between your <body> and </body> tag, we will insert the following code (this is the form):

<form method="post" action="form-example-process.cfm" enctype="multipart/form-data">
    <table class="table table-striped">
        <tr>
           <th>File</th>
           <th colspan="2">Select what you'd like to do with it!</th>
        </tr>
        <tr>
            <td>
               <input type="file" name="uploadFile" />
            </td>
            <td>
              <input type="submit" name="whatToDoWithFile" value="Upload File To Server" />
           </td>
           <td>
              <input type="submit" name="whatToDoWithFile" value="Upload File To Server and Email It To SiteAdmin" />
           </td>
        </tr>
    </table>
 </form>

If you placed the code in the proper place, which I am confident you did! Your code should look something very similar to this:

Now let’s break down what we actually did… the code above basically will create a web form with a file selection input (this allows the user to select a file on their local machine to upload to your site) and two buttons that trigger the upload and then based on user selection will either send the file in an email or not the site administrator! We accomplish this with the submit buttons. We will break that down in a few….

Note: The form tag has an added attribute “enctype=”multipart/form-data”” which basically tells the server that you will be sending files along with your request and not just data/strings. You can learn more on <form> tags here.

If you open the file in your browser now, you will see something similar to this:

Graphic 1.2 – Let’s see what the form looks like on a browser!

See… creating forms is easy…. you got this! The next part is to tell ColdFusion what to do with the form fields from the form (i.e. the file being uploaded and what you want it to do based on the submit button pressed).

It really sounds more complicated then it really is… trust me… 🙂 you have now completed the form page. The next thing you need to create is the form process page. You defined what that would be in your <form> tag with the action attribute as shown below:

Graphic 1.3 – Where is this form sending the data to anyway? Let’s check!

Step 2. Let’s create a processing page that will do something with the form submission data! This is the ColdFusion Part! Exciting!

So you now need to create a file called “form-example-process.cfm“. and save it in the same folder you saved the “form-example.cfm” file. Now because this is a processing page, we do not need to create a Bootstrap skeleton HTML page. This page will simply process what you are asking it to do and then send you somewhere else, so the users will never see it so no display is needed!

<cfif structKeyExists(form, 'fieldnames') AND structKeyExists(form, 'whatToDoWithFile') AND structKeyExists(form, 'uploadFile')>

   <!--- This code will only run when a form is submitted to this page, and when the variable "whatToDoWithFile" and "UploadFile" exists --->
   <!--- 
              ToDo: This is where we will put in the ColdFusion that will handle the processing   
   --->

</cfif>

So now… let’s break down what will be expected for this page to run correctly. The page expects for a form to be submitted to it… now ColdFusion can talk to these variables and do things with them… The first thing the page does is to check if three form variables exist. Form.FieldNames, Form.whatToDoWithFile, and Form.uploadFile.

We achieve this with the following code:

<cfif structKeyExists(form, 'fieldnames') AND structKeyExists(form, 'whatToDoWithFile') AND StructKeyExists(form, 'uploadFile')>
StructKeyExists() is a ColdFusion function that is native to ColdFusion. It's sole purpose is to check if the form structure contains a particular field. You can read more on it here: https://cfdocs.org/structkeyexists

If those three form fields exist, then we know we can do something with this form. But let’s talk a little about the fields and how/why they exist.

Form.Fieldnames = This is an automatic variable that will be created by ColdFusion of all the form fields being passed in. This gets generated anytime form fields are submitted to a ColdFusion file and contain all the fields available. We can use this as a way to ensure that an actual form was submitted and that the page wasn’t called directly in a browser!
Form.uploadFile = This is a form variable that contains the actual file that was uploaded to the server.
Form.whatToDoWithFile = This is the form submit button that was pressed by the user. There are two forms on the page with the same name, however only the one you click will be sent along with the request and that’s why we can know exactly what the user intended to do. Does that make sense?

Ok, you now get the idea of how it works… so what do we do on the ColdFusion side to handle this upload? and possibly email the file? Let’s talk through it!

Right under the ToDo comment in the processing page, let’s add some actual ColdFusion code.

<cfif form.whatToDoWithFile EQ "Upload File To Server">
    <!--- here we will upload the file to the uploads folder only --->
    <cffile action="upload" filefield="uploadFile" destination="#expandPath('/uploads/')#" nameconflict="makeunique" />
    <cfset uploadedFileName = cffile.serverfile />

    <!--- That's it... this processing is done now let's redirect the user back to the display page --->
    <cflocation url="form-example.cfm?actionCompleted=UploadedFile" addtoken="false" />
            
<cfelseif form.whatToDoWithFile EQ "Upload File To Server and Email It To SiteAdmin">
    <!--- here we will upload the file to the email folder and then email the file to the user --->
    <cffile action="upload" filefield="uploadFile" destination="#expandPath('/emails/')#" nameconflict="makeunique" />
    <cfset uploadedFileName = cffile.serverfile />

    <!--- Now let's send an email with the file as an attachment --->
    <cfmail from="uploads@mysite.com" to="administrator@mysite.com" subject="A User Uploaded A File For You!">
        <cfmailparam file="#expandPath('/emails/' & uploadedFileName )#" />
    </cfmail>
            
    <!--- That's it... this processing is done now let's redirect the user back to the display page --->
    <cflocation url="form-example.cfm?actionCompleted=EmailedFile" addtoken="false" />
<cfelse>
    <!--- Since no button matched what we wanted to do, just redirect back to the main page with an error --->
    <cflocation url="form-example.cfm?actionCompleted=Nothing" addtoken="false" />
</cfif>

That was a lot of code… I know it seems like that.. but let’s break it down and walk through it… It’ll make sense shortly!

The first thing we do is check to see if the button that the user clicked was “Upload File To Server”. If they did, then this piece of code will execute and do what you tell it to do. So let’s break that code down:

The first thing we did is call CFFILE with an action of Upload. This tells ColdFusion that the user is uploading a file to the server and then what it should do with that file. There are two additional attributes set on the tag which are destination (where should the file be placed?) and nameconflict (if the file already exists on the server, what should ColdFusion do with it!)

Then the next thing it does is to create a variable and give it a name of “uploadedFileName” and assign to that variable a value of the name of the file being saved on the server. This is important because the name on the server could be different then the name of the file on the users machine. The nameconflict attribute for example says makeunique so if that file already existed (say the user uploaded it twice) then the second time around it would give it a unique name and you’d want to know that the name of the file on the server is changed to something else. Make sense?

Now, the file is uploaded, next we will redirect the user back to the form page (form-example.cfm) and we will pass a URL variable named “actionCompleted” to that page telling it what we did!

Now, if the user didn’t click that button, but they instead clicked the button that said “Upload File To Server and Email It To SiteAdmin” then that code above would be ignored at processing and the logic would then run for the second block of the check because the value of that field matches this one and not the other one! Make sense?

Now, in this area, we have to upload the file and then email the file to the system administrator.. so there is more code to do, but let’s walk through it!

The first two lines will look very similar to the previous example.. It’s a CFFILE that uploads and then we set the uploadedFileName variable. The only thing that is different is that in the destination for this one it will upload to a folder named “emails” and the previous one uploaded the files to a folder named “uploads”. As you can see below:

Note: We did two folders so you can keep your files in different places on your site and know which ones came from uploads and which ones were sent to the system administrator! That would give you easier cleanup capabilities later on! (Thinking about ways to simplify maintenance later as you create things will help you later keeping your site more efficient!)

The next thing this code will do is send out an email using the <cfmail> tag. The cfmail tag has 3 attributes on it.
– from = This is the email address used in the from at send time. (if the recipient replies it would go to this! For example we will hard code it; however in a realistic setting you might as the user for their email address in a field field and put that in that location so they can respond accordingly.
– to = This is who will receive the email (the system administrator!)
– subject = This is the subject of the email being sent.

Inside the <cfmail> tags, you have a cfmailparam tag. This tag basically tells cfmail that you are wanting to attach a file to the email going out and where the file is located.

Last, we simply redirect the user like we did in the previous example, however the actionCompleted value will be different (so we can differentiate it later).

Last, if neither of the button values match the two checks, then we can assume a button with that name was submitted to the page but it did not have one of our desired actions; so therefore we will simply redirect the user back to the “form-example.cfm” page with an actionCompleted value of “Nothing”.

That is almost it… you’re almost done! So what do we have left to do now? Well remember that we are redirecting users back to the form page with a url variable that will tell them what the system did.. So we have to create some type of confirmation message to the user telling them what was done. So let’s open up the “form-example.cfm” page again from step 1.

Right before the <form> tag you will need to add the following block of code:

<cfif structKeyExists(URL, 'actionCompleted')>
    <div class="alert">
        <cfif url.actionCompleted EQ "UploadedFile">
            Your file was successfully uploaded!
        <cfelseif url.actionCompleted EQ "EmailedFile">
            Your file was successfully uploaded and email to the system administrator!
        <cfelseif url.actionCompleted EQ "Nothing">
            Nothing was done, just letting you know!
        </cfif>
    </div>
</cfif>

When you are done, your page should look something similar to this:

Basically, what we did here is check to see if when this page loads there is a URL variable named “actionCompleted” and if it exists, then display an alert window at the top of the page with a predefined message based on the action taken on the processing page. An example of this would look like this “This example shows you what would be shown after the user uploads and sends an email to the system administrator”.

And that’s it! You now have a single form that contains multiple buttons and processed differently in the back-end with ColdFusion based on what the user clicked.

if you run into problems or need further help let us know. We’re here to help!

You can access all the files for this tutorial by going to the GIT repository for this tutorial at:
https://bitbucket.org/easycfm/tutorials/src/master/form-multiple-submits-example/

Advertisement