Dirk Dot Net

Creator of useful things. Based in Chiang Mai, Northern Thailand.

Star Rating Control with Clojurescript, Reagent, Facebook React JS

There are at least two Star Rating components for Facebook React that can be used with the brilliant Reagent.

I found these to be too complex and neigh impossible to integrate with Reagent so I came up with a simple solution like so:

(ns my-star-rating-control
  (:require [reagent.core :as reagent :refer [atom]])
  )
  
(defonce star-rating-info
  (atom {
         :rating-temp 0
         :rating 0
         :clicked false
         }))

(defn get-attr [x]
  (-> x .-target (.getAttribute "data-index") js/parseInt)
  )

(defn si-update [elem-kw upd]
  (swap! star-rating-info update-in [elem-kw] upd))

(defn set-active [index item-kw]
  (if (<= index (get-in @star-rating-info [item-kw]))
    " star_active"
    " star_inactive"))

(defn star-item [index]
  [:span {:class (str "rating_star" (if (get-in @star-rating-info [:clicked])
                                      (set-active index :rating)
                                      (set-active index :rating-temp)
                                        ))
          :data-index index
          :on-mouse-enter #(do
                             (si-update :rating-temp (fn [] (get-attr %)))
                             (si-update :clicked (fn [] false))
                             )
          :on-mouse-leave #(si-update :rating-temp (fn [] 0))
                                        ;:on-mouse-leave #(js/alert (-> % .-target (.getAttribute "data-index")))
          :on-click #(do
                       (si-update :rating (fn [] (get-attr %)))
                       (si-update :clicked (fn [] true)))

          } "\u2605"]
  )

(defn five-stars []
  [:div.star_container
   (for [x (range 1 6)]
   [star-item x])
   ])

It should be called like any other reagent component:

[five-stars]

Here's some styling:

.rating_star
{
    font-size: 32px;
    cursor: pointer;
}    

.star_active
{
 color: #F6B11C;
}

.star_inactive
{
    color: #D3D3D3;
}

The magic of Facebook React, Reagent and Clojure/Clojurescript is really coming together nicely here. Surely there are a few problems, e.g. that the user has to click the star pretty much exactly. But he gets proper feedback and it could be fixed with css.

Hope it helps.