Fork me on GitHub
#hoplon
<
2016-04-16
>
leontalbot02:04:06

@jumblerg: "try pulling the responsive-layout-attributes branch of hoplon now and boot build-jar" I confirm it now works simple_smile

leontalbot02:04:41

@jumberg In hoplon/ui are there ways to use custom stylesheets that hack bootstrap defaults? Is porting a bootstrap template I bought a good idea? Thanks!

leontalbot02:04:03

I suppose I just declare css stylesheets, and same classes name will overwrite boostrap defaults, is that correct?

leontalbot03:04:06

from looking at the source, I guess I just do (which is cool by the way):

(u/window 
 ...
  :styles      ["css/bootstrap-theme.css"]
...)

leontalbot03:04:09

Ok, it works, though I must not use (u/button hoplon.ui/+danger-button+ ...) but rather call (u/button :class "btn-danger" ...)

leontalbot03:04:09

I must specify classes and not rely on +ui/vars+

leontalbot03:04:13

What is cool is that the rest of the attributes like :w ["100%" sm 200] still works.

leontalbot03:04:58

so far so good, good night, and sorry for the noise folks... Talking alone in the channel helped me stay awaken a little later 😛

levitanong03:04:32

you’re not alone. creepy

leontalbot04:04:51

@jumblerg: I was mistaken. u/button has defaults such as transparent background so that when I use :class btn-danger the default u/button css specs overrides the theme's class specs, because u/button writes inline css like so style="background-color: transparent; ..." which has the priority...

leontalbot04:04:59

But, if I use regular buttonfn, I can call the class AND still use the rest of the attributes like :w ["100%" sm 200] great!

leontalbot04:04:42

i could also create a custom var like so (def +danger-button+ {:color 0xd9534f :s-color 0xd43f3a :font-color 0xfff}) but when using bootrap theme, this will take much time to convert into vars, so I guess I'll stick with classe and regular html elements.

leontalbot04:04:49

Thank you in advance for your reading 😛

leontalbot04:04:37

@jumblerg: So far, I feel hoplon/ui gives you much control over the ui, but you need to invest some time up front, to convert regular bootstrap theme to fit the ui model. Can't wait to get your feedback on how to integrate a custom bootstrap theme simple_smile

thedavidmeister06:04:10

if you have this:

thedavidmeister06:04:13

(let [state-1 ["a" "a"]
              state-2 ["a"]
              current (cell [])]
          [(span "state 1" :click #(reset! current state-1) (br))
           (span "state 2" :click #(reset! current state-2) (br))
           (loop-tpl :bindings [i current]
            (input :value i))])))))

thedavidmeister06:04:38

you can click “state 1” and “state 2” all day and see the inputs update correctly

thedavidmeister06:04:11

but if you click “state 1” and then delete the value in it manually (clicking in the input and hitting delete) and then click “state 2"

thedavidmeister06:04:33

the loop-tpl does not build the inputs correctly for state 2

roti12:04:06

I am trying to define a :value-bind attribute, like this:

(defmethod do! :value-bind [elem _ opts]
           (let [ref (first opts)
                 path (rest opts)]

                (do! elem :change (fn [jq-event]
                                      (swap! ref assoc-in path (.-value (.-target jq-event)))))

                (do! elem :value (cell= (get-in ref path)))))
Sadly, both calls to do! are not working as expected. My change handler gets called with jq-event beeing 0. The second call to do! does not get the value out of the cell, so my input field gets the value "[object Object]". Any ideas?

micha12:04:40

the :change there is an event, no?

micha12:04:52

you want to use the on! multimethod for that

jumblerg12:04:00

@leontalbot: two of the ideas behind hoplon/uiare the notions that (1) selector queries should be avoided due to their unmanageability and inefficiency and (2) that it more cohesive to associate attributes with the elements to which they belong; placing them elsewhere leads to a poor separation of concerns. css runs contrary to both of these ideas by requiring the use of selectors for everything and factoring styles out into a separate language entirely. consequently, my approach to hoplon/ui is not to support them. we don’t need to use id or class attributes at all because we rely on the use of variable bindings instead of selectors.

jumblerg13:04:53

if you want to convert a bootstrap theme into one for hoplon/ui, you`d need to simply associate the stylistic attributes (like colors, font sizes, etc) with clojurescript vars like i do at the top of ui.cljs.hl then bind to them from your code. it is perhaps a bit more effort up front, but i can assure you from by own experience that it saves me an enormous amount of time afterwards. it’s quite nice to get an error and a stack trace when you make a stylistic mistake because you used a var instead of a query to associate a style with an element.

jumblerg13:04:36

i’ll try to write some documentation after my current project at work is over (sometime next week).

roti13:04:14

@micha: indeed, using on! works. thank you

micha13:04:07

@roti i think there might be an issue with your code though

micha13:04:07

the body will be evaluated multiple times if the attribute value (the vector) is itself a cell

micha13:04:37

so it could add multiple times the event handler

micha13:04:50

like if you do

micha13:04:46

(div :value-bind (cell= ...))

roti13:04:52

do you know why :value does not work?

micha13:04:39

@roti oh yeah i did n't notice that

micha13:04:54

the do! multimethod doesn't know anything about cells

micha13:04:01

it's just a regular function

micha13:04:16

for example, if you do this

micha13:04:28

(div :value (cell= ...))

micha13:04:40

hoplon adds a watch to the cell

micha13:04:06

and whenever the cell changes it calls (do! elem :value @the-cell)

micha13:04:11

does that make sense?

micha13:04:33

the do! multimethod is at a lower level than the reactive bindings basically

micha13:04:09

you could replace (do! elem :value (cell= ...)) with (elem :value (cell= ...))

micha13:04:16

that will fix the issue you see

roti13:04:56

wait, elem is the dom element, not the function that creates it

roti13:04:14

so what's the result of calling a dom node?

micha13:04:19

well every dom element is also a function

micha13:04:25

in hoplon

micha13:04:36

that's the thing that hoplon adds to the DOM model

micha13:04:45

that's why you can do like this

micha13:04:59

((div "hi") "world")

micha13:04:24

in hoplon you can invoke a dom element as a function

micha13:04:51

invoking a dom element is equivalent to appendChild or setAttribute, depending on the arguments

micha13:04:59

just like html really

roti13:04:15

quite nice

micha13:04:20

this means that you can do:

micha13:04:40

(def my-thing (div "hello world"))

...
(my-thing :class "foobar")

micha13:04:14

that's pretty important because my-thing is a dom element, but it might come from some other module of code

micha13:04:31

and that other modiule doesn't know about which classes you will want at the presentation layer

micha13:04:41

it might be a general purpose constructor

micha13:04:34

so without the ability to invoke dom elements as functions you would have to add a class parameter to the constructor for your custom element

micha13:04:47

and you end up with the spaghetti hell of like php templates

micha13:04:06

keep adding more arguments to a function whenever you need to do something slightly different

roti13:04:45

what I have done until now in the constructor of the custom element is to pass whatever arguments I don't recognize to the created element simple_smile

roti13:04:04

but using nodes like that is quite nice

roti13:04:29

I suspect I will run into some issues because these functions are destructive without beeing very obvious, but let's see...

micha13:04:38

yeah what i mean is that the piece of code that calls the constructor doesn't always know all the attributes the final element will need to have

micha13:04:56

most of the time you will separate those concerns

micha13:04:36

there is a slight mismatch though

micha13:04:56

i have been trying to address that with the defelem+ form

roti13:04:59

what's the mismatch?

micha13:04:27

like consider:

micha13:04:01

(defelem my-list
  [attr kids]
  (ul (map li kids)))

leontalbot13:04:11

@jumberg Gotcha! Your point of using vars is persuasive. +1 for activating the wiki of your github repo. I could help you document. Would you see an FAQ? We could use some of the questions asked on slack and put back your answers there.

leontalbot13:04:32

For a start...

leontalbot13:04:22

As you wish...

micha13:04:42

(defelem my-list
  [attr kids]
  (div
    (ul
      (map li kids))))

(my-list "one" "two" "three")
<div>
  <ul>
    <li>one</li>
    <li>two</li>
    <li>three</li>
  </ul>
</div>

((my-list "one" "two") "three")
<div>
  <ul>
    <li>one</li>
    <li>two</li>
  </ul>
  three
</div>

micha13:04:28

@roti: see the problem?

micha13:04:41

the my-list function returns a div

micha13:04:03

so applying the div to "three" just appends a text node to the div

micha13:04:15

but the arguments to my-list had a different meaning

micha13:04:30

children would go in the list and be wrapped in li elements

micha13:04:04

ideally the two examples would result in the same dom structure

micha13:04:38

with defelem+ that issue is fixed

micha13:04:54

but it has its own quirks lol

jumblerg15:04:02

@leontalbot: anything you can do to help would be very much welcome. simple_smile

leontalbot21:04:28

@jumblerg: So i've put together a FAQ. Very drafty. I just searched for your name in the Slack recent archives (March 31 up) and selected some Q&As. https://github.com/hoplon/ui/wiki/FAQ

leontalbot21:04:25

I'd say the "Why hoplon/ui?" answer would be the one that would need love the most. That could be the premise of your manifesto. I encourage you to edit it! Cheers!

jumblerg21:04:40

@leontalbot: excellent - it’s great to have another contributor! and many thanks! simple_smile

leontalbot23:04:52

Glad to help!