Fork me on GitHub
#clojurescript
<
2023-03-13
>
M J07:03:28

Im using a re-com selection list, any ideas how to target the checked items to give them a different class? I want list-group-item to have a different class when it is checked or selected..

[selection-list :src (at)
    :class (selection-list-style)
    :hide-border? true
    :model          selections
    :choices        multi-select-items
    :label-fn       :label
    :as-exclusions? false
    :multi-select?  (:allow_multiple settings)
    :disabled?      false
    :required?      false
    :parts {:list-group {:class (list-group-style)}
            :list-group-item {:class (list-group-item-style )} 
            :checkbox {:class (list-group-checkbox-style {:color (:buttons_color theme-data)})}
            :radio-button {:class (list-group-radio-btn-style {:color (:buttons_color theme-data)})}}
    :on-change      (fn [value]
                      (reset! selections value)

                      (reset! new-session false))]

p-himik11:03:09

The :item-renderer function. Although the docs incorrectly state that it's "a function which takes no params and returns nothing". Judging by the source, it's a function that accepts choice id-fn selected on-change disabled? label-fn required? as-exclusions? and returns Hiccup for a particular item.

M J11:03:01

is there an example of how i can use it?

p-himik11:03:11

Right there in the sources are as-checked and as-radio. The only difference is that those functions also accept parts.

M J12:03:42

sorry im quite a beginner at re-com and cant make it work tbh. i wanna include it with my existing classes in the parts I want a simple working example that works, that i can play with

p-himik12:03:29

What have you come up with that doesn't work?

M J12:03:44

(defn my-item-renderer [item id-fn selected on-change disabled? label-fn required? as-exclusions?]
  [:div
   {:on-click #(do (reset! selected item) (println (str "Item " item " clicked!")))}
   (if selected
     [:span.selected (label-fn item)]
     [:span (label-fn item)])])

[selection-list :src (at)
    :class (selection-list-style)
    :hide-border? true
    :model          selections
    :choices        multi-select-items
    :label-fn       :label
    :as-exclusions? false
    :item-renderer (r/atom nil)
    :multi-select?  (:allow_multiple settings)
    :disabled?      false
    :required?      false
    :item-renderer my-item-renderer
    :parts {:list-group {:class (list-group-style)}
            :list-group-item {:class (list-group-item-style  {:background-color (str (:answers_background_color theme-data) "60")
                                                              :border-color (:answers_border_color theme-data "#9c9ea8")
                                                              :answer-color (:answers_color theme-data)
                                                              :border-size "1px solid"
                                                              :style {:focus-visible {:outline "2px solid blue"}}})}
            :checkbox {:class (list-group-checkbox-style {:color (:buttons_color theme-data)})}
            :radio-button {:class (list-group-radio-btn-style {:color (:buttons_color theme-data)})}}
    :on-change      (fn [value]
                      (reset! selections value)
                      (println (str "val: " value))
                      (reset! new-session false))]
Now tre is no checkbox or radio, its only divs when I use th item-renderer

p-himik12:03:28

Try copying the as-select function first and removing its parts argument and everything that uses it. It should work right away. And start from there.

p-himik12:03:50

Also, why :item-renderer (r/atom nil)? It must be a function, not a ratom.

M J12:03:32

this was supposed t be deleted, im uaing the below item-renderer. which as-select function?

p-himik12:03:06

Sorry, I meant as-checked.

M J14:03:14

is there an example of one tht works and is simple? i can manag from there..

p-himik14:03:38

as-checked is such an example. What issues do you have after copying it verbatim and replacing the code that uses parts?

M J14:03:32

copy it as is in place of parts without item-renderer?

p-himik15:03:15

I meant it as "copy the implementation of as-checked and use it as the body of your my-item-renderer but replace all the parts that use the parts argument with something reasonable".

Olaleye Blessing17:03:46

Has anyone tried sending event from Clojurescript to Phoenix Liveview? It works locally but the live version throws an error saying:

Uncaught TypeError: b.ce is not a function
    at HTMLDocument.<anonymous> (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2579:303)
    at HTMLDocument.Wi (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2494:405)
    at HTMLDocument.a (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2493:38)
    at gj (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2495:1306)
    at Km (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2582:222)
    at app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2587:267
    at Function.e [as j] (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2586:203)
    at dk (app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2520:162)
    at app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2520:312
    at app-009ad4db669c2c11ee60f472612576b5.js?vsn=d:2511:337

p-himik17:03:42

No clue about LiveView and what "sending" here means and entails, but, assuming that "live version" also means "compiled with advanced optimizations" and "locally" means "compiled with none or simple optimizations", then those optimizations are likely to blame. Something gets renamed - something that shouldn't be. Impossible to tell from this stacktrace, but you can compile optimized code with pseudo names - that should get you going in the right direction.

p-himik17:03:55

Also pay attention to "cannot infer type" warnings.

Olaleye Blessing17:03:51

Thanks, I just noticed cannot infer type warning is turned off.

thheller17:03:37

yeah, that looks like an externs issue

Olaleye Blessing08:03:44

I'm still on the issue but I'll describe briefly what I'm trying to achieve.

(ns app.utils.events
  (:require
   [goog.events :as gevents]))

# create custom event
(defn- create [ev payload]
  (js/CustomEvent. ev
                   (clj->js {:detail {:payload payload}})))

# dispatch custom event
(defn dispatch
  "Dispatches the event `ev` with the `payload` on the `js/document`
   element by default, but allows specifying a different `target` element."
  ([ev payload]
   (dispatch ev payload js/document))
  ([ev payload target]
   (let [ev (create ev payload)]
     (.dispatchEvent target ev))))

# listen to event
(defn listen
  "Listens for events on element `el` and executes function `f` when
   triggered.

   Saves non-phx events to enable listener cleanup on unmount, as phx
   events are registered only once on live view mount and don't
   require cleanup."
  ([el ev f] (listen el ev f false))
  ([el ev f is-phx?]
   (when el
     (gevents/listen el ev f)
     (if (not is-phx?)
       (update-state :ui {:el el
                          :ev ev
                          :f f})))))
I dispatch the event:
(ns app.services.wallets.metamask
  (:require
   [app.utils.events :as events]))

(defn- test-dispatch []
  (events/dispatch "relay-data"
                   {:address "3893937927293739339"}))
And I listen to events:
(ns app.hooks
  (:require
   [app.utils.events :as events]))

;; (set! *warn-on-infer* false)

(defn- payload [ev]
  (.. ev -event_ -detail -payload))

(defmulti listen
  "Listens for event `ev` and executes function `f`.

   ;; Usage:
   (listen key this ev)
   "
  identity)

(defmethod listen :relay [_ this ev]
  (events/listen js/document
                 ev
                 #(.pushEvent this ev (payload %))
                 true))

(defn- callback [hook evs]
  {:mounted #(this-as this
                      (doseq [ev evs]
                        (listen hook this ev)))})

(defn callbacks
  "Map of livesocket hook callbacks used in the app. They are
   passed to the socket in the `app.main` namespace."
  []
  {:relay (callback :relay ["relay-data" "alert"])
  ;;  other hooks here
   })
Then I got this warning:
(.. ev -event_ -detail -payload))
iex(1)> ---------^----------------------------------------------------------------------
iex(1)>  Cannot infer target type in expression (. ev -event_)
#(.pushEvent this ev (payload %))
iex(1)> -------------------------^------------------------------------------------------
iex(1)>  Cannot infer target type in expression (. this pushEvent ev (payload p1__11520#))
@U2FRKM4TW @U05224H0W

p-himik08:03:43

No need to @ - participants of a thread will be notified when something is posted there, unless they've unsubscribed from the thread. https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html

🆗 2
p-himik08:03:23

tl;dr: Add ^js in front of ev for the first warning and in front of this for the second (although weird that you got the warning for this).

p-himik08:03:32

@U05224H0W Do you think it would make sense to add that or some other link to that warning? Awfully often mentions of the warning are followed by answers with that link or some run-of-the-mill explanation.

Olaleye Blessing08:03:47

Thanks, I no longer have the warnings. I'll go ahead and test the live version.

Olaleye Blessing09:03:58

It's working. Thanks. Thanks for the help.

👍 2
Drew Verlee23:03:59

my project is using this cljs library and it's causing a build error because of a dependency issue. The required namespace ".cookies" is not available, it was required by "com/smxemail/re_frame_cookie_fx.cljs". So I'm not sure why it's not available, but if I look at the library https://github.com/SMX-LTD/re-frame-cookie-fx/blob/972f4f58d8427b91d29a1bf73450a8fec6b263c3/src/com/smxemail/re_frame_cookie_fx.cljs#L4. But if I used my projects cljs repl to try and require the goog.net.cookies library its not on the classpath. However, I can import it. (e.g (import goog.net.cookies) I'm trying to wrap my head around whats going on here in the most economical way possible.

thheller00:03:59

goog.net.cookies was a deprecated namespace and was removed in the latest closure library update that shadow-cljs just started using in 2.22.+

thheller00:03:54

so you can either downgrade the closure library to the older release

thheller00:03:15

or switch the code to not use that. goog.net.Cookies is the proper ns

👍 2
Drew Verlee00:03:52

Thanks heller, that's what it looked like on my end to.

p-himik06:03:24

I would suggest against using libraries like re-frame-cookie-fx, unless such a library does something magical (and then I would suggest against it for another reason). It's just 50 lines of code if you reformat it and remove obvious comments and extra whitespace. And much less if you remove all the things you don't use (I assume you don't need each and every coeffect from there).

👀 2
👍 2