PlutoUI.jl
                                
                                 PlutoUI.jl copied to clipboard
                                
                                    PlutoUI.jl copied to clipboard
                            
                            
                            
                        Button should return number of clicks?
Right now the Button always returns the same: the label of the button (String). This is fine, you can use the button to "trigger reactivity" just by referencing the bound variable somewhere:
https://github.com/fonsp/PlutoUI.jl/blob/v0.6.1/src/Builtins.jl#L64-L86
But if you only want to do something after the button is clicked, you need to write that logic yourself:
begin
    clicked_ref = Ref(false)
	@bind click Button("Do it!")
end
begin
	if clicked_ref[]
		something()
	end
    clicked_ref[] = true
end
Instead we could have the bound value be the number of times it was clicked:
@bind click Button("Do it!")
if click > 0
	something()
end
@GiggleLiu @dralletje
Another option is to add a new element: ToggleButton, which looks like a button, but feels like a checkbox
Returning the counter is definitely better, besides providing more information, it also makes it clear that a click changes a value. It took me a while to understand the meaning of a button, and the answer is "nothing" :rofl:
Returning a counter is not enough, a loophole of the above solution is
if click > 0
        other_vars
	something()
end
When click > 0 and other_vars is updated, it can still run.
I posted a possible solution here https://github.com/fonsp/PlutoUI.jl/issues/37#issuecomment-694432874
But that's reactivity 😅 I'll comment more on the other issue
Yeah, I mean it requires people to understand the logic of Pluto. Is it possible to let button return a button object so that one can use the button like:
if button.signal()  # this is not julian, see bellow.
    # do something
end
There is a field _signal in the button object, and
- set _signal = trueif the button is clicked,
- return the value of _signalwhen callingsignal(),
- signal()function will reset the- _signalfield to false.
onclick(button) do
	... 
end
:o
https://github.com/fonsp/PlutoUI.jl/issues/37#issuecomment-695217352
But won't returning the number of times it is clicked generate a hidden state, namely the number of clicks? If someone wants an incremental counter, they can simply trigger reactivity in a cell which also updates a variable.
Or implement a Counter which can be both incremented and decreased. A button shouldn't return how many times it's clicked, just the fact that it is clicked.
How about allowing to bind an already existing function name to the Button which then calls the function on click?
begin
  function onclick(text)
    dostuff()
    println("Button $text has been pressed")
  end
  @bind onclick Button("Do it!")
  @bind onclick Button("Do other!")
end
internal implementation might be a bit cumbersome but with (@isdefined binding) && binding isa Function && binding(text) this should be possible. Sure, that has the drawback that only functions can be used here, but that's a restriction that is very easy to overcome.
@rapus95 It's a cool idea, but if you think about, it does not work with the way you write interactivity in Pluto. The cool thing about Pluto is that, instead of callbacks, we work with global variables as the way to make things interactive. In fact, it is not possible for a function to produce any kind of visual output, since the are no display side-effects in Pluto.
@fonsp While that's true, there's no good way to barrier a cell from arbitrary evaluation on startup. We'd need an option to make a cell ONLY execute on the click of a button. I.e. there's no elegant way to prevent evaluation until the click.
@bind num_clicks Button()
if num_clicks > 0
	...
end
And the counter is reset once the cell with the @bind is re-evaluated, right? Then that would be awesome. Is there an eta for it? :D
In fact, it is not possible for a function to produce any kind of visual output, since the are no display side-effects in Pluto.
That could individually be solved by adding some sort of triggerupdate(:trigger) function that allows for manually triggering the flow graph for certain variables. Though, I see that would make it necessary to wrap every cell into its own function and pass it a global state object 🤔 Probably not worth the effort.
Will the feature that the button references the click counter make it into Pluto? Arbitrarily breaking out of reactivity would also be very easy since it just requires an additional ref that holds a "counter at last time executed" number or any other relative number. I.e. triggering by comparison to a reference value.
Together with https://github.com/fonsp/disorganised-mess/blob/f0f13eb4038604f0cccf12922cea6a4c635c6633/javascript.jl#L97-L128 (and div replaced by span in order to allow inline) the following code
begin
	reactivitybreaker = Dict{Symbol, Int}()
	function needsupdate(x::Symbol, value)
		value != get(reactivitybreaker, x, 0)
	end
	function update!(x::Symbol, value; force=false)
		if force || needsupdate(x, value)
			reactivitybreaker[x] = value
			return true
		end
		return false
	end
	macro update!(x)
		return Expr(:call, :update!, QuoteNode(x), esc(x))
	end
end
allows for
@bind clicker ClickCounter("Click It!")
to be the only way to trigger the following print
if @update!(clicker)
  println(clicker)
end
I added CounterButton in PlutoUI 0.7.16 which does https://github.com/fonsp/PlutoUI.jl/issues/38#issuecomment-818532913
In PlutoUI 0.8.0 I will CounterButton the default Button.