Search code examples
htmlclojureclojurescriptreagenthiccup

Render table element with colspan in Reagent


I have a table in reagent and have set the col-span of a table header = 2.

 (defn my-table []
  [:table.table.table-striped.table-bordered
   [:thead
    [:tr
     [:th "Col1"]
     [:th "Col2"]
     (doall (for [id @ids]
          ^{:key id}
          [:th {:data-id (id :id)
                :col-span "2"}
           (str (get id :name))]))]]
   [:tbody
    (doall (for [i (range (count @table-items))]
         (let [table-item (cursor table-items [i])]
           ^{:key i}
           [item-row table-item])))]])

But in each row, see item-row below, I am looping through a data structure to grab the data for the split column in that row and am having issues. I can get the data to render properly if do

[:div [:td [:span (:id id)]]
             [:td [:span (:name id)]]]

which I know is incorrect/invalid html.

 (defn item-row [item]
    (fn []
      [:tr
       [:td [:span (:key1 @item)]]
       [:td [:span (:key2 @item)]]
       (doall (for [id @ids]
            ^{:key id}
            [[:td [:span (:x id)]]
             [:td [:span (:y id)]]]))]))

Does anyone have an idea on how render two :td elements in the for loop? My thought was to wrap the two :td elements in a vector and let reagent handle rendering the split columns.

 (doall (for [id @ids]
            ^{:key id}
            [[:td [:span (:x id)]]
             [:td [:span (:y id)]]])

I also get the following error: core.cljs:4793 Uncaught Error: No item [:td "."] in vector of length 2 at Object.cljs$core$vector_index_out_of_bounds [as vector_index_out_of_bounds]

which is correlated to [:td [:span (:y id)]]


Solution

  • You can take advantage of the fact that you are just returning data, so one way to do this is just build up the initial contents of the :tr vector with those first two columns and then add the rest of the :td elements in using into. Here's an example that I think will solve your problem:

    cljs.user=> (def ids [{:x 1 :y 2} {:x 3 :y 4}])
    #'cljs.user/ids
    cljs.user=> (let [tr [:tr 
           #_=>           [:td "first col"]
           #_=>           [:td "second col"]]]
           #_=>   (reduce (fn [acc id]
           #_=>             (into acc
           #_=>                   [[:td [:span (:x id)]]
           #_=>                    [:td [:span (:y id)]]]))
           #_=>           tr
           #_=>           ids))
    [:tr [:td "first col"] [:td "second col"] [:td [:span 1]] [:td [:span 2]] [:td [:span 3]] [:td [:span 4]]]
    cljs.user=>