[SalesForce] Lightning Design for Apex:inputFile

I am seeking to make a VF page using SLDS including the . Below is how the documentation has the file upload element.

<div class="slds-form-element">
  <span class="slds-form-element__label" id="file-selector-id">Attachment</span>
  <div class="slds-form-element__control">
    <div class="slds-file-selector slds-file-selector_files">
      <div class="slds-file-selector__dropzone">
        <input type="file" class="slds-file-selector__input slds-assistive-text" accept="image/png" id="file-upload-input-01" aria-describedby="file-selector-id">
        <label class="slds-file-selector__body" for="file-upload-input-01">
          <span class="slds-file-selector__button slds-button slds-button_neutral">
            <svg class="slds-button__icon slds-button__icon_left" aria-hidden="true">
              <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#upload"></use>
            </svg>Upload Files</span>
          <span class="slds-file-selector__text slds-medium-show">or Drop Files</span>
        </label>
      </div>
    </div>
  </div>
</div>

Selector Example

I was not sure how to wire up an input tag to my controller, so I opted to use the apex:inputFile element.

the updated code is below. The element did not support aria-describedby, did not need the file type and I added a value (required). The current page, when I select the file picker button, does not pull up the modal for choosing a file. Any help would be appreciated.

 <div class="slds-form-element">
      <span class="slds-form-element__label" id="file-selector-id">Attachment</span>
      <div class="slds-form-element__control">
        <div class="slds-file-selector slds-file-selector_files">
          <div class="slds-file-selector__dropzone">
              <apex:inputFile styleClass="slds-file-selector__input slds-assistive-text" accept="image/png" id="file-upload-input-01" value="foo" />
            <label class="slds-file-selector__body" for="file-upload-input-01">
              <span class="slds-file-selector__button slds-button slds-button_neutral">
                <svg class="slds-button__icon slds-button__icon_left" aria-hidden="true">
                  <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#upload"></use>
                </svg>Upload Files</span>
              <span class="slds-file-selector__text slds-medium-show">or Drop Files</span>
            </label>
          </div>
        </div>
      </div>
    </div>

Best Answer

This is the rather classic mistake of mixing normal id values and apex id values. Apex ID values, which I like to call "managed IDs", which are prefixed and suffixed in a variety of ways depending on your code's design in order to make them globally unique, which is needed for rendering purposes (e.g. reRender, actionRegion, etc).

You should use apex:outputLabel instead, for your own convenience:

<apex:inputFile styleClass="slds-file-selector__input slds-assistive-text" accept="image/png" id="fileUploadInput01" value="foo" />
<apex:outputLabel styleClass="slds-file-selector__body" for="fileUploadInput01">

Alternatively, you can still use your normal HTML label, but then you have to figure out the prefix:

<label for="{!$Component.formName.blockName.fileUploadInput01}" ...

Where "formName.blockName" is just a placeholder for all intermediate Visualforce ("apex:" prefixed) elements surrounding the input element.

Related Topic