-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Widget for dynamically adjustable vectors/arrays #303
Comments
Very cool! Can you write a bit more about the two bullet points at the end of your post, especially the first one? Can you share how you implemented this with |
In general, I think you would want to implement this yourself without |
Thanks for your quick reply!
Sure. I have uploaded a notebook with the current implementation here, that might be the easiest to see all the details: Here is a summary (disclaimer: I used Julia for a while now, but I'm relatively new to JavaScript and web development in general)
Regarding the current implementation, originally, I wanted to try this
Since I couldn't figure out how to run a Julia function from within JavaScript, I went for creating just one widget at the start and then just copying it when pressing "+". This worked well with text fields, but I couldn't figure out how to properly create new So my current solution for the whole widget is quite primitive: I supply a maximum number of list elements (I usually can estimate how many I will need at most ). All I have to do then is to hide/show the list elements when pressing the buttons – the extra elements are already there in the DOM, but will just be ignored. This is only a half-baked solution of course, but it would be enough for my current use case I think. The advantage is that I can generate proper widgets on the Julia side without having to worry about doing it later from within JS.
The current prototype is actually heavily inspired by the implementation of |
Questions I have going forward:
|
Hey @angerpointnerd, thanks for the detailed answer! I really like the solution of defining a maximum, and rendering all widgets from the start. Genius! An addition would be to set In fact, this means that you can probably use My idea: use before_transform = PlutoUI.combine() do Child
@htl """
<adjustable-vector>
<ul>
$(Child.(bonds))
</ul>
$(Child(ControllerWidget()))
</adjustable-vector>
"""
end
"""
Where ControllerWidget is the + - widget, which returns the number of elements selected. But it's also responsible for hiding/showing the vector bonds! And updating text.
Something like:
```html
@htl """
<adjustable-vector-controller>
<button class="button removeElementButton">–</button>
<button class="button addElementButton">+</button>
<script>
const controller = currentScript.closest("adjustable-vector-controller")
const widget = currentScript.closest("adjustable-vector")
const buttons = ...
let value = 1
buttons[1].addEventListener("click", () => {
value += 1
make_visible(0...value)
})
Object.defineProperty(controller, "value", {
get: () => value,
})
</script>
</adjustable-vector-controller>
""" Then with result = PlutoUI.Experimental.transformed_value(before_transform) do from_js
values = from_js[1:end-1]
num_elements = from_js[end]
values[1:num_elements]
end Hope this helps! Btw, the advantage of Alternatively, to continue more in the direction of your existing approach: We recently released this new feature: fonsp/Pluto.jl#2726. You could use this to get the HTML repr of a newly generated widget. You can't modify a const div = document.createElement("div")
div.innerHTML = "..."
some_element.append(div) Unfortunately, this won't run scripts included in the HTML. To get this, you could look into is the internals of Pluto's |
Btw I'm working on documentation! Take a look at https://plutojl.org/en/docs/advanced-widgets/ What do you think so far? What's missing? I would love a list of things-you-would-have-like-to-know-about when doing your research! There might be things that are not so obvious to me that need to be documented. (You are of course welcome to contribute if you like!) |
Thanks for your feedback @fonsp ! Creating the list of elements with What doesn't work yet, but would be nice to add is using the (I re-ran the cell multiple times by holding Shift+Return to make it "stuck" at the point before the error, just to demonstrate the issue) Screen.Recording.2024-04-23.at.10.56.59.movThe full error message is this: Details
The
Haven't had time to investigate more, but perhaps you have some idea? (Not really useful for me, but a
That looks great! I think I found many of the things mentioned there before, but spread across a few different notebooks and it just didn't occur to me how to properly combine the pieces. I'll see if I can contribute anything. |
Hi! 👋
In a project of mine, I sometimes need to input a list of identically-typed values where the number of values is variable (think of a list of chemical reactions to simulate for example). So far I couldn't find any type of "array widget" or "vector widget" here or in other related packages like PlutoExtras.jl, so I posted this issue.
Questions
I'll start with the main questions, details below:
Proposed Feature
VectorWidget
that takes a given widget/bond and creates a list of independent copies of that widget. It should allow for dynamically adjusting the number of elements and return aVector
containing the outputs of the individual widgets. Adjusting the number of elements should not reset the previous inputs (see below).Currently possible workarounds
So far I used a two-cell approach, where the first would define a
numberOfElements
for the vector input and the second cell contains acombine
widget which createsnumberOfElements
copies of a given widget. My main problems with this approach are that it doesn't compose well (not possible to nest this workaround inside acombine
widget) and that changing thenumberOfElements
will re-run the cell containing the array widget and reset its state.Example implementation
I hacked together a solution that (kind of) works for me and behaves like this:
demo_textfield_widget.mov
There are still some problems I couldn't figure out so far:
combine
works, which is mostly enough for me)VectorWidget
with other widgets inside acombine
doesn't work yetThe text was updated successfully, but these errors were encountered: