Skip to content

Instantly share code, notes, and snippets.

@feanor12
Created April 25, 2021 13:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save feanor12/54a20ac37ae4505f4b5d5dabf6ef0189 to your computer and use it in GitHub Desktop.
Save feanor12/54a20ac37ae4505f4b5d5dabf6ef0189 to your computer and use it in GitHub Desktop.
### A Pluto.jl notebook ###
# v0.14.2
using Markdown
using InteractiveUtils
# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
quote
local el = $(esc(element))
global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
el
end
end
# ╔═╡ 020915f4-167c-4501-8f4b-30449b5a672e
md"# Themed Number Field
This widget should show a number selector with a default value, a range, a width in pixel and a border color.
To define such a widget we save the properties in a custom struct:
"
# ╔═╡ 92b85e15-1d71-41d4-a704-1668a5614123
struct ThemedNumberField
value
range
width
color
end
# ╔═╡ d248fca0-38a2-4dbc-aa25-5c61b27c901e
md"To output the html code to Pluto the Base.show method is defined using the text/html mime.
Our code contains the input element wrapped in a div container to show how to use root elements which are not input.
To get this working we have to dispatch the CustomEvent to notify Pluto about an update.
To get the value fromhtml Pluto requests the value property from the root element. Therefore we have to define a function which sets the value property of the div element and call it once at generation trigger a change event. To also enable the change after creation we register setValue to be called on an input event from the number field.
"
# ╔═╡ 3199a4a0-f7fd-4469-a482-18e6cc79214d
function Base.show(io,::MIME"text/html",nf::ThemedNumberField)
print(io,"""<div>
<input type="number" value=$(nf.value)
min="$(first(nf.range))"
max="$(last(nf.range))"
style="border: 4px solid $(nf.color);
float: right;
width: $(nf.width)px"
</input>
<script>
const container = currentScript.parentElement
const input = container.querySelector("input");
function setValue() {
container.value = parseFloat(input.value);
container.dispatchEvent(new CustomEvent("input"));
}
setValue();
input.addEventListener("input", setValue);
</script>
</div>""")
end
# ╔═╡ 528d8c14-14b6-4f9e-8787-2a13d64be7f8
get(nf::ThemedNumberField) = nf.value
# ╔═╡ e5831576-6296-4277-aa34-a254839a9469
@bind number ThemedNumberField(4,3:6,300,"blue")
# ╔═╡ 16cce27a-e291-481f-85bb-6dc9e507e0a1
number
# ╔═╡ Cell order:
# ╟─020915f4-167c-4501-8f4b-30449b5a672e
# ╠═92b85e15-1d71-41d4-a704-1668a5614123
# ╟─d248fca0-38a2-4dbc-aa25-5c61b27c901e
# ╠═3199a4a0-f7fd-4469-a482-18e6cc79214d
# ╠═528d8c14-14b6-4f9e-8787-2a13d64be7f8
# ╠═e5831576-6296-4277-aa34-a254839a9469
# ╠═16cce27a-e291-481f-85bb-6dc9e507e0a1
@fonsp
Copy link

fonsp commented Apr 29, 2021

It should be an overload of Base.get, not just get at line 72

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment