[#3191] added client-side validation and syntax highlight for the json field
This commit is contained in:
@@ -1,31 +1,80 @@
|
||||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import tooltip from "@/actions/tooltip";
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
import Field from "@/components/base/Field.svelte";
|
||||
|
||||
export let field;
|
||||
export let value = undefined;
|
||||
|
||||
let serialized = JSON.stringify(typeof value === "undefined" ? null : value, null, 2);
|
||||
let editorComponent;
|
||||
|
||||
let serialized = serialize(value);
|
||||
|
||||
$: if (value !== serialized?.trim()) {
|
||||
serialized = JSON.stringify(typeof value === "undefined" ? null : value, null, 2);
|
||||
serialized = serialize(value);
|
||||
value = serialized;
|
||||
}
|
||||
|
||||
$: isValid = isValidJson(serialized);
|
||||
|
||||
function serialize(val) {
|
||||
return JSON.stringify(typeof val === "undefined" ? null : val, null, 2);
|
||||
}
|
||||
|
||||
function isValidJson(val) {
|
||||
try {
|
||||
JSON.parse(val === "" ? null : val);
|
||||
return true;
|
||||
} catch (_) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
editorComponent = (await import("@/components/base/CodeEditor.svelte")).default;
|
||||
} catch (err) {
|
||||
console.warn(err);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<Field class="form-field {field.required ? 'required' : ''}" name={field.name} let:uniqueId>
|
||||
<label for={uniqueId}>
|
||||
<i class={CommonHelper.getFieldTypeIcon(field.type)} />
|
||||
<span class="txt">{field.name}</span>
|
||||
<span
|
||||
class="json-state"
|
||||
use:tooltip={{ position: "left", text: isValid ? "Valid JSON" : "Invalid JSON" }}
|
||||
>
|
||||
{#if isValid}
|
||||
<i class="ri-checkbox-circle-fill txt-success" />
|
||||
{:else}
|
||||
<i class="ri-error-warning-fill txt-danger" />
|
||||
{/if}
|
||||
</span>
|
||||
</label>
|
||||
<textarea
|
||||
id={uniqueId}
|
||||
class="txt-mono"
|
||||
required={field.required}
|
||||
value={serialized}
|
||||
on:input={(e) => {
|
||||
serialized = e.target.value;
|
||||
value = e.target.value.trim(); // trim the submitted value
|
||||
}}
|
||||
/>
|
||||
{#if editorComponent}
|
||||
<svelte:component
|
||||
this={editorComponent}
|
||||
id={uniqueId}
|
||||
maxHeight="500"
|
||||
language="json"
|
||||
value={serialized}
|
||||
on:change={(e) => {
|
||||
serialized = e.detail;
|
||||
value = serialized.trim(); // trim the submitted value
|
||||
}}
|
||||
/>
|
||||
{:else}
|
||||
<input type="text" class="txt-mono" value="Loading..." disabled />
|
||||
{/if}
|
||||
</Field>
|
||||
|
||||
<style>
|
||||
.json-state {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user