-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Inputs
Inputs objects are used to edit component properties
For example TextInput extends Input object and is defined as
let TextInput = { ...Input, ...{
//what events should be listened for changes and on what inputs
events: [
//event, listener, child element
["focusout", "onChange", "input"],
],
//the event listener
onChange: function(event, node, input) {
if (event && event.target) {
//triger the propertyChange event for the editor to update the element
const e = new CustomEvent('propertyChange', { detail: {value : input.value ?? this.value, input: this, origEvent:event} });
event.currentTarget.dispatchEvent(e);
}
},
//the editor will call this method to set the initial value loadad from the element
setValue: function(value) {
this.element[0].querySelector('input').value = value;
},
//this method creates the input elements, the render method uses the template inside editor.html, for this input is `<script id="vvveb-input-textinput"><input type="text"></script>`
init: function(data) {
return this.render("textinput", data);
},
}
);
Inputs also require a template that is defined as a <script>
tag in the editor html (inside editor.html) with the id vvveb-input-inputname
for example for text input is vvveb-input-textinput
and is defined as
<script id="vvveb-input-textinput" type="text/html">
<div>
<input name="{%=key%}" type="text" class="form-control"/>
</div>
</script>
{%=key%} is used to set the unique input name defined as "key" in component properties, if additional data is provided then these must be set in the template, for example ToggleInput needs on and off
<script id="vvveb-input-toggle" type="text/html">
<div class="toggle">
<input type="checkbox" name="{%=key%}" value="{%=on%}" data-value-off="{%=off%}" data-value-on="{%=on%}" class="toggle-checkbox" id="{%=key%}">
...
Usually Input objects define the following keys
- events - This provides a collection of definitions for functions to be called on certain events, the format is ["event_name","input_object_method_to_be_called", "css_selector_for_element_in_template"] For example text input monitors keyup event for input element in the template, while select input monitors onchange event for select element in template, by default they both call onChange function on parent Input object.
let TextInput = { ...Input, ...{
events: {
//event, listener, child element
["keyup", "onChange", "input"],
},
...
let SelectInput = { ...Input, ...{
events: {
//event, listener, child element
["change", "onChange", "select"],
},
...
Sometimes you need to read another attribute than value from the input such as checked for checkbox in this case you need to override onChange method to use checked attribute.
let CheckboxInput = { ...Input, ...{
//override onChange
onChange: function(event, node) {
if (event.data && event.data.element){
const e = new CustomEvent('propertyChange', { detail: {value : this.checked, input: this, origEvent:event} });
event.currentTarget.dispatchEvent(e);
}
},
//or define a new method for the listener and call onChange from it
events: [
["change", "onToggleChange", "input"],
],
onToggleChange: function(event, node, input) {
input.value = this.checked ? this.getAttribute("data-value-on") : this.getAttribute("data-value-off");
return input.onChange.call(this, event, node, input);
},
- setValue - This method is called automatically by Vvveb.Builder when setting the value for the input.
- init - This method is called when the input is initialized, the return value is used as html to render the input, by default the parent Input.render() is called with the template name and additional data as parameters.
All input object extends Input object that handles template loading and processing and also provides a default onChange function that automatically processes events using value attribute.
let Input = {
init: function(name) {
},
onChange: function(event, node, input) {
if (event && event.target) {
const e = new CustomEvent('propertyChange', { detail: {value : input.value ?? this.value, input: this, origEvent:event} });
event.currentTarget.dispatchEvent(e);
}
},
renderTemplate: function(name, data) {
return tmpl("vvveb-input-" + name, data);
},
setValue: function(value) {
if (this.element[0] && value) {
let input = this.element[0].querySelector('input');
if (input) {
input.value = value;
}
}
},
render: function(name, data) {
}
};
You can check editor.html for input templates and inputs.js for inputs code.