Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 61 additions & 6 deletions formulus-formplayer/src/HtmlLabelRenderer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { RankedTester, rankWith, uiTypeIs, UISchemaElement } from '@jsonforms/core';
import { withJsonFormsLabelProps } from '@jsonforms/react';
import { withJsonFormsLabelProps, useJsonForms } from '@jsonforms/react';
import { Typography, Box } from '@mui/material';

/**
Expand Down Expand Up @@ -31,29 +31,84 @@ const hasHtmlTags = (content: string): boolean => {
return htmlTagPattern.test(content);
};

/**
* Check if content contains handlebars template syntax
*/
const hasHandlebarsSyntax = (content: string): boolean => {
const handlebarsPattern = /\{\{data\.[\w]+\}\}/;
return handlebarsPattern.test(content);
};

/**
* Process handlebars template syntax in label text.
* Replaces {{data.fieldName}} with actual values from form data.
* Supports field names with alphanumeric characters and underscores.
*/
const processHandlebarsTemplate = (text: string, data: any): string => {
if (!text || !data) {
return text || '';
}

// Match handlebars syntax like {{data.fieldName}}
// Supports field names with letters, numbers, and underscores
const handlebarsPattern = /\{\{data\.([\w]+)\}\}/g;

return text.replace(handlebarsPattern, (match, fieldName) => {
// Get the value from data object
const value = data[fieldName];

// Handle different value types
if (value === null || value === undefined) {
return ''; // Return empty string for missing values
}

// Handle empty strings - return empty string
if (value === '') {
return '';
}

// Convert value to string
return String(value);
});
};

interface HtmlLabelProps {
text?: string;
visible?: boolean;
uischema?: UISchemaElement;
}

/**
* Custom Label renderer that supports HTML content.
* Custom Label renderer that supports HTML content and handlebars template syntax.
* Detects HTML tags in the label text and renders them safely.
* Processes handlebars template syntax like {{data.fieldName}} to replace with actual values.
*/
const HtmlLabelRenderer: React.FC<HtmlLabelProps> = ({ text, visible, uischema }) => {
const { core } = useJsonForms();
const formData = core?.data || {};

if (visible === false) {
return null;
}

if (!text) {
return null;
}

// Process handlebars template syntax first (before HTML processing)
let processedText = text;
if (hasHandlebarsSyntax(text)) {
processedText = processHandlebarsTemplate(text, formData);
}

// Check if HTML rendering is enabled via options or if content has HTML tags
const options = (uischema as any)?.options || {};
const htmlEnabled = options.html === true || options.format === 'html';
const contentHasHtml = hasHtmlTags(text || '');
const contentHasHtml = hasHtmlTags(processedText);
const shouldRenderHtml = htmlEnabled || contentHasHtml;

if (shouldRenderHtml && text) {
const sanitized = sanitizeHtml(text);
if (shouldRenderHtml && processedText) {
const sanitized = sanitizeHtml(processedText);
return (
<Box sx={{ mb: 2 }}>
<Typography
Expand Down Expand Up @@ -88,7 +143,7 @@ const HtmlLabelRenderer: React.FC<HtmlLabelProps> = ({ text, visible, uischema }
// Plain text rendering
return (
<Box sx={{ mb: 2 }}>
<Typography variant="body1">{text}</Typography>
<Typography variant="body1">{processedText}</Typography>
</Box>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"files": {
"main.css": "./static/css/main.ce996368.css",
"main.js": "./static/js/main.1f0e855c.js",
"main.js": "./static/js/main.72f3488a.js",
"index.html": "./index.html",
"main.ce996368.css.map": "./static/css/main.ce996368.css.map",
"main.1f0e855c.js.map": "./static/js/main.1f0e855c.js.map"
"main.72f3488a.js.map": "./static/js/main.72f3488a.js.map"
},
"entrypoints": [
"static/css/main.ce996368.css",
"static/js/main.1f0e855c.js"
"static/js/main.72f3488a.js"
]
}
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>React App</title><script src="./formulus-load.js"></script><script defer="defer" src="./static/js/main.1f0e855c.js"></script><link href="./static/css/main.ce996368.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>React App</title><script src="./formulus-load.js"></script><script defer="defer" src="./static/js/main.72f3488a.js"></script><link href="./static/css/main.ce996368.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Loading