How to use btn__toggle in Stipple

Hi and thank you @hhaensel :smiley:

How can I use btn__toggle in Stipple? I think my struggle is the options property. I can’t get it to work no matter what syntax I use (copy-paste the JS from the example, vector of named tuples, vector of Dicts, Dict of vectors, etc).

Where exactly is your problem? Do you want to exchange the text of the buttons?
If you just want a static version than it is straight forward

Base.@kwdef mutable struct ButtonToggle<: ReactiveModel
    btntoggle::R{String} = ""
end

btn_opt(label::AbstractString, value::AbstractString) = "{label: '$label', value: '$value'}"
btn_opt(labels::Vector, values::Vector) = "[ $(join( btn_opt.(labels, values), ",\n  ")) ]"
btn_opt(values::Vector) = btn_opt(values, values)

function ui()
    app = dashboard(vm(model),
        [
         heading("Button Toggle"),
         row(cell(class="st-module", [
            quasar(:btn__toggle, "", 
                @bind("btntoggle"),
                toggle__color="primary",
                :multiple,
                options=@data(btn_opt(["One", "Two", "Three"], ["one", "two", "three"]))
            )
        ])),
    ], title = "Button Toggle")

    html(app)
end
1 Like

This indeed solved it. I didn’t know about the @data macro or its need…

Is there a non-static version of this? I need the labels to be part of the model. The user (you know the story by now) uploads a file, and the content of the file dictates the labels.

Seems to be more difficult, as we have to supply an array of objects

Maybe there is a way to do that with a separate route… For one, I can have an initial page that is only for uploading the settings file, and once that’s done, then the dashboard page gets loaded (somehow).

Not sure how to proceed.

use Dictionaries :slight_smile:

btn_opt(label, value) = Dict(:label => label, :value => value)
btn_opt(values::Vector) = btn_opt.(values, values)
julia> model.btn_options[] = btn_opt(["one","two","three"])
3-element Array{Dict{Symbol,String},1}:
 Dict(:value => "one",:label => "one")
 Dict(:value => "two",:label => "two")
 Dict(:value => "three",:label => "three")

julia> model.btn_options[] = btn_opt(collect(1:3))
3-element Array{Dict{Symbol,Int64},1}:
 Dict(:value => 1,:label => 1)
 Dict(:value => 2,:label => 2)
 Dict(:value => 3,:label => 3)

And to see it in action:

using Stipple, StippleUI
using Genie.Renderer.Html

Base.@kwdef mutable struct JSmethods <: ReactiveModel
    x::R{Int} = 0 # pressing this will update the array of buttons
    btntoggle::R{Any} = ""
    btn_options::R{Array} = btn_opt.(["One", "Two", "Three"], ["one", "two", "three"])
end

function restart()
    global model
    model = Stipple.init(JSmethods(), debounce=1)
    on(model.x) do x
        model.btn_options[] = x == 0 ? btn_opt(["one", "two", "three"]) : btn_opt(string.(1:3))
    end
end

Stipple.js_methods(::JSmethods) = raw"""
    showNotif (m) {
        this.$q.notify({
            message: m,
            color: 'purple'
        });
        this.x = 1 - this.x;
    }
"""

btn_opt(label, value) = Dict(:label=>label, :value=>value)
btn_opt(values::Vector) = btn_opt.(values, values)

function ui()
    app = dashboard(vm(model),
        [
         heading("jsmethods"),
         row(cell(class="st-module", [
            p(button("Change text", @click("showNotif(\"New labels!\")"))),
            quasar(:btn__toggle, "", @bind("btntoggle"), toggle__color="primary", :multiple,
                options=:btn_options
            )
        ])),
        ], title = "jsmethods")

    html(app)
end

route("/", ui)
Genie.config.server_host = "127.0.0.1"
restart()
up(open_browser = true)

1 Like