S
SolaraJohnowhitaker

Does anyone know how I might interact

Does anyone know how I might interact with anywidgets widgets in solara? I can make one:
class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)
class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)
Then since it uses traitlets I can set up an observer to do something when the value changes (including for e.g. updating a solara reactive variable to keep them in sync). BUT: to show the widget in a solara app I have to use counter = CounterWidget().element() but this makes it much harder to then figure out how to get the value (I'm not familiar with whatever magic .element does yet). This (traitlets etc) doesn't even feel like quite the right approach - perhaps someone more familiar with anywidgets can give a tip on the quickest way to have some shared state between custom javascript and solara?
Johnowhitaker
Johnowhitaker•22d ago
Ah I see one mistake I was making was using counter = CounterWidget().element() not counter = CounterWidget.element()
MaartenBreddels
MaartenBreddels•22d ago
CounterWidget.elements(value=r.value, on_value=r.set) where r is a reactive value. This should work. @alonsosilva you just wrote a blog post about this right?
Johnowhitaker
Johnowhitaker•22d ago
text_1 = solara.reactive("This is a global reactive variable")
count = solara.reactive(0)

class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)

def __init__(self):
super().__init__()
self.value = count.value

@traitlets.observe("value")
def _on_value_change(self, change):
count.set(int(change["new"]))

@solara.component
def Page():
counter = CounterWidget.element()
solara.Markdown(f"### Counter Widget count: {count.value}")
solara.Button("Reset counter", on_click=lambda: count.set(0))
text_1 = solara.reactive("This is a global reactive variable")
count = solara.reactive(0)

class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)

def __init__(self):
super().__init__()
self.value = count.value

@traitlets.observe("value")
def _on_value_change(self, change):
count.set(int(change["new"]))

@solara.component
def Page():
counter = CounterWidget.element()
solara.Markdown(f"### Counter Widget count: {count.value}")
solara.Button("Reset counter", on_click=lambda: count.set(0))
This is what I had which sort of worked (ckicking the custom widget updated the markdown, but resetting the reactive variable count didn't reset the custom widget. Just seen your message, will try Yes that works
import solara
import anywidget
import traitlets

class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)

@solara.component
def Page():
count = solara.use_reactive(0)
counter = CounterWidget.element(value=count.value, on_value=count.set)
solara.Markdown(f"### Counter Widget count: {count.value}")
solara.Button("Reset counter", on_click=lambda: count.set(0))
import solara
import anywidget
import traitlets

class CounterWidget(anywidget.AnyWidget):
# Widget front-end JavaScript code
_esm = """
function render({ model, el }) {
let button = document.createElement("button");
button.innerHTML = `count is ${model.get("value")}`;
button.addEventListener("click", () => {
model.set("value", model.get("value") + 1);
model.save_changes();
});
model.on("change:value", () => {
button.innerHTML = `count is ${model.get("value")}`;
});
el.appendChild(button);
}
export default { render };
"""
# Stateful property that can be accessed by JavaScript & Python
value = traitlets.Int(0).tag(sync=True)

@solara.component
def Page():
count = solara.use_reactive(0)
counter = CounterWidget.element(value=count.value, on_value=count.set)
solara.Markdown(f"### Counter Widget count: {count.value}")
solara.Button("Reset counter", on_click=lambda: count.set(0))
^^ If anyone wants the solution Many thanks @MaartenBreddels
alonsosilva
alonsosilva•22d ago
Yes, and I did that mistake as well! After this discussion, I have updated the blog post by adding how to access the anywidget counter https://alonsosilvaallende.github.io/blog/posts/2024-04-23-Build_a_basic_widget_with_AnyWidget.html
Johnowhitaker
Johnowhitaker•21d ago
Fantastic post, came for the content stayed for the satisfying confetti 😄
Want results from more Discord servers?
Add your server
More Posts
Common object across pagesI was wondering, what is a good way to share a common object across multiple pages, organized in sepInitializing function.Please help me make an initializing function. I'm using the solara.use_router().search function to installation problem, outdated version solara-uipoetry add solara Using version ^1.32.0 for solara Updating dependencies Resolving dependencies... Server routeI need to somehow change the state depending on the behavior of the external service, I think I needipyaggrid memory leakHi, I have an app that uses a few sizeable `ipyaggrid` grids (one per tab) that are leading to memorExtract the value from an ipywidgetHi all! I want to extract the value from an ipywidget but the values between the Solara app and the Hi, can you tell me where to dig to addHi, can you tell me where to dig to add supabase auth?Quarto Solara compatibilityI'm writing a tutorial to build LLM chat apps with Solara: https://alonsosilvaallende.github.io/blogPermissionError for nbextensions on startup with v1.29+hi all, i've been trying out solara for the past month or so. i was using v1.28 with no issues. todaImage SelectHi all. Can you help me. I'm trying to make an image selector, like the one made here by https://gitRemove the "Powered by Solara" Tag for production deployment?Hey all! Knew to Solara and loving the package so far! I'm curious if it is possible to remove the Google Analytics?Hello. Has anyone figured out how to inject a google analytics tag into the html <head>? Is this eveHelp with running solaraHello! I am new to solara. I started using solara a couple weeks ago and it was running fine. I use Citing solaraHello! This may be a bit of an odd request, but I'm interested in citing solara. Some popular pythonEmbedding Solara / iframe / parameterI would like to integrate Solara to the exiting application using iframe with passing arguments. Full Screen OutputI am getting an error whenever I click on the full screen button and it also occurs in the documentaSetting height of `ipyaggrid` in Solara app gives errorHi, how can I set the `height` of a `ipyaggrid` that is being cross-filtered by a `solara` componStreaming partial extractionI want to replicate this streaming partial extraction: https://x.com/jxnlco/status/17557231722283500OAuth example failshttps://solara.dev/documentation/examples/general/login_oauth clicking the button results in an errSwitching Tabs resets a state when lazy loading is set to TrueI want to keep local state of components when switching Tabs but also I need lazy=True since I don't