Expand my Community achievements bar.

SOLVED

Content fragment editor extension

Avatar

Level 9

Hello Team,

 

For my POC purpose, I am creating a Content Fragment Editor Extension. I referred few projects here.
https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

 

Executed below project and able to see the custom field displaying product details
Custom Field Extension: https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

 

My actual requirement is: To support multifiled values(Key, value pair) in content fragment.
After the deployment (aio app run), then used the url: https://experience.adobe.com/?repo= so on
Able to see the multifield in content frgment. Note: I have created the dummy text field in CF. Referred the id in ExtensionRegistration.js file

CF-Editor.png


But, when i type the key or value, Its trying to save the value. But getting the error: Fragment update failed. Autosave failed.

fragment-failed.png
What I am missing here?

Below is the  CompositeMultiField.js that is being used in my extension project.

import React, { useEffect, useState } from "react";
import { extensionId } from "./Constants";
import { attach } from "@adobe/uix-guest";
import {
  Provider,
  View,
  defaultTheme,
  Button,
  TextField,
  Flex,
  Repeat,
} from "@adobe/react-spectrum";
import "./CompositeMultiField.css";

const CompositeMultiField = () => {
  const [connection, setConnection] = useState(null);
  const [validationState, setValidationState] = useState(null);
  const [fields, setFields] = useState([{ key: "", value: "" }]); // Default one empty key-value pair

  // Update field value when the user types
  const updateField = (index, type, newValue) => {
    const updatedFields = [...fields];
    updatedFields[index][type] = newValue;
    setFields(updatedFields);
    connection?.host.field.onChange(updatedFields);
  };

  // Add a new key-value pair
  const addField = () => {
    setFields([...fields, { key: "", value: "" }]);
  };

  // Remove a key-value pair
  const removeField = (index) => {
    const updatedFields = fields.filter((_, i) => i !== index);
    setFields(updatedFields);
    connection?.host.field.onChange(updatedFields);
  };

  useEffect(() => {
    const init = async () => {
      const conn = await attach({ id: extensionId });
      setConnection(conn);

      const model = await conn.host.field.getModel();
      const defaultValue = await conn.host.field.getValue();

      if (Array.isArray(defaultValue) && defaultValue.length > 0) {
        setFields(defaultValue);
      }

      conn.host.field.onValidationStateChange(setValidationState);
    };

    init().catch(console.error);
  }, []);


  if (!connection) {
    
    return <Provider theme={defaultTheme}>Loading custom field...</Provider>;
  }

  return (
    <Provider theme={defaultTheme}>
      <View padding="size-200">
        {fields.map((field, index) => (
          <Flex key={index} gap="size-100" alignItems="center">
            <TextField
              label="Key"
              value={field.key}
              onChange={(value) => updateField(index, "key", value)}
              isRequired
              width="45%"
            />
            <TextField
              label="Value"
              value={field.value}
              onChange={(value) => updateField(index, "value", value)}
              isRequired
              width="45%"
            />
            <Button
              variant="negative"
              onPress={() => removeField(index)}
              isDisabled={fields.length === 1} // Prevent removing the last field
            >
              Remove
            </Button>
          </Flex>
        ))}

        <Button variant="cta" onPress={addField} marginTop="size-200">
          Add Key-Value Pair
        </Button>
      </View>
    </Provider>
  );
};

export default CompositeMultiField;

 

My next query is: When I done with testing the extension project(aio app run), I need to deploy to Adobe IO Runtime. Then, how can I link this project to AEM (as cloud service)

 

cc @daniel-strmecki  @sarav_prakash  @arunpatidar @AMANATH_ULLAH  @AmitVishwakarma 

Thanks in advance.

1 Accepted Solution

Avatar

Correct answer by
Level 9

Hi @daniel-strmecki 

 

setFields is the valid one. This is used here

const [fields, setFields] = useState([{ key: "", value: "" }]); // Default one empty key-value pair

 

This was missing earlier.

const [model, setModel] = useState(null); 

 

So, if anyone facing the issue, it is better to use the sample project given in 

https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

Especially, if you are working on any custom field, this is the better project to refer: https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

 

Regarding the deployment: I will ask the query in separate query thread.

 

Thanks

 



 

 

View solution in original post

3 Replies

Avatar

Community Advisor

Hi @Mahesh_Gunaje,

I haven't seen an example before using setFields(customValue). Is that something you built custom or officially supported? In my plugin, I am using setValue(customValue) to ensure that my custom fields store the value back to the original field. This may be something causing problems with auto-save.

After you are done testing locally, you can deploy your app using the aio app deploy command. This will allow you to test your plugin on a DEV AEMaaCS instance. To promote it to PROD, you will need to use the new Extension Manager. I believe this is done trough the UI.

 

Hope this helps,

Daniel

Avatar

Correct answer by
Level 9

Hi @daniel-strmecki 

 

setFields is the valid one. This is used here

const [fields, setFields] = useState([{ key: "", value: "" }]); // Default one empty key-value pair

 

This was missing earlier.

const [model, setModel] = useState(null); 

 

So, if anyone facing the issue, it is better to use the sample project given in 

https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

Especially, if you are working on any custom field, this is the better project to refer: https://experienceleague.adobe.com/en/docs/experience-manager-learn/cloud-service/developing/extensi...

 

Regarding the deployment: I will ask the query in separate query thread.

 

Thanks

 



 

 

Avatar

Community Advisor

Hi @Mahesh_Gunaje,

great to hear you solved it. Just one more thing, be careful with custom multifield, as it will probably work fine with plain text fields. However, if you start adding references (to assets or pages) AEM will not recognize them OOTB. Therefore, MSM operations and copy/move commands might not work as expected.

 

Good luck,

Daniel