I have a small application that I’m writing using Pluto.jl. The general idea behind it is to display a list of sliders (dynamically generated) over a couple tabs that can be used to set the numbers for specific variables. Once the numbers have been selected, I would like to use a button to grab the values from the HTML/JavaScript and export it into Julia to use later. Since I have some experience with Vue/Vuetify, I decided to use that to generate the sliders and tabs. I have been able to get the sliders and tabs working in Pluto (it looks really great), but the issue that I’m running into is fetching the numbers from the sliders.
Here’s the Pluto code for what I’m doing:
begin
using JSON2
d1 = Dict("rates" =>[Dict([("slider", 1), ("max", 10), ("min",0), ("sname","rate1")]),
Dict([("slider", 1), ("max", 15), ("min",-1), ("sname","rate2")]),
],
"conc" =>[Dict([("slider", 1), ("max", 5), ("min",0), ("sname","c1")]),
Dict([("slider", 1), ("max", 8), ("min",-10), ("sname","c2")]),
Dict([("slider", 1), ("max", 8), ("min",-10), ("sname","c3")])
],
"tab" => "null",
)
djson1 = JSON2.write(d1)
test = HTML("""
<html>
<body>
<div id="app">
<form>
<v-app>
<v-main>
<template>
<v-card>
<v-tabs
v-model="tab"
background-color="transparent"
grow
>
<v-tab>
Rates
</v-tab>
<v-tab>
Concentrations
</v-tab>
</v-tabs>
<v-tabs-items v-model="tab">
<v-tab-item
>
<v-card flat>
<v-card-text>Adjust the reaction rates</v-card-text>
<v-slider
v-for = "s in rates"
v-model="s.slider"
:max="s.max"
:min="s.min"
:label = "s.sname"
>
<template v-slot:append>
<v-text-field
v-model="s.slider"
class="mt-0 pt-0"
hide-details
single-line
type="number"
style="width: 60px"
></v-text-field>
</template>
</v-slider>
</v-slider>
</v-card>
</v-tab-item>
<v-tab-item
>
<v-card flat>
<v-card-text>Adjust the Concentrations</v-card-text>
<v-slider
v-for = "s in conc"
v-model="s.slider"
:max="s.max"
:min="s.min"
step =".1"
:label = "s.sname"
>
<template v-slot:append>
<v-text-field
v-model="s.slider"
class="mt-0 pt-0"
hide-details
single-line
type="number"
style="width: 60px"
></v-text-field>
</template>
</v-slider>
</v-slider>
</v-card>
</v-tab-item>
</v-tabs-items>
</v-card>
</template>
<v-btn v-on:click="buttonClick">Update</v-btn>
</v-main>
</v-app>
</form>
</div>
<head>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
</head>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<script>
new Vue({
el: '#app',
vuetify: new Vuetify(),
data () {
return $djson1
},
methods: {
buttonClick: function(event) {
const form = currentScript.parentElement.querySelector('form')
console.log(form)
let rateArrVal = new Array()
let rateArrNames = new Array()
let concArrVal = new Array()
let concArrNames = new Array()
console.log(form)
let x = this.rates
let y = this.conc
for (let i=0; i<x.length;i++){
rateArrVal.push(x[i].slider)
rateArrNames.push(x[i].sname)
}
for (let i=0; i<y.length;i++){
concArrVal.push(y[i].slider)
concArrNames.push(y[i].sname)
}
form.value = rateArrVal
console.log(form.value)
form.dispatchEvent(new CustomEvent('input'))
}
}
})
</script>
</body>
</html>
""");
nothing
end
And in another cell, the code is bound using the bind macro.
@bind c test
Here’s what it looks like when running:
Ideally, the “Update” button at the bottom of the display will update the variable c, such that it grabs an array of values taken from the sliders. Currently, using the JS inside of the Vue instance I’m able to grab the values of the sliders and compile them into an array, but I’m not sure how to link up the Vue instance’s variables/functions with Pluto. Any idea on how to do this or what I’m doing wrong? Thanks in advanced.