0

Let's assume that we have this grid with values that can be 0 or 1:

(def grid [[1 0 1]
           [1 0 0]
           [1 0 1]])

Now I want to transform grid into an html Hiccup like format using list comprehension:

(defn cell-component [is-it-1 key]
  ^{:key key} [:td (if (= is-it-1 1) {:class "is-it-1"})])


(defn grid-html []
  ([:table
   [:tbody
   (for [row grid]
      ^{:key row} [:tr 
                      (for [cell row]
                      (cell-component cell how-i-can-generate-a-index?))])]]))

The table is generated correctly but I don't have any ideas to how to make a unique index for my td. what how-i-can-generate-a-index? should be?

Michel Uncini
  • 321
  • 1
  • 14
  • As a side note: the round parentheses around `[:table ...]` in `grid-html` are redundant (and the code won't run with them as they translate to a function call - while you just need to return the component: `(defn grid-html [] [:table [:tbody ... ]])`) – Aleph Aleph Dec 03 '16 at 13:24
  • Just use `map-indexed` instead of the for. – ClojureMostly Dec 03 '16 at 17:48

3 Answers3

2

In your case, each cell is uniquely identified by its index within the row. Also, it would be more natural to specify the children's keys in the parent structure rather than in the components:

(defn cell-component [is-it-1]
  [:td (if (= is-it-1 1) {:class "is-it-1"})])

(for [[i cell] (map-indexed vector row)]
  ^{:key i} [cell-component cell])

Note that you should similarly assign index-based keys to rows - ^{:key row} won't work if you have duplicating rows in your table.

Aleph Aleph
  • 5,215
  • 2
  • 13
  • 28
0

You simply need to call gensym:

(cell-component cell (gensym))

That is a generic way to do it. However usually it is better to find some attribute in your data that already provides unique differentiation.

If you prefer to see numbers counting from 0 up then you can write your own sequence generator:

(def uniq-key (atom -1))
(defn gen-key []
  (swap! uniq-key inc)) 

With the above the first time you call (gen-key) you get 0 back, the second time 1 etc.

Chris Murphy
  • 6,411
  • 1
  • 24
  • 42
  • I could do it but with `gensym` a new symbol is generated and the all point of reagent and the key attribute is to have a unique id in your data. Do you have any idea how to create an index from 0 to (grid-size * grid-size)? If not I may allways doing what you said and add some metadata on my data – Michel Uncini Dec 03 '16 at 12:10
0

I recommend to define reagent components accepting props and children as parameters.

(defn my-li
  [:keys [a-string]]
  [:li
   a-string])

(defn my-list
  [{:keys [color]} & children]
  [:ul
   {:style {:background-color color}}
   (map-indexed #(with-meta %2 {:key %1}) children)])

(defn thelist []
  [my-list
   {:color "#ccc"}
   [my-li "one"]
   [my-li "two"]])

Adapted from https://github.com/reagent-project/reagent/issues/68

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jp_
  • 5,973
  • 4
  • 25
  • 36