Bind values from multiple HTML fields in Pluto

Hello,

I would like to organize a grid of number fields in a cell and assign each input to a different julia variable (or perhaps a dictionary). What is the best way to do that? I attached example code below.

Thank you!

Code
html"""
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Number Field Grid</title>
<style>
    .grid-container {
        display: grid;
        grid-template-columns: auto auto;
        grid-template-rows: auto auto auto;
        grid-gap: 10px;
    }
    .grid-item {
        display: flex;
        align-items: center;
    }
    label {
        margin-right: 10px;
    }
    input[type="number"] {
        width: 50px;
    }
</style>
</head>
<body>

<div class="grid-container">
    <div class="grid-item">
        <label for="field1">Field 1:</label>
        <input type="number" id="field1" name="field1" min="0" value="0">
    </div>
    <div class="grid-item">
        <label for="field2">Field 2:</label>
        <input type="number" id="field2" name="field2" min="0" value="0">
    </div>
    <div class="grid-item">
        <label for="field3">Field 3:</label>
        <input type="number" id="field3" name="field3" min="0" value="0">
    </div>
    <div class="grid-item">
        <label for="field4">Field 4:</label>
        <input type="number" id="field4" name="field4" min="0" value="0">
    </div>
    <div class="grid-item">
        <label for="field5">Field 5:</label>
        <input type="number" id="field5" name="field5" min="0" value="0">
    </div>
    <div class="grid-item">
        <label for="field6">Field 6:</label>
        <input type="number" id="field6" name="field6" min="0" value="0">
    </div>
</div>

</body>
</html>
"""

Have you seen the functionality available in the StructBondModule of PlutoExtras.jl or in the PlutoTables.jl package from @aplavin?

They do provide similar functionality to what you are interested in without going into the HTML javascript side.

If you really want to implement this with a custom HTML element like your grid container above you should look at this featured Pluto notebook for examples on how to start implementing something to achieve what you want

1 Like

Thank you. These are close to what I need. PlutoTables is not quite right, because I need labels for each cell, rather than labels for columns and rows. I did go through the Pluto interactivity examples before posting, but it was unclear how to bind values to the Julia variables. Do you happen to know if any of the packages you listed can create a grid similar to the image?

As you can see, I am stuck at the process of binding values to variables.

I don’t know about PlutoTables, you could hack your way into getting something similar with PlutoExtras with CSS, but for your use case it’s probably better (and more educating :D) to simply use the unexported PlutoUI.combine function.
You can check it’s docstring for more usage details but it’s quite nice for composing groups of inputs into a single Tuple output (or NamedTuple).

The synthax might be a bit strange if you are not quite used to the do synthax in julia but you can basically achieve what you want with the following code:

# ╔═╡ 00d2e3b5-7955-4c3a-a8d6-39ad8f04e7ab
begin
	using HypertextLiteral
	using PlutoUI
end

# ╔═╡ 6b8c5356-18ac-425d-b644-9ce8ead7e107
magic

# ╔═╡ 76155b37-b275-47e2-b0de-818d95528c16
@bind magic PlutoUI.combine() do Child
	# Create id and field label programmatically
	id_text(n) = ("field$n", "Field $n:")
	# We make a separate function to create the custom input as we can't nest @htl three times (we only have """ and " as string delimiters)
	function input_field(id)
		@htl("
		<input type='number' id='$id' name='$id' min='0' value='0'>
		")
	end
	# This is the actual output
	@htl("""
<div class="grid-container">
	$([	
	@htl("
	<div class='grid-item'>
		<label for='$id'>$text</label>
		$(Child(input_field(id)))
	</div>
	") for (id, text) in id_text.(1:6)
	])
</div>
<style>
    .grid-container {
        display: grid;
        grid-template-columns: auto auto;
        grid-template-rows: auto auto auto;
        grid-gap: 10px;
    }
    .grid-item {
        display: flex;
        align-items: center;
    }
    label {
        margin-right: 10px;
    }
    input[type="number"] {
        width: 50px;
    }
</style>
""")
end

1 Like

Thank you. This was very helpful.

1 Like