Jasny Bootstrap – File upload with existing file

by Arnold Daniels on 02/15/2013

I’m happy to say that many developers have found their way to Jasny Bootstrap. Especially the file upload component, is very popular. It can replace any normal <input type="file"> element to display a nice widget that is consistent across browsers and can show a preview for images.

This is just an imageThis is just an image

The documentation shows the HTML to use, but it doesn’t show how to use it with existing files. I’ll explain it here.

The basics

The HTML stays largely the same. Change fileupload-new to fileupload-exists for the .fileupload container div (line 1). Put the <img> for the existing image in the .fileupload-preview div (line 4). If you’re not image preview, put the file name in the .fileupload-preview div instead.

1
2
3
4
5
6
7
8
9
10
<div class="fileupload fileupload-exists" data-provides="fileupload">
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png">
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" name="myimage" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>
<div class="fileupload fileupload-exists" data-provides="fileupload">
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png">
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" name="myimage" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>

When a user presses submit without changing or removing the image, the form post contains an entry for ‘myimage’ without a new file. When clear is pressed the value for ‘myimage’ is an empty string. In PHP you could handle it as

1
2
3
4
5
  if (isset($_POST['myimage']) && $_POST['myimage'] == '') {
    // Delete file
  } elseif ($_FILES['myimage']['error'] == 0)  {
    // Save uploaded file
  }
  if (isset($_POST['myimage']) && $_POST['myimage'] == '') {
    // Delete file
  } elseif ($_FILES['myimage']['error'] == 0)  {
    // Save uploaded file
  }

Omit from POST

However this in some languages and frameworks you can’t easily make the distinction between no file being selected and the post containing an empty string. In that case you can use the `data-name` attribute and leave you the `name` attribute on the <input type="file">.

1
2
3
4
5
6
7
8
9
10
<div class="fileupload fileupload-exists" data-provides="fileupload" data-name="myimage">
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png">
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>
<div class="fileupload fileupload-exists" data-provides="fileupload" data-name="myimage">
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png">
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>

Now when the user presses submit without changing or clearing the file, the ‘myimage’ entry will not be part of the post data. In the next PHP example both $_FILES and $_POST are processed and present in $data.

1
2
3
4
5
6
7
  if (isset($data['myimage'])) {
     if ($data['myimage'] == '') {
       // Delete file
     } else {
       // Handle uploaded file
     }
  }
  if (isset($data['myimage'])) {
     if ($data['myimage'] == '') {
       // Delete file
     } else {
       // Handle uploaded file
     }
  }

Posting a specific value

In some cases this still won’t do, for instance when you’re using a form builder which combines the defaults with posted data. In that case you can manually add the <input type="hidden"> and set it to a specific value. (In the following example ’1′ is chosen, but you can also use the basename of the file or whatever you want.)

1
2
3
4
5
6
7
8
9
10
11
<div class="fileupload fileupload-exists" data-provides="fileupload" data-name="myimage">
  <input type="hidden" name="myimage" value="1" />
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png" />
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>
<div class="fileupload fileupload-exists" data-provides="fileupload" data-name="myimage">
  <input type="hidden" name="myimage" value="1" />
  <div class="fileupload-new thumbnail" style="width: 200px; height: 150px;"><img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" /></div>
  <div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px; max-height: 150px; line-height: 20px;">
    <img src="/images/example.png" />
  </div>
  <div>
    <span class="btn btn-file"><span class="fileupload-new">Select image</span><span class="fileupload-exists">Change</span><input type="file" /></span>
    <a href="#" class="btn fileupload-exists" data-dismiss="fileupload">Remove</a>
  </div>
</div>

In this case when the user presses submit without changing or clearing the file, the ‘myimage’ entry will be ’1′. When the user clears the image it will be an empty string. In the next PHP example both $_FILES and $_POST are processed and combined with all the default/original values as $data.

1
2
3
4
5
  if ($data['myimage'] === '') {
    // Delete file
  } elseif ($data['myimage'] !== '1') {
    // Handle uploaded file
  }
  if ($data['myimage'] === '') {
    // Delete file
  } elseif ($data['myimage'] !== '1') {
    // Handle uploaded file
  }

Please contribute

If you’re using the file upload component with Ruby, Python, C# or Java, please leave a comment with the above PHP examples in your language. Thanks.

Arnold Daniels

I've spend a big part of my life behind a computer, learning about databases (MySQL), programming (PHP) and system administration (Linux). Currently I playing with HTML5, jquery and node.js.

E-mailTwitterLinkedInGithubGittip

There are 7 comments in this article:

  1. 20 February 2013hyh says:

    Can u add some demo?

    ReplyReply
  2. 26 February 2013Vikram says:

    Hey Arnold,

    Thanks a lot for creating this library and sharing it. I have a question regarding the library. I am using the same code as you have mentioned in the sample. It works as expected on the iphone and android mobile devices. But, on the the ipad I am getting the banner with a “loading” text and icon. Is there something that I am missing to set in the function.

    I appreciate your help.

    Thanks,
    Vikram ..

    ReplyReply
  3. 1 March 2013Arnold Daniels says:

    @Vikram: I’m experiencing trouble on Android as well. The page is reloaded when using the element. I haven’t had the chance to test on iOS yet. Best just disable this element for mobile devices for now :(

    ReplyReply
  4. 2 April 2013Shiv says:

    Is there a way to make the input field required. If you add the “required” attribute to the field, but try and submit a parent form, no error message is produced. Am I missing something?

    Thanks!

    ReplyReply
  5. 16 April 2013Alex G says:

    @Shiv:
    Yeah, I am experiencing the same issue. If the file input is required and you don’t supply a file, no error is displayed. Not sure how to fix this :(

    ReplyReply
  6. 24 April 2013Michael G says:

    The work you put into this is great appreciated! I’m currently using it with Node.js/Express, with the help of req.files. If anybody wants an example, let me know and I can upload something to Github.

    ReplyReply
  7. 15 May 2013Arnold Daniels says:

    @Alex G and @Shiv: The actual input is hidden, so the message is hidden as well. You could use a solution like http://reactiveraven.github.io/jqBootstrapValidation/ to get around this.

    ReplyReply

Write a comment: