Creating Forms that Allow File Uploads

When you create a form for users to submit data to a custom item type (CIT), you can allow them to upload files that are associated with the database item created by the form submission.

Uploaded files are always part of a CIT, and are part of either a Related Assets or Dedicated File field of the Item Type.

Depending on the field type, you can upload one or more files in a form, and can have the upload be part of the creation of a new CIT instance or as part of an edit/update to an existing CIT.

CIT Changes

To enable support for external file uploads, create or edit your CIT and add a custom field of type “Related Assets” or “Dedicated File”. If you are using Related Assets, set the “Type Options” field to an integer value greater than 0. This number is the maximum number of files that will be allowed per upload. Dedicated File fields always support one file per field.

When using a Related Assets field, the max count is not a requirement for how many files must be uploaded. It is simply the total number of files that can be sent with the form submission.

After saving any changes to your CIT, generate a new Form item. Check the option “Allow Form To Accept Item Updates” if you intend for the form to be able to update existing records. (Note that the only updates that are supported are additional file uploads to an item.)

If this form is only for creating new items, leave the box unchecked.

We recommend that you create separate forms for new item creation versus editing of existing items to enhance security.

Form Elements

To support file uploads, the form element itself requires the attribute enctype="multipart/form-data". This is automatically included if you use the form prototype code generated by the system.

The system also generates a number of input elements of type “file”. It creates a total of N of these elements, where N is the max files number you entered in the CIT description. You do NOT have to use all of these fields. If you wish to have fewer, simple delete the unneeded fields (starting with the field with the highest ID). You may also create alternative UIs that dynamically hide and show the DOM to generate these elements; the critical part is using the naming convention described here.

A typical input element looks like:


<input type="file" id="upload_test_id_dymd_pictures_0_asset" name="upload_test_id[dymd][pictures][0][asset]" />

The critical attribute is the name attribute. It must use the convention:

css_form_id[dymd][fieldname][N][asset]

where each part is mandatory and has the following requirements:

Key Value
css_form_id the EXACT css form id as provided on the form setup page
dymd fixed value
fieldname the name of the related asset or dedicated file fields in the target CIT
N n integer, starting at 0, and less than the max files number you specified in the CIT
asset fixed value

For forms that are going to be used to update an existing CIT, you will typically structure a form with just the input elements. You also need to specify a special hidden “ID” field that contains the CIT’s ID and an MD5 hash which is used to verify that the given element can legitimately be targeted.

The following form, for example, allows photos to be submitted for addition to a profile page:


<w:kb:item>
  <h1><w:name /> Profile Page</h1>
  <ul>
    <w:assets:each sort="created_at ASC">
      <li>
        <img src="<w:assets:path rendition='thumb' />" />
      </li>
    </w:assets:each>
  </ul>
  <h2>Contribute a new picture</h2>
  <form enctype="multipart/form-data" action="/profile-thanks/" autocomplete="off" class="new_dy_node" id="upload_test_id" method="post">
    <input id="upload_test_id_profile_id" name="upload_test_id[profile][id]" type="hidden" value="<w:kb:item:id />-<w:kb:item:md5 />"/>
    <label for="upload_test_id_dymd_pictures">Pictures</label>
    <div class="file-picker-wrap">
      <input type="file" id="upload_test_id_dymd_pictures_0_asset" name="upload_test_id[dymd][pictures][0][asset]" />
    </div>
    <div class="file-picker-wrap">
      <input type="file" id="upload_test_id_dymd_pictures_1_asset" name="upload_test_id[dymd][pictures][1][asset]" />
    </div>
    <div class="file-picker-wrap">
      <input type="file" id="upload_test_id_dymd_pictures_2_asset" name="upload_test_id[dymd][pictures][2][asset]" />
    </div>
    <input id="email2" name="email2" style="display:none;" type="text" value="" />
    <input id="form_id" name="form_id" type="hidden" value="upload_test_id" />
    <input id="dy_node_submit" name="commit" type="submit" value="Upload" />
  </form>
</w:kb:item>

File Management

Uploads are automatically uploaded to a root folder (see configs) and organized by CIT names. Within each CIT name folder are unique, system-generated folders, one per upload. This maintains clean “namespaces” for each and every upload, and provides a bit of security, as the container uses a special hash of the asset info. These files are accessed through WebvantaScript.

The unique named folder starts with a time stamp (incrementing integer), so you can see sequence information in a sense.

Within each upload folder, the files maintain their uploaded names when possible. In some cases, if duplicate names are detected, a unique filename that maintains most of the existing filename and the file extension is generated.

Uploaded files that require moderation are displayed in the Control Panel with a warning icon in the row and a notice of “Needs Moderation?” in the preview panel.

Moderation Workflow

Whenever a form requires moderation (i.e., it is not set to “auto accept”), files will require moderation too.

NOTE: You must approve files separately from the item to which it is attached. When you click on the thumbs up/down button on the Submissions list, the files are not approved too. You must go to the “Review Item” screen and approve the items one at a time.

If there are files that need approval, they will display a warning badge and a checkbox with the label “Approve?”. Check each file you want to approve, select the Approve popup if desired, and press Next or Previous. (Note that whether you select Approve or not is independent of the moderation flag of the files.)

You may also defer approval of files and just approve the item.

If you have a previous approved item and are going back to approve assets (either from an original deferral or because this is an item that supports updates, you can go in to the item editor and approve the files as above.

You can also moderate files from the Files screen. Approving files on CITs that have themselves not been moderated will not approve the CIT, but it will mark the files as approved, should the item itself be approved at any future time. Simply select the asset, press the Edit button in the preview pane, and if the item needs moderation, a Remove Moderation Block checkbox will be shown.

Once a file has been approved, it is always approved…it simply removes the block from the file.

NOTE: Currently, there is no way to “reject” a file other than to delete it. Alternatively, if you want to keep the file for a while, just leave it set to require moderation.

WebvantaScript

All asset related tags for WebvantaScript that iterate over an item’s assets will filter out files that require moderation. There is NO way to iterate over pending assets.

When an uploaded file is part of a form submission that is pending moderation, the normal WebvantaScript statements will not return the filename, because the file has not yet been approved. You can override this limitation by adding the attribute:

moderator = "true"

to the WebvantaScript statement that is accessing the filename. This is especially useful if you want to sent a notification email of the site admin, and you want to include the image in the notification email.

For example, suppose you have an item type with a dedicated file field named "photo". In the snippet that provides the notification email, which is named something like admin_notice_form_name, you would include something like this to include a thumbnail version of the image in the email:

<img src='http://www.yoursite.com/rendition.thumb<w:photo moderator="true" />'>