It is also possible to combine your custom input element with traditional dynamics. For instance you want to create multiple input fields, which are synchronised with each other or using some equation.
You need a WLJS Function with update
methods defined. One can generate those on-fly for each input element within a WLX script
.wlx
CustomInput[sym_, OptionsPattern[]] := Module[{
Label = OptionValue["Label"],
Ev = OptionValue["Event"],
Pattern = OptionValue["Pattern"],
Handler
},
With[{Template =
<div class="mt-2 flex">
<div style="width: 7rem" class="flex shrink-0 items-center rounded-l-md bg-white px-3 text-base text-gray-500 outline outline-1 -outline-offset-1 outline-gray-300 sm:text-sm/6"><Label/></div>
<input type="number" step="1" class="-ml-px block w-full grow rounded-r-md bg-white px-3 py-1.5 text-base text-gray-900 outline outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600 sm:text-sm/6" placeholder="0.0"/>
<script type="module">
core['<Handler/>'] = async (args, env) => {
const input = env.element.getElementsByTagName('input')[0];
const data = await interpretate(args[0], env);
input.value = +data.toFixed(4);
env.local.input = input;
input.addEventListener('change', () => {
console.warn(input.value);
env.local.skip = true;
server.kernel.emitt('<Ev/>', input.value, '<Pattern/>');
});
}
core['<Handler/>'].update = async (args, env) => {
if (env.local.skip) {
env.local.skip = false;
return;
}
console.log('Update');
env.local.input.value = +(await interpretate(args[0], env)).toFixed(4);
}
core['<Handler/>'].destroy = () => {
delete core['<Handler/>'];
}
core['<Handler/>'].virtual = true;
</script>
</div>
},
HTMLView[Template, Epilog->(Handler[sym])]
]
]
Options[CustomInput] = {"Label"->"", "Event"->"", "Pattern"->"Default"};
what happens here:
- we define a template for our custom input field
- we define a support script with a generated
Handler
function, which reads and updates this input field - we pack in into
HTMLView
, which calls ourHandler
on a provided argument after this component has been mounted
Let's see it in action