How to style your input file in Reagent with Bootstrap

Ok this caused me a lot of headache, hope it will help anyone.
In bootstrap the only way to style a input with type file, is to close it in a label. Like this:
  • <label class="btn btn-default btn-file"> Browse <input type="file" style="display: none;"> </label>
   

Unfortunately, as things are now, the only way to do something like this in Reagent is to set the InnerHhtml and do something like this:

(defn ^:export on-click
  [event]
  (js/alert "Upload Button Clicked")

(defn ^:export on-change
  [event]
  (js/alert "File Changed)

(def input-html "<input id='upload-file' name='updload-file' type='file' 
style='display: none;' onclick='{ns}.table.on_click(event)' 
onchange='{ns}.table.on_change(event);'></input>")

[:label.btn.btn-primary.col-span-1
     {:dangerouslySetInnerHTML
      {:__html (str (label-input "Select File") input-html)}}]


Also the javascript functions that will be called will have to be exported and called using {ns}.function
This is the only 'non elegant' solution that is possible now.
An interesting thing that give me headache was this one.
I wanted to change the label str ("Select File") in the on-change function. I used a reagent atom for that and changed the label in this way:

(def label (reagent/atom "Select File"))

(defn ^:export on-change
  [event]
  (reset! label "New Label)
[:label.btn.btn-primary.col-span-1      {:dangerouslySetInnerHTML       {:__html (str (label-input @label) input-html)}}]
This actually cause the input to loose it's file because React replace the <label> with it's html recreating the input and loosing the file.
Hope this will prevent some other guys to have the same headache I had :D

Comments