Custom Views
Overview
Custom views allow you to create custom pages in the frontend of your application.
They can be embedded into form views or used to build specialized UI.
Steps to Create a Custom Page in a Form View
-
Create the custom view component
Place it inside your extensions folder:
solid-ui/app/admin/extensions/BookSimilarTitles.tsx -
Register the custom view
Register it insolid-ui/app/admin/extensions/index.tsusingregisterExtensionComponent.
Code: Registering the Component
registerExtensionComponent("BookSimilarTitles", BookSimilarTitles);
- Add the custom view to the form layout
You can embed the custom widget in your form JSON layout.
Code: Form Layout Example
{
"name": "book-form-view",
"type": "form",
"layout": {
"type": "form",
"attrs": {
"name": "form-1",
"label": "Book"
},
"children": [
{
"type": "sheet",
"attrs": { "name": "sheet-1" },
"children": [
{
"type": "notebook",
"attrs": { "name": "notebook-1" },
"children": [
{
"type": "page",
"attrs": { "name": "page-1", "label": "General Info" },
"children": [
{
"type": "row",
"attrs": { "name": "page-1-row-1" },
"children": [ ... ]
}
]
},
{
"type": "page",
"attrs": { "name": "page-5", "label": "Similar Titles", "visible": true },
"children": [
{
"type": "custom",
"attrs": {
"name": "page-5-custom-1",
"widget": "BookSimilarTitles"
}
}
]
}
]
}
]
}
]
}
}
Example: BookSimilarTitles Component
Code: BookSimilarTitles.tsx
"use client";
import Image from "next/image";
import { useEffect, useState } from "react";
import { SolidFormWidgetProps } from '@solidxai/core-ui';
const BookSimilarTitles = ({ formData, field, fieldsMetadata, viewMetadata }: SolidFormWidgetProps) => {
const [books, setBooks] = useState<any[]>([]);
useEffect(() => {
const myHeaders = new Headers();
myHeaders.append("Authorization", "[PASSWORD]");
const requestOptions = { method: "GET", headers: myHeaders };
async function fetchBookData() {
try {
const title = formData['title'];
console.log(`Fetching similar titles for ${title}`);
const endpoint = `https://www.googleapis.com/books/v1/volumes?q=${title}&maxResults=40`;
const response = await fetch(encodeURI(endpoint), requestOptions);
const result = await response.json();
console.log(`Loaded similar titles from Google Books API`, result);
setBooks(result.items);
} catch (error) {
console.error(error);
}
}
fetchBookData();
}, []);
return (
<div className="flex justify-center">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-12 gap-4" style={{ minWidth: "30vw" }}>
{books.map((book, index) => (
<div key={index} className="h-32 relative" style={{ width: "100px", height: "100px" }}>
<a target="_blank" href={book.volumeInfo.infoLink}>
<Image
src={book.volumeInfo.imageLinks?.thumbnail}
alt={`Book description: ${book.volumeInfo.description}`}
layout="fill"
objectFit="cover"
className="rounded"
unoptimized={true}
/>
</a>
</div>
))}
</div>
</div>
);
};
export default BookSimilarTitles;
How It Works
- SolidX loads the custom view component when the form is rendered.
- The custom view is injected into the form layout at the specified location.
- The custom view receives props of type
SolidFormWidgetProps.
Code: Props Types
export type SolidFormWidgetProps = {
field: any;
formData: Record<string, any>; // Comes from Formik
viewMetadata: SolidView;
fieldsMetadata: FieldsMetadata;
formViewData: any;
};
export type SolidView = CommonEntity & {
name: string;
displayName: string;
type: string;
context: string;
layout: LayoutNode;
model: Model;
module: Module;
};
export type FieldMetadata = CommonEntity & {
id: number;
name: string;
displayName: string;
[key: string]: any; // Flexible for extra key-value pairs
};
- The custom view can render any UI components and access:
- Form data
- Field metadata
- View metadata
- Other properties
With this approach, you can extend SolidX forms with powerful custom views.