Occur error when trying to get and change button.label in its CustomJS callback

buttonclick = CustomJS(args=dict(div=div, sl=slider, b1=button1), code="""
    if (cb_obj.label == '► Play'){
        div.text = cb_obj.label;
        alert(cb_obj.label);
        cb_obj.label = '❚❚ Pause';
        cb_obj.change.emit();
    }
    else{
        cb_obj.label = '► Play';
        div.text = cb_obj.label;
        alert(cb_obj.label);
        cb_obj.change.emit();
    }
    
    /*
        function update() {
            div.text = sl.value.toString();
            if (sl.value < sl.end){
                sl.value = sl.value+sl.step;
                sl.change.emit();
            }
            else{
                clearInterval(sh)
            }
        }
        var sh;
        sh = setInterval(update, 1000);

    */
    

""")
button = Button(label='► Play',  button_type="primary")
button.js_on_click(buttonclick)

Q1:Hello, in the simple code above, I get cb_obj.label undefined, not ‘► Play’ ? How can I change the label of the button in its ‘callback’ function?
Q2:By the way, In the reference of Button, I find js_on_change (event , *callbacks ) and js_on_click (handler ). What is the difference between callback and handler? Does the cb_obj in callback support accessing the property of itself but not in handler?

Hi @swpper ,

I tried your code, and found that I could see the label in both the developer console and the alert. I had to make some changes to make it runnable, but here’s what I used:


from bokeh.models import CustomJS, Button, Div, Slider
from bokeh.io import show

div = Div()
slider = Slider(start=0, end=10)
button = Button(label='► Play', button_type="primary")

buttonclick = CustomJS(args=dict(div=div, sl=slider, b1=button), code="""
    console.log(cb_obj.label)
    if (cb_obj.label == '► Play'){
        div.text = cb_obj.label;
        console.log(cb_obj.label)
        alert(cb_obj.label);
        cb_obj.label = '❚❚ Pause';
    }
    else{
        cb_obj.label = '► Play';
        console.log(cb_obj.label)
        div.text = cb_obj.label;
        alert(cb_obj.label);
    }
""")
button.js_on_click(buttonclick)
show(button)

If you’re continuing to get an error, you may want to provide a full runnable example, so that we can fully test and find the problem.

Hi, @carolyn Thanks for your reply. Your code is clean but the problem is still there. I add some details to make the problem clear:

from bokeh.models import CustomJS, Button, Div, Slider
from bokeh.io import show
from bokeh.layouts import column, row, layout

div = Div(text='', background='blue')
slider = Slider(start=0, end=10)
button = Button(label='► Play', button_type="primary")

buttonclick = CustomJS(args=dict(div=div, sl=slider, b1=button), code="""
    console.log('1: ' + cb_obj.label)
    if (cb_obj.label == '► Play'){
        div.text = cb_obj.label;
        console.log('c1: ' + cb_obj.label)
        alert('a1' + cb_obj.label);
        cb_obj.label = '❚❚ Pause';
    }
    else{
        cb_obj.label = '► Play';
        console.log('c2: ' + cb_obj.label)
        div.text = cb_obj.label;
        alert('a2: ' + cb_obj.label);
    }
""")
button.js_on_click(buttonclick)
show(layout([[div], [button]]))

What I get every time by my click in my browser(Edge) is 1: undefined, c2: ► Play in the console, and a2: ► Play is alerted.
So it seems that:
1, cb_obj.label can’t be correctly access in console.log()
2, the label can’t be changed with cb_obj

Hi @swpper

You access the button label via cb_obj.origin.label.

See this post for similar discussion.

But I get spirit from the User Guide of Button and Toggle:

button.js_on_click(CustomJS(code="console.log('button: click!', this.toString())"))

toggle.js_on_click(CustomJS(code="""
    console.log('toggle: active=' + this.active, this.toString())
"""))

I use this.origin.label instead of cb_obj.label and it works!

from bokeh.models import CustomJS, Button, Div, Slider
from bokeh.io import show
from bokeh.layouts import column, row, layout

div = Div(text='', background='blue')
slider = Slider(start=0, end=10)
button = Button(label='► Play', button_type="primary")

buttonclick = CustomJS(args=dict(div=div, sl=slider, b1=button), code="""
    console.log('1: ' + this.origin.label)
    if (this.origin.label == '► Play'){
        console.log('c1: ' + this.origin.label)
        alert('a1' + this.origin.label);
        this.origin.label = '❚❚ Pause';
        div.text = this.origin.label;
    }
    else{
        console.log('c2: ' + this.origin.label)
        alert('a2: ' + this.origin.label);
        this.origin.label = '► Play';
        div.text = this.origin.label;
    }
""")
button.js_on_click(buttonclick)
show(layout([[div], [button]]))
1 Like

@_jm Thank you!

1 Like