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
BlogPostscollection, we want ourslugto be a kebab-case version of thetitlefield. We'll do this by writing aFieldHookthat runs onbeforeChangeof theslugfield and formats the incomingtitlefield.Here is a screenshot of the result after saving:
Beta Was this translation helpful? Give feedback.
All reactions