be-reformable is a web component that progressively enhances the built-in form element. It uses be-decorated as the underpinning approach, as opposed to the controversial "is" extension.
Size of package, including custom element behavior framework (be-decorated):
Size of new code in this package:
Let's see how we can use be-reformable, to work with the newton advanced math micro service, declaratively.
<link id=newton-microservice rel=preconnect href=https://newton.now.sh/ >
<form be-reformable='{
"base-link": "newton-microservice",
"path": ["api/v2/", "operation", "/", "expression"],
"autoSubmit": true,
}'
target="json-viewer[-object]"
>
<label for=operation>Operation:</label>
<input id=operation value=integrate>
<label for=expression>Expression:</label>
<input id=expression value="x^2">
</form>
<json-viewer -object></json-viewer>
<noscript>
<iframe name="json-viewer[-object]"></iframe>
</noscript>
If target isn't found, or isn't specified, the form will apply the underlying submit mechanism.
The "path" value is an "interpolation from a distance" expression -- it alternates between hardcoded strings, and names of input elements it expects to find in oForm.elements.
be-reformable examines the content-type header of the response, and parses to json when "json" is found in that string.
"base-link" is optional, but allows for easy management of common base API URL's across the application. The link tag should probably go in the head tag of index.html (typically).
Another optional parameter not shown above is "init" which allows for binding to an object that specifies the second parameter (init / reqInit) of the fetch request. To hardcode this parameter, use initVal.
Sometimes it is useful to allow form elements to "add themselves" to the path, just as form elements can add themselves to the query string. This allows for dynamic form elements to be added.
<link id=newton-microservice rel=preconnect href=https://newton.now.sh/ >
<form be-reformable='{
"base-link": "newton-microservice",
"path": true,
"autoSubmit": true,
}'
target="json-viewer[-object]"
>
<label for=operation>Operation:</label>
<input data-path-idx=0 data-path-lhs="api/v2/" id=operation value=integrate>
<label for=expression>Expression:</label>
<input data-path-idx=1 data-path-lhs="/" id=expression value="x^2">
</form>
<json-viewer -object></json-viewer>
<noscript>
<iframe name="json-viewer[-object]"></iframe>
</noscript>
The following markup scores 100% from Lighthouse:
<form>
<label for='url'>URL:</label>
<input id='url' type='url' required>
</form>
<template be-switched='{
"if": {
"observe": "form",
"on": "input",
"vft": "querySelector|input.checkValidity|"
}
}'>
<form be-reformable='{
"autoSubmit": true,
"url": {
"observe": "form",
"on": "input",
"vft": "querySelector|input.value"
},
"as": "json"
}'
target='xtal-editor[-input-obj]'></form>
<xtal-editor -input-obj></xtal-editor>
<script type='module' crossorigin='anonymous'>
import 'https://esm.run/xtal-editor@0.0.162';
import 'https://esm.run/be-reformable@0.0.39';
</script>
</template>
<script type=module crossorigin='anonymous'>
import 'https://esm.run/be-switched@0.0.68';
</script>
What this does:
- Until a url is entered, the only JS loaded is for be-switched. Be-switched enables the template to not load until the input is valid.
- Once the input is valid, the template is instantiated, and the be-reformable library is loaded. The form auto submits the url entered by the user.
- The result of the fetch is parsed as JSON, and the JSON is passed to the xtal-editor component.
<form
class='main-form'
action="https://o2h-cw.bahrus.workers.dev/"
target="[-innerHTML]"
be-reformable='{
"autoSubmit": false,
"path": ["", "proxy-to"],
"transform": {
"input": [{},{},{"a": ["b"]}]
}
}'
be-valued
>
<label>
<span>Proxy to:</span>
<input autofocus be-focused required name='proxy-to' type='url'>
</label>
<label>
<span>Output config:</span>
<input name="x38d47cd9-8a95-4037-9e71-d63f6416a6d5" value="https://unpkg.com/o2h-cw/src/o2hConfig.json">
</label>
<label be-typed='{
"beReformable": true
}' be-clonable be-delible><span>[Set name of first parameter]</span></label>
<button type='submit'>Submit</button>
</form>
<div -innerHTML></div>
<form
action="a.html"
target="[-innerHTML]"
method="post" be-reformable='{
"bodyName": "my-body",
"headers": true
}'>
<input type='hidden' data-header-name='Content-Type' value='application/json'>
<label>
JSON:
<textarea name='my-body'>{"hello": "world"}</textarea>
</label>
<button type='submit'>submit</button>
</form>
<div -innerHTML>
</div>
First do xslt, then DTR transform.
[TODO] Example
<form be-reformable='{
"filterOutDefaultValues": true,
}'>
<input data-optional=true name=prop1 value=defaultValue1>
<input name=prop2 value=differentValue>
</form>
If prop1 isn't modified from the original value, the parameter is not sent.
<form be-reformable='{
"headers": true,
}'>
<input data-header-name=header1>
<input data-header-name=header2>
</form>
The attribute be-reformable can be replaced with data-be-reformable.
A web-friendly VSCode plug-in is available to make editing json-in-html more pleasant.
The following import map is needed for non-bundling environments:
<script type=importmap>
{
"imports": {
"trans-render/": "../node_modules/trans-render/",
"xtal-element/": "../node_modules/xtal-element/",
"be-decorated/": "../node_modules/be-decorated/",
"be-observant/": "../node_modules/be-observant/",
"be-hive/": "../node_modules/be-hive/"
}
}
</script>
To view this element locally:
- Install git, npm
- Clone or fork this git repo.
- Open a terminal from the folder created in step 2.
- Run npm install
- Run npm run serve
- Open http://localhost:3030/demo/dev
import 'be-reformable/be-reformable.js';
<script type=module crossorigin=anonymous>
import 'https://esm.run/be-reformable';
</script>