Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RichTextEditor value and onChange props #1236

Closed
vitalbone opened this issue Sep 14, 2022 · 12 comments · Fixed by #1740
Closed

RichTextEditor value and onChange props #1236

vitalbone opened this issue Sep 14, 2022 · 12 comments · Fixed by #1740

Comments

@vitalbone
Copy link

vitalbone commented Sep 14, 2022

Hi, I've been trying to understand if it's possible to add an initial value and change the value of the RichTextEditor field.

There doesn't seem to be any documentation so I'm not sure how it's supposed to function. Pardon my naiveté but I was hoping it would be as simple as the following however this doesn't work.

const INITIAL_DOCUMENT = {
  nodeType: BLOCKS.DOCUMENT,
  data: {},
  content: [
    {
      nodeType: BLOCKS.PARAGRAPH,
      data: {},
      content: [
        {
          nodeType: 'text',
          value: 'Initial value',
          marks: [],
          data: {},
        },
      ],
    },
  ],
}

const Field = () => {
  const sdk = useSDK<FieldExtensionSDK>()
  const [value, setValue] = React.useState(INITIAL_DOCUMENT)
  
  useAutoResizer()

  function handleTextChange(doc: any) {
    doc.content[0].content[0].value = 'Updated value'
    setValue(doc)
  }

  return (
    <RichTextEditor
      sdk={sdk}
      isInitiallyDisabled={false}
      value={value}
      onChange={handleTextChange}
    />
  )
}

export default Field

Could you please provide an example of the correct way to add an initial value in the text in the editor, as well as the mechanism to update the text in the editor. Thank you.

@github-actions
Copy link

Marking issue as stale since there was no activity for 30 days

@github-actions github-actions bot added the stale Used to mark when there was no activity for a set period of time label Oct 15, 2022
@JoelWakefield
Copy link

I've also been looking into this - I wanted to add a character counter below to allow my team to keep track of character count without being strictly limited by a max or min.

It's not a big feature, but it's a small quality of life improvement that would allow them to avoid jumping from character-counting tool to contentful.

@JoelWakefield
Copy link

JoelWakefield commented Dec 29, 2022

@vitalbone, I found something which I hope is helpful - at least concerning the onChange prop; I don't know about setting initial values.

While I couldn't get the RichTextEditor's onChange function to fire, there is a ConnectedRichTextEditor exported from '@contentful/field-editor-rich-text' as well - it also uses the same props (minus the isInitiallyDisabled prop)!

The onChange function for this component will fire properly; here's a small example of what I used it for:

import { useEffect, useState } from 'react';
import { sum } from 'lodash/fp';

import { Box, Paragraph } from '@contentful/f36-components';
import { FieldExtensionSDK } from '@contentful/app-sdk';
import { useSDK } from '@contentful/react-apps-toolkit';
import { } from '@contentful/field-editor-reference';
import { 
  ConnectedRichTextEditor 
} from '@contentful/field-editor-rich-text';
import * as Contentful from '@contentful/rich-text-types';

const Field = () => {
  //  resize the field wrapper to fit the content
  const sdk = useSDK<FieldExtensionSDK>();
  useEffect(() => {
    sdk.window.startAutoResizer();
  });

  //  update the character count from the rich text values
  const [charCount, setCharCount] = useState(0);
  const handleChange = (doc: Contentful.Document) => {
    const values = doc.content.map((content: any) => 
      content.content[0].value.length
    )
    setCharCount(sum(values));
  }

  return (
    <>
      <ConnectedRichTextEditor 
        sdk={sdk}
        onChange={handleChange} 
      />

      <Box paddingTop='spacingS'>
        <Paragraph>{charCount} characters</Paragraph>
      </Box>
    </>
  ) 
};

export default Field;

I hope this helps! :)

@github-actions github-actions bot removed the stale Used to mark when there was no activity for a set period of time label Dec 30, 2022
@github-actions
Copy link

Marking issue as stale since there was no activity for 30 days

@github-actions github-actions bot added the stale Used to mark when there was no activity for a set period of time label Jan 29, 2023
@rodikh
Copy link

rodikh commented Sep 11, 2023

Hi,
I'm running into this issue as well with the RichTextEditor component.
It doesn't fire the onChange event when content is written into the text-editor.

I also tried to dig into the internals and found that useOnValueChanged inside SyncEditorChanges which should handle the binding of the callback does not work properly inside its useEffect environment.

Anecdotally, when removed the wrapping useEffect, it started firing properly.

I would appreciate some guidance on the issue.

@github-actions github-actions bot removed the stale Used to mark when there was no activity for a set period of time label Sep 12, 2023
@rodikh
Copy link

rodikh commented Sep 12, 2023

Update:
I tested various older versions of @contentful/field-editor-rich-text and found that onChange and sdk.field.onValueChanged triggers properly in version 3.9.0 but stops working in 3.9.1 and onwards.

@github-actions
Copy link

Marking issue as stale since there was no activity for 30 days

@github-actions github-actions bot added the stale Used to mark when there was no activity for a set period of time label Oct 13, 2023
@skoch
Copy link

skoch commented Feb 15, 2024

Would be nice to get this operational, any update here?

export const RichTextEditorField = ({ sdk }: { sdk: FieldAppSDK }) => {
  const handleOnChange = (doc: Contentful.Document) => {
    console.log('doc', doc)
  }
  return (
    <RichTextEditor onChange={handleOnChange} sdk={sdk} isInitiallyDisabled />
  )
}

@github-actions github-actions bot removed the stale Used to mark when there was no activity for a set period of time label Feb 16, 2024
Copy link

Marking issue as stale since there was no activity for 30 days

@github-actions github-actions bot added the stale Used to mark when there was no activity for a set period of time label Mar 18, 2024
@scarySpice
Copy link

is there any updates on this?

@github-actions github-actions bot removed the stale Used to mark when there was no activity for a set period of time label Aug 9, 2024
@z0al
Copy link
Member

z0al commented Aug 28, 2024

Hey folks, sorry for the lack of engagement here.

Field editors are designed to work exclusively with the App SDK, specifically the FieldSDK. Meaning, all field editors read their values and write changes back via the SDK.

If you want to update a field value, you need do that via the appropriate SDK method. Otherwise onChange may not trigger or would have an undefined behavior.

e.g. This is a tiny field app that renders a text area and the contentful rich text editor. It then syncs all writes to the text area to the Rich text editor as a paragraph. It's a dumb app but gets the idea across. You can use sdk.field.getValue() to get the current value.

Demo

rich-text-editor-updates.mp4

Code

import { FieldAppSDK } from "@contentful/app-sdk";
import { Flex, Textarea, Heading } from "@contentful/f36-components";
import { useAutoResizer, useSDK } from "@contentful/react-apps-toolkit";
import { RichTextEditor } from "@contentful/field-editor-rich-text";
import { useEffect, useState } from "react";

const Field = () => {
	useAutoResizer();

	const sdk = useSDK<FieldAppSDK>();

	const [textAreaValue, setTextAreaValue] = useState<string>("");

	useEffect(() => {
		sdk.field.setValue({
			nodeType: "document",
			data: {},
			content: [
				{
					nodeType: "paragraph",
					data: {},
					content: [
						{
							nodeType: "text",
							value: textAreaValue,
							marks: [],
							data: {},
						},
					],
				},
			],
		});
	}, [textAreaValue]);

	return (
		<Flex flexDirection="column">
			<Heading> Custom Editor</Heading>
			<Flex marginBottom="spacingS" marginTop="spacingS">
				<Textarea
					onChange={(e) => setTextAreaValue(e.target.value)}
					placeholder="Type here to change the rich text editor"
				>
					{textAreaValue}
				</Textarea>
			</Flex>
			<RichTextEditor sdk={sdk} isInitiallyDisabled={false} />
		</Flex>
	);
};

export default Field;

I hope that helps.

@z0al
Copy link
Member

z0al commented Sep 3, 2024

Looks like I misunderstood the issue, sorry. If the issue is that onChange prop to RichTextEditor doesn't work then we confirmed it's a bug and #1740 will fix it.

If you are stuck in an older version, using sdk.field.onValueChanged does the same thing as onChange prop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants