Loading...
Area: Optimizely CMS
Applies to versions: 12 and higher
Other versions:

Editor templates

Recommended reading 
Note: This documentation is for the preview version of the upcoming release of CMS 12/Commerce 14/Search & Navigation 14. Features included here might not be complete, and might be changed before becoming available in the public release. This documentation is provided for evaluation purposes only.

Custom script

The VisitorGroupCriterion attribute has a ScriptUrl property where you can specify a script file that is used when creating the user interface for a criteria. The ScriptUrl should refer to a JavaScript file that is a valid CommonJS Module which exports a React component as default.

The available packages in your component are React ^16, axios ^0.19 and @episerver/ui-framework ^0.12.

Props

The props passed to your component is a CriteriaEditorProps that looks like this:

interface CriteriaEditorProps{
name: string;
editorConfig: Array<CriteriaEditorModelPropertyConfig>;
settings: any;
onValueChange: (value: string) => void;
	initLocalization(path: string): any;
	translationsLoaded: boolean;
localization(key: string, fallbackText?: string, values?: any[]): string
}

interface CriteriaEditorModelPropertyConfig {
defaultValue: any;
required: boolean;
range: ValidRange;
pattern: string;
stringLength: ValidRange;
selectItems: any;
additionalProps: any;
label: string;
typeName: string;
order: number;
}

interface ValidRange {
	min: number;
	max: number;
}

The editorConfig property is an array of CriteriaEditorModelPropertyConfig containing all information about each property on the criteria model. The keys are mapped to your model’s property names in camelCase. All attribute decorations and rules for each property are populated here. The property additionalProps contains your additional configuration defined in the CriterionPropertyEditor as JSON.

To use front-end localization, you have to call props.initLocalization(‘path.to.xml.node’) with the path to your XML node. Your translations will be fetched and put in the state. There is a boolean property, translationsLoaded, which indicates when the call is complete. You can then call the localization function to get your translations. This is described further in Localizing the visitor group criterion.

If your model property is an ISelectionFactory, the items are available in the selectItems property.

The settings property holds the saved data for your criteria. It matches the object you emit in the onValueChange function described below.

Saving

For your custom component to be able to save data, you have to pass the data on using the onValueChange prop. Whenever you change your local state also call props.onValueChange, passing in the new state.

const QueryString = (props: CriteriaEditorProps) => {
	const [localModelState, setLocalModelState] = React.useState({});

	useEffect(() => {
    	const state = { ...props.settings }
    	setLocalModelState(state);
	}, []);

	const emitValueChange = (newState: any) => {
    	setLocalModelState(newState);
    	props.onValueChange(newState);
	}

	return (
    	<>
        	<TextField
            	outlined
            	label={props.editorConfig.key.label}
            	defaultValue={localModelState.key}
            	required={props.editorConfig.key.required}
            	onChange={evt => {
                	let newState = { ...localModelState };
                	newState.key = evt.currentTarget.value;
                	emitValueChange(newState);
            	}}
        	/>
        	<ExposedDropdownMenu
            	outlined
            	label={props.editorConfig.condition.label}
            	options={props && props.editorConfig.condition.selectItems.map(item => {
                	return {
                    	label: item.text ?? "",
                    	value: item.value?.toString() ?? ""
                	}
            	})}
            	value={localModelState.condition?.toString()}
            	onValueChange={value => {
                	let newState = { ...localModelState };
                	newState.condition = value;
                	emitValueChange(newState);
            	}}
        	/>
        	{localModelState.condition?.toString() === "1" && <TextField
            	style={{ marginLeft: "10px" }}
            	outlined
            	label={props.editorConfig.value.label}
            	defaultValue={localModelState.value}
            	required={props.editorConfig.value.required}
            	onChange={evt => {
                	let newState = { ...localModelState };
                	newState.value = evt.currentTarget.value;
                	emitValueChange(newState);
            	}
            	}
        	/>}
    	</>
	)
}

export default QueryString
Do you find this information helpful? Please log in to provide feedback.

Last updated: Jul 02, 2021

Recommended reading