Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Show preview of image in form

I want to achieve the following in a django form, for a models.ImageField:

  • do not show the standard <input type="file"> button ("choose file" button)
  • show a preview of the current image, for already populated models
  • for empty (new) models, show a custom button
  • clicking on the image preview or the custom button will open a file dialog to select the image from the user's file system
  • selecting a new image replaces the custom button or the old image preview with the preview of the new image

This seems to me like a normal workflow to select images in a form, but I do not seem to find any fully working solution. All I can find involves hacking around several parts:

  • styling the label and hiding the standard "choose file" button: https://www.youtube.com/watch?v=4p2gTDZKS9Y
  • use a widget instead of the standard for forms.FileField.

I have tried to use:

class ImagePreviewWidget(Widget):

    def render(self, name, value, attrs=None):
        return mark_safe('<img src="/media/%s" width="100px"/>' % escape(value))

For the widget, and I am using this in the form like this:

class DesignCampaignForm(ModelForm):

    brand_logo = FileField(widget=ImagePreviewWidget)

This is properly showing the preview of the existing image, but I am unable to click on it to select another file, and even if I was that would not update the preview.

Is there an already available solution for this simple use case?

like image 975
blueFast Avatar asked Oct 31 '15 19:10

blueFast


1 Answers

I haven't been able to find a complete solution, so I have done the following:

  • use a widget to render a modified ClearableFileInput, rendering an image and an <input> element
  • style the <input> in the element with CSS, to hide it
  • make sure that clicking in the image triggers the hidden <input> element, wrapping the <img> in a <label> and using the for attribute
  • add some javascript to replace the image preview whenever the selection in the <input> element changes
  • whenever the selection is cleared, show the original preview

A gist can be found here.

In my final solution (not yet in the gist), I have added a button for when the image is not yet selected.

edit: Gist only works for Django before version 1.11.x.
class ClearableFileInput has since been gutted and changed

like image 62
blueFast Avatar answered Sep 26 '22 21:09

blueFast