10

I am attempting to style my Django file upload button, but since it's handled through the form and not explicitly written in the HTML within the template I cannot style it directly with HTML and CSS like I can for other buttons of type input.

I've attempted to add my CSS class within my forms.py, but it is placing the vanilla default Django file upload button on top of my CSS styled button.

My code is as follows:

class FileUploadForm(forms.Form):
    docFile = forms.FileField(
        label = "Select a CSV file",
    )

    class Meta:
        model = FileUpload
        fields = ('docFile')

    def __init__(self, *args, **kwargs):
        super(FileUploadForm, self).__init__(*args, **kwargs)
        self.fields['docFile'].widget.attrs.update({'class': 'my_class'})

I also tried defining a widget within my Meta class like so:

class Meta:
        model = FileUpload
        widgets = {
            'docFile': forms.FileInput(attrs={'class': 'my_class'}),
        }

but that had the same effect as my first attempt.

Is there a different way of accomplishing this or are there some logical errors that you can spot within my code?

alacy
  • 4,972
  • 8
  • 30
  • 47
  • Just to be specific... is the problem that you don't see this class added in the rendered HTML (Django problem)? Or are you unable to override the CSS set by default (CSS problem)? – dylrei Jan 13 '15 at 19:15
  • I can see my custom CSS, but the problem is that the default `File Upload` button that triggers the file picker is then placed on top of my CSS styles. So it seems that it could be a problem on both the CSS or the Django side. – alacy Jan 13 '15 at 19:21
  • So... you look at the HTML source of a rendered form and your button has a class of my_class? Then it's a CSS problem. Possible solutions include loading your CSS later and/or adding the !important option or doing a quick JS call at the bottom of your template to force a different style on the button. – dylrei Jan 13 '15 at 19:29
  • @dylrei Yeah it looks like a CSS problem then. I tried your solutions but without success unfortunately. – alacy Jan 13 '15 at 19:37
  • 1
    Might be helpful to see this discussion: http://stackoverflow.com/questions/14401550/adding-style-to-file-upload-button-in-css – dylrei Jan 13 '15 at 19:46

2 Answers2

5

For posterity's sake here is the solution which I found using Bootstrap here.

.fileUpload {
 position: relative;
 overflow: hidden;
 margin: 10px;
}
.fileUpload input.upload {
 position: absolute;
 top: 0;
 right: 0;
 margin: 0;
 padding: 0;
 font-size: 20px;
 cursor: pointer;
 opacity: 0;
 filter: alpha(opacity=0);
}
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"/>
<div class="fileUpload btn btn-primary">
    <span>Upload</span>
    <input type="file" class="upload" />
</div>
alacy
  • 4,972
  • 8
  • 30
  • 47
3

If you want to style the file upload button define another button or link and style that. Then set it's click event to trigger file upload button.

HTML:

<div>
    <a id="browse" class="my_class">Browse</a>
    <input type="file" name="data" style="display: none" />
</div>

Javascript:

$('#browse').click(function(){
    $(this).parent().find('input').click();
});

To make this work in a Django form you can do it by a widget.

nima
  • 6,566
  • 4
  • 45
  • 57
  • I tried using a `widget` as shown in the original question, but it rendered the same result as when I defined the attribute in my `__init__()` function. – alacy Jan 13 '15 at 19:27
  • I meant a custom widget with the above html and js. – nima Jan 13 '15 at 19:28