File upload

The WFileUpload widget allows you to upload a local file to the server.

Signals

To properly use this widget you need to handle the uploaded() or fileTooLarge() signals; even when upload() was not called.

An oversized file will result in a fileTooLarge() signal. The default threshold value (128) for this signal is defined in the general application settings file wt_config.xml by the parameter max-request-size (Kb). See the Library overview for more details.

Also check using canUpload() if upload() will schedule a new upload.

  • If (!canUpload()) then upload() will not have any effect.
  • If (canUpload()), then upload() will start a new file upload.
    If the upload completes successfully then an uploaded() signal will be emitted. Otherwise a fileTooLarge() signal will be emitted.

Example
source
#include <Wt/WBreak.h>
#include <Wt/WContainerWidget.h>
#include <Wt/WFileUpload.h>
#include <Wt/WProgressBar.h>
#include <Wt/WPushButton.h>
#include <Wt/WText.h>

using namespace Wt;


auto container = std::make_unique<Wt::WContainerWidget>();

Wt::WFileUpload *fu = container->addNew<Wt::WFileUpload>();
fu->setProgressBar(std::make_unique<Wt::WProgressBar>());
fu->setMargin(10, Wt::Side::Right);

// Provide a button to start uploading.
Wt::WPushButton *uploadButton = container->addNew<Wt::WPushButton>("Send");
uploadButton->setMargin(10, Wt::Side::Left | Wt::Side::Right);

Wt::WText *out = container->addNew<Wt::WText>();

// Upload when the button is clicked.
uploadButton->clicked().connect([=] {
    fu->upload();
    uploadButton->disable();
});

// Upload automatically when the user entered a file.
fu->changed().connect([=] {
    fu->upload();
    uploadButton->disable();
    out->setText("File upload is changed.");
});

// React to a succesfull upload.
fu->uploaded().connect([=] {
    out->setText("File upload is finished.");
});

// React to a file upload problem.
fu->fileTooLarge().connect([=] {
    out->setText("File is too large.");
});

File Drop

Try dropping files in the widget below. It accepts a maximum of 5 files. You can drop one or multiple files at a time.

Example
source
#include <Wt/WContainerWidget.h>
#include <Wt/WFileDropWidget.h>


auto dropWidgetPtr = std::make_unique<Wt::WFileDropWidget>();
auto dropWidget = dropWidgetPtr.get();

dropWidget->drop().connect([=] (const std::vector<Wt::WFileDropWidget::File*>& files) {
  const int maxFiles = 5;
  unsigned prevNbFiles = dropWidget->uploads().size() - files.size();
  for (unsigned i=0; i < files.size(); i++) {
    if (prevNbFiles + i >= maxFiles) {
      dropWidget->cancelUpload(files[i]);
      continue;
    }

    Wt::WContainerWidget *block = dropWidget->addNew<Wt::WContainerWidget>();
    block->setToolTip(files[i]->clientFileName());
    block->addStyleClass("upload-block spinner");
  }

  if (dropWidget->uploads().size() >= maxFiles)
    dropWidget->setAcceptDrops(false);
});

dropWidget->uploaded().connect([=] (Wt::WFileDropWidget::File* file) {
  std::vector<Wt::WFileDropWidget::File*> uploads = dropWidget->uploads();
  std::size_t idx = 0;
  for (; idx != uploads.size(); ++idx)
    if (uploads[idx] == file)
      break;
  dropWidget->widget(idx)->removeStyleClass("spinner");
  dropWidget->widget(idx)->addStyleClass("ready");
});

dropWidget->tooLarge().connect([=] (Wt::WFileDropWidget::File *file, uint64_t size) {
  std::vector<Wt::WFileDropWidget::File*> uploads = dropWidget->uploads();
  std::size_t idx = 0;
  for (; idx != uploads.size(); ++idx)
    if (uploads[idx] == file)
      break;
  dropWidget->widget(idx)->removeStyleClass("spinner");
  dropWidget->widget(idx)->addStyleClass("failed");
});

dropWidget->uploadFailed().connect([=] (Wt::WFileDropWidget::File *file) {
  std::vector<Wt::WFileDropWidget::File*> uploads = dropWidget->uploads();
  std::size_t idx = 0;
  for (; idx != uploads.size(); ++idx)
    if (uploads[idx] == file)
      break;
  dropWidget->widget(idx)->removeStyleClass("spinner");
  dropWidget->widget(idx)->addStyleClass("failed");
});

Top