File upload

When to use this component

Use the file upload component to help users select and upload one or more files.

How it works

There are two cases in which the file upload component can be used:

  • To upload one file only (default)
  • To upload one or more files

Upload one file only (default)

When the user should only be able to select and upload one file, the file upload component can be used as is. See the “default” example.

Upload one or more files

When the user should be able to select and upload one or more files, the file upload component is placed in a fieldset.

There are two ways of using and presenting the file upload component in a fieldset to upload one or more files:

  • A fieldset with one single file upload component with the option to upload one or more files. See the “multiple” example.
  • A fieldset with multiple file upload components that are stacked. The file upload components can be shown immediatelly or can be shown one by one where the user is in control and actively chooses to select and upload one file more using a button that adds a file upload component. See the “stacked” example.

Usage, behavior, layout and validation

The file upload component is a form element that should always be used in a form. For a description of the usage, the behavior, the layout and validation of form elements, see the form component documentation.

<!-- Default -->
<section class="file-upload">
  <div class="form-item">
    {% include '@label' with {
      "label": label,
      "for": id ~ '--' ~ _self.name,
    } %}
    <div class="form-columns">
      <div class="form-item-column">
        {% render '@file' with {
          "id": id ~ '--' ~ _self.name,
          "name": name ~ '--' ~ _self.name|default(id ~ '--' ~ _self.name),
        } %}
      </div>
      <div class="form-item-column"></div>
    </div>
  </div>
</section>

<!-- Multiple -->
<fieldset class="file-upload">
  <legend>{{ label }}</legend>

  <div class="form-item">
    {% include '@label' with {
      "label": label,
      "for": id ~ '--' ~ _self.name,
    } %}
    <div class="form-columns">
      <div class="form-item-column">
        {% render '@file' with {
          id: id ~ '--' ~ _self.name,
          name: name ~ '--' ~ _self.name|default(id ~ '--' ~ _self.name),
          multiple: true
        } %}

        <ul class="inline">
          <li>{% render '@tag--filter-tag' with { tag_text: 'my uploaded file.pdf' } %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'another_file.pdf' }  %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'my_image.jpg' }  %}</li>
          <li>{% render '@tag--filter-tag' with { tag_text: 'super_secret.txt' }  %}</li>
        </ul>
      </div>
      <div class="form-item-column"></div>
    </div>
  </div>

</fieldset>

<!-- Stacked -->
<fieldset class="file-upload">
  <legend>{{ label }}</legend>

  {% for i in 1..2 %}
    <div class="form-item">
      {% include '@label' with {
          "label": itemLabel|replace({'%s': i}),
          "for": id ~ '--' ~ _self.name ~ '--' ~ i,
        } %}
      <div class="form-columns">
        <div class="form-item-column">
          {% render '@file' with {
              "id":  id ~ '--' ~ _self.name ~ '--' ~ i,
              "name": (name ~ '--' ~ _self.name ~ '--' ~ i)|default( id ~ '--' ~ _self.name ~ '--' ~ i),
            } %}
        </div>
        <div class="form-item-column"></div>
      </div>
    </div>
  {% endfor %}

  {% render '@button' with {
    text: 'Add attachment',
    type: 'primary',
    modifier: 'icon-plus'
  } %}
</fieldset>
<!-- Default -->
<section class="file-upload">
    <div class="form-item">
        <label for="file-upload--default">Attachment
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--default" aria-describedby="file-upload--default-description" name="--default" />

                    <span id="file-upload--default-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>
</section>

<!-- Multiple -->
<fieldset class="file-upload">
    <legend>Attachments (max. 3)</legend>

    <div class="form-item">
        <label for="file-upload--multiple">Attachments (max. 3)
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--multiple" aria-describedby="file-upload--multiple-description" name="--multiple" multiple />

                    <span id="file-upload--multiple-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>

                <ul class="inline">
                    <li>
                        <span class="tag filter ">
                            my uploaded file.pdf
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            another_file.pdf
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            my_image.jpg
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                    <li>
                        <span class="tag filter ">
                            super_secret.txt
                            <button><span class="visually-hidden">Remove tag</span></button>
                        </span>

                    </li>
                </ul>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>

</fieldset>

<!-- Stacked -->
<fieldset class="file-upload">
    <legend>Attachments (max. 3)</legend>

    <div class="form-item">
        <label for="file-upload--stacked--1">Attachment 1 of 3
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--stacked--1" aria-describedby="file-upload--stacked--1-description" name="--stacked--1" />

                    <span id="file-upload--stacked--1-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>
    <div class="form-item">
        <label for="file-upload--stacked--2">Attachment 2 of 3
        </label>
        <div class="form-columns">
            <div class="form-item-column">
                <div class="file" data-file="No file chosen.">

                    <input type="file" id="file-upload--stacked--2" aria-describedby="file-upload--stacked--2-description" name="--stacked--2" />

                    <span id="file-upload--stacked--2-description" class="file__button">Select your files here to upload</span>
                </div>

                <span class="help-text">Info about size and extension (optional)</span>
            </div>
            <div class="form-item-column"></div>
        </div>
    </div>

    <button type="button" class="button button-primary icon-plus ">
        Add attachment
    </button>
</fieldset>

/* Default */
{
  "id": "file-upload",
  "label": "Attachment"
}

/* Multiple */
{
  "id": "file-upload",
  "label": "Attachments (max. 3)"
}

/* Stacked */
{
  "id": "file-upload",
  "label": "Attachments (max. 3)",
  "itemLabel": "Attachment %s of 3"
}

  • Content:
    .file-upload {
    
      ul.inline {
        margin-top: .8rem;
    
        li {
          margin-right: .4rem;
          margin-bottom: .4rem;
        }
      }
    
      .button {
        margin-bottom: .8rem;
      }
    }
    
  • URL: /components/raw/file-upload/_file-upload.scss
  • Filesystem Path: components/31-molecules/file-upload/_file-upload.scss
  • Size: 173 Bytes