Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:list field, fake placeholder and empty value #109

Open
lambdam opened this issue Jul 4, 2016 · 3 comments
Open

:list field, fake placeholder and empty value #109

lambdam opened this issue Jul 4, 2016 · 3 comments

Comments

@lambdam
Copy link

lambdam commented Jul 4, 2016

Hello,

I would like to have the possibility to add a fake placeholder to select lists.

I found this : http://stackoverflow.com/questions/5805059/how-do-i-make-a-placeholder-for-a-select-box

So with reagent 0.5.1 and reagent-forms 0.5.22, this was working :

[:div
 [:select {:field :list :id :countries}
  (->> data ;; [{:value "germany" :text "Germany"} {...} ...]
       (map #(do [:option {:key (-> % :value)}
                  (:text %)]))
       doall
       (into [[:option {:key nil
                        :disabled true
                        :hidden true}
               "Select a country"]]) ;; Placeholder text
       seq)]]

But React/Reagent was throwing a warning: Warning: Every element in a seq should have a unique :key : ([:option {:key nil, :disabled true, :hidden true}...

After upgrading to reagent 0.6.0-rc, this doesn't work anymore. The first value of the sequence is displayed by default, no fake placeholder, and the value of the ratom (:countries here) is not selected when provided.

I tried this and removed the warning but it didn't work better as a bound form (with [bind-fields ... ...]):

[:div
 [:select {:field :list :id :countries}
  [:option {:key "placeholder-da39a3ee5e6b4b0d3255bfef95601890afd80709"
            :value nil
            :disabled true
            :hidden true}
   "Select a country"]
  (->> data
       (map #(do [:option {:key (-> % :value)}
                  (:text %)]))
       doall)]]

Is having the "key" attribute used for the React key and for the value a good thing? Here I really want and empty value so that null is returned to the API.

Thanks

@yogthos
Copy link
Member

yogthos commented Jul 10, 2016

It might be an idea to add a separate attribute that would be preferred to the :key if present. This would preserve the existing behavior, but would allow decoupling the React key from the value.

@noesis-software
Copy link

noesis-software commented Mar 20, 2018

I also had a related problem where I would end up with duplicate keys because the option values were the same. Here's the version I wrote which supports the :value attr on option elements in addition to supporting:key.

(defn- normalize-option-elt
  [[elt {:keys [key value] :as attrs} label]]
  [elt (assoc attrs :value (or value key)) label])

(defmethod reagent-forms.core/init-field :list
  [[type {:keys [field id] :as attrs} & options] {:keys [doc get save!]}]
  (let [options   (map normalize-option-elt (reagent-forms.core/extract-selectors options))
        selection (atom (or (get id)
                            (get-in (first options) [1 :value])))]
    (save! id @selection)
    (render-element attrs doc
      [type
       (merge
         (reagent-forms.core/clean-attrs attrs)
              {:default-value (reagent-forms.core/default-selection options @selection)
               :on-change #(save! id (reagent-forms.core/value-of %))})
       (doall
         (filter
           #(if-let [visible? (:visible? (second %))]
             (visible? @doc) true)
           options))])))

@yogthos
Copy link
Member

yogthos commented Mar 20, 2018

I'd be open to a pr to allow providing an explicit :value attr for this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants