Replies: 2 comments 2 replies
-
How do we listen to a change event on the title and create the slug, live, just like the title of the collection is being rendered as we type? Any idea? |
Beta Was this translation helpful? Give feedback.
1 reply
-
These examples are out dated. Here's my current working solution. Also allows you to specify the tracking field to make it reusable and universal: import React from "react";
import { Field } from "payload/types";
import { merge } from "lodash";
import SlugInput from "../ui/SlugInput";
type Slug = (
options?: { trackingField?: string },
overrides?: Partial<Field>
) => Field;
export const slug: Slug = ({ trackingField = "title" } = {}, overrides) =>
merge<Field, Partial<Field> | undefined>(
{
name: "slug",
unique: true,
type: "text",
admin: {
position: "sidebar",
components: {
Field: (props) => (
<SlugInput trackingField={trackingField} {...props} />
),
},
},
},
overrides
); import React, { useEffect, useRef } from "react";
import { kebabCase } from "lodash";
import { TextInput, useFieldType } from "payload/components/forms";
export interface SlugInputProps {
trackingField: string;
}
export default function SlugInput(props: SlugInputProps) {
const { trackingField } = props;
const { value: slugValue = "", setValue: setSlugValue } =
useFieldType<string>({
path: "slug",
});
const { value: trackingFieldValue } = useFieldType<string>({
path: trackingField,
});
const prevTrackingFieldValueRef = useRef(trackingFieldValue);
const stopTrackingRef = useRef(false);
useEffect(() => {
console.log(trackingFieldValue);
if (!trackingField || stopTrackingRef.current) {
return;
}
if (trackingFieldValue === prevTrackingFieldValueRef.current) {
return;
}
const prevSlugValue = kebabCase(prevTrackingFieldValueRef.current);
prevTrackingFieldValueRef.current = trackingFieldValue;
if (prevSlugValue !== slugValue) {
return;
}
setSlugValue(kebabCase(trackingFieldValue));
}, [trackingFieldValue]);
return (
<div>
<TextInput
name="slug"
path="slug"
label="Slug"
description={
slugValue
? `Auto generated based on ${trackingField}`
: `Will be auto-generated from ${trackingField} when saved`
}
value={slugValue}
onChange={(e) => {
setSlugValue(e.target.value);
stopTrackingRef.current = true;
}}
/>
</div>
);
} |
Beta Was this translation helpful? Give feedback.
1 reply
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
This is a common question, so I thought I'd write up a quick example.
In this
BlogPosts
collection, we want ourslug
to be a kebab-case version of thetitle
field. We'll do this by writing aFieldHook
that runs onbeforeChange
of theslug
field and formats the incomingtitle
field.Here is a screenshot of the result after saving:
Beta Was this translation helpful? Give feedback.
All reactions