Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2092c71
feat: add custom validation functionality for resource columns[1]
yaroslav8765 Mar 18, 2026
e36cdf0
feat: add mutex dependancy
yaroslav8765 Mar 18, 2026
e7affbd
feat: add custom validation functionality for resource columns[2]
yaroslav8765 Mar 18, 2026
6073982
feat: add custom validation functionality for resource columns[3]
yaroslav8765 Mar 18, 2026
0fc29a2
feat: add custom validation functionality for resource columns[4]
yaroslav8765 Mar 19, 2026
3ff0b72
fix: validate columns with custom validator in parallel
yaroslav8765 Mar 19, 2026
a9f259c
add spinner to the save button for the create/edit view
yaroslav8765 Mar 19, 2026
a8c1372
refactor: simplify spinner visibility logic in ColumnValueInputWrapper
yaroslav8765 Mar 19, 2026
bf3ea7b
refactor: clean up unused imports and move required column logic in s…
yaroslav8765 Mar 19, 2026
14bdf25
refactor: enhance validation logic by introducing block setting for c…
yaroslav8765 Mar 19, 2026
b3f0944
docs: add docs for the backend validation function
yaroslav8765 Mar 19, 2026
8c9b779
fix: move field loader spinner next to error message
yaroslav8765 Mar 19, 2026
3c2dc8b
style: change styling of the list view
yaroslav8765 Mar 19, 2026
65d835d
chore: update readme to use pnpm
yaroslav8765 Mar 23, 2026
dbefa20
chore: update readme to use pnpm[2]
yaroslav8765 Mar 23, 2026
bca7178
Merge pull request #522 from devforth/next
SerVitasik Mar 25, 2026
341bcd8
fix: add missing repository name to the adminforth package
yaroslav8765 Mar 26, 2026
c90ec77
fix: get rid of "vue-slider-component" package and use new custom ran…
yaroslav8765 Mar 30, 2026
dfba81d
fix: use latest version of handlebars to prevent AST Type Confusion i…
yaroslav8765 Mar 30, 2026
cc595f0
fix: add ts type-check in spa folder to the release scripts
yaroslav8765 Mar 30, 2026
e402983
fix: fix ts errors in showView
yaroslav8765 Mar 30, 2026
6b1dd66
fix: update release script to use pnpx vue-tsc, instead of local vue-…
yaroslav8765 Mar 30, 2026
233e377
Merge branch 'next' of github.com:devforth/adminforth into feature/Ad…
yaroslav8765 Mar 30, 2026
e3c7522
Merge branch 'next' of github.com:devforth/adminforth into feature/Ad…
kulikp1 Mar 30, 2026
42d89bd
chore: fix resolve version conflicts for docusaurus
yaroslav8765 Mar 30, 2026
6b18bf4
chore: fix resolve version conflicts for docusaurus
yaroslav8765 Mar 30, 2026
abf874b
docs: add documentation for isInternalUrl method
kulikp1 Mar 30, 2026
9bf2329
feat: update style of create/edit/list/show views
yaroslav8765 Mar 30, 2026
c7a1986
Merge pull request #527 from devforth/feature/AdminForth/1334/lets-tr…
yaroslav8765 Mar 30, 2026
570ecb8
fix: update adminforth package version to 2.26.0-next.36
yaroslav8765 Mar 30, 2026
84830fa
Merge branch 'main' of github.com:devforth/adminforth into next
yaroslav8765 Mar 30, 2026
42a4b0d
Merge branch 'next' of github.com:devforth/adminforth into feature/Ad…
yaroslav8765 Mar 30, 2026
b416aa3
chore: fix typo in docs
yaroslav8765 Mar 30, 2026
3408b4c
fix: update regex validation handling and make properties optional in…
yaroslav8765 Mar 30, 2026
0d9641c
fix: add @types/lodash.debounce and update lodash types in package.js…
yaroslav8765 Mar 30, 2026
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
Original file line number Diff line number Diff line change
Expand Up @@ -677,34 +677,6 @@ export default {
> `minValue` and `maxValue` checks are enforced both on frontend and backend.


### Validation

In cases when column values must follow certain format, you can add `validation` to it.
`validation` is an array of rules, each containing `regExp` that defines a format for a value and `message` that will be displayed in case when entered value does not pass the check.

```typescript title="./resources/adminuser.ts"
export default {
name: 'adminuser',
columns: [
...
{
name: 'email',
required: true,
isUnique: true,
validation: [
{
regExp: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
message: 'Email is not valid, must be in format example@test.com',
},
],
},
],
},
...
],
```

> `validation` checks are enforced both on frontend and backend.

### Input prefix and suffix

Expand Down Expand Up @@ -967,6 +939,81 @@ When defined like this, adminforth will use value in `property_type` to figure o

If `beforeDatasourceRequest` or `afterDatasourceResponse` hooks are set for polymorphic foreign resource, they will be called for each resource in `polymorphicResources` array.

## Validation (create/edit view)
In cases when column values must follow certain format, you can add `validation` to it.
`validation` is an array of rules, each containing `regExp` or `validator function` that defines a format for a value and `message` that will be displayed in case when entered value does not pass the check.

### Frontend validation
We recommend to use this validation with regExp, because it validates fields in real time

```typescript title="./resources/adminuser.ts"
export default {
name: 'adminuser',
columns: [
...
{
name: 'email',
required: true,
isUnique: true,
//diff-add
validation: [
//diff-add
{
//diff-add
regExp: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$',
//diff-add
message: 'Email is not valid, must be in format example@test.com',
//diff-add
},
//diff-add
],
},
],
},
...
],
```

### Backend validation
There might be rare cases, when you want to have your own validation function. For this you can use `validator` callback:
```typescript title="./resources/adminuser.ts"
export default {
name: 'adminuser',
columns: [
...
{
name: 'email',
required: true,
isUnique: true,
//diff-add
validation: [
//diff-add
{
//diff-add
async validator(value: any, record: any) {
//diff-add
if (value.endsWith("@example.com")) {
//diff-add
return { isValid: false, message: 'Your email can`t end with `@example.com`' };
//diff-add
}
//diff-add
return { isValid: true }
//diff-add
}
//diff-add
}
//diff-add
],
},
],
},
...
],
```

>Avoid using a custom validator because every time you change a field (after a failed first save attempt), it will make an API call.

## Filtering

### Filter Options
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -405,4 +405,30 @@ app.post(

> ⚠️ Do not call `commitUrlToUpdateExistingRecord` or `commitUrlToNewRecord` from the same resource’s `beforeSave`/`afterSave` hooks, as it would create an infinite loop of updates/creates. These methods are intended to be called from your own API endpoints after the browser upload finishes.

## Handling Internal vs. External Links (isInternalUrl)

Have you ever encountered a situation where a user pastes a beautiful image directly from Google Images into the Markdown editor, but your system tries to save it as if it were a file from your own S3 bucket? Previously, this could lead to "broken" paths and corrupted data in your database.

### You can easily use this method in your code:
Imagine you are building a custom preview page or a specialized plugin, and you need to know: Is this file something we manage in our storage, or is it just a link to an external resource?

```ts title="./index.ts"
// Get the upload plugin instance
const uploadPlugin = admin.getPluginById('my_s3_storage');

const urlFromEditor = "https://my-bucket.s3.eu-central-1.amazonaws.com/apartments/flat.png";
const externalUrl = "https://images.unsplash.com/photo-1503376780353-7e6692767b70";

// Check the first link
if (await uploadPlugin.isInternalUrl(urlFromEditor)) {
console.log("✅ This is our file. We can extract the path and manage it in S3.");
const path = uploadPlugin.getPathFromUrl(urlFromEditor);
// Result: "capartmentsars/flat.png"
}

// Check the second link
if (!(await uploadPlugin.isInternalUrl(externalUrl))) {
console.log("🌐 This is an external link.");
}
```

Loading