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
-
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