@progress/sitefinity-nextjs-sdk
Version:
Provides OOB widgets developed using the Next.js framework, which includes an abstraction layer for Sitefinity communication. Additionally, it offers an expanded API, typings, and tools for further development and integration.
112 lines (111 loc) • 6.93 kB
JavaScript
'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { useContext, useState } from 'react';
import { StylingConfig } from '../../styling/styling-config';
import { VisibilityStyle } from '../../styling/visibility-style';
import { classNames } from '../../../editor/utils/classNames';
import { FormContext } from '../../form/form-context';
import { getUniqueId } from '../../../editor/utils/getUniqueId';
export function CheckboxesClient(props) {
let layoutClass = '';
let innerColumnClass = '';
const parsed = parseInt(props.columnsNumber.toString(), 10);
switch (parsed) {
case 0:
layoutClass = 'd-flex flex-wrap';
innerColumnClass = 'me-2';
break;
case 2:
layoutClass = 'row m-0';
innerColumnClass = 'col-6';
break;
case 3:
layoutClass = 'row m-0';
innerColumnClass = 'col-4';
break;
default:
break;
}
const checkboxUniqueId = props.sfFieldName;
const inputCheckboxUniqueId = getUniqueId(checkboxUniqueId, props.widgetContext.model.Id);
const otherChoiceOptionId = getUniqueId(`choiceOption-other-${checkboxUniqueId}`, props.widgetContext.model.Id);
const otherChoiceInputRef = React.useRef(null);
const [inputValues, setInputValues] = React.useState(props.choices);
const { formViewProps, sfFormValueChanged, hiddenInputs, skippedInputs, registerFieldValidator } = useContext(FormContext);
const isHidden = hiddenInputs[checkboxUniqueId];
const isSkipped = skippedInputs[checkboxUniqueId];
const [errorMessageText, setErrorMessageText] = useState('');
const [otherInputText, setOtherInputText] = useState('');
const [showOtherInput, setShowOtherInput] = useState(false);
let delayTimer;
function dispatchValueChanged() {
clearTimeout(delayTimer);
delayTimer = setTimeout(function () {
sfFormValueChanged();
}, 300);
}
function clearErrorMessage() {
setErrorMessageText('');
}
const handleChange = (event) => {
clearErrorMessage();
const newInputValues = [...inputValues].map((input) => {
return {
...input,
Selected: event.target.value.toString() === input.Value?.toString() ? event.target.checked : input.Selected
};
});
setInputValues(newInputValues);
dispatchValueChanged();
};
function handleOtherChange(event) {
setShowOtherInput(event.target.checked);
dispatchValueChanged();
}
function handleOtherInputChange(event) {
if (event.target.value) {
clearErrorMessage();
}
else {
setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label));
}
dispatchValueChanged();
}
function handleOtherInputInput(event) {
setOtherInputText(event.target.value);
}
const hasValueSelected = React.useMemo(() => {
return inputValues.some((i) => i.Selected);
}, [inputValues]);
const handleChoiceValidation = () => {
const otherChoiceInput = otherChoiceInputRef.current;
if ((props.required && !hasValueSelected) && !(otherChoiceInput && otherChoiceInput.required)) {
setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label));
return false;
}
if (otherChoiceInput && otherChoiceInput.required && otherChoiceInput.validity.valueMissing) {
setErrorMessageText(props.requiredErrorMessage.replace('{0}', props.label));
return false;
}
return true;
};
const validatorRef = React.useRef(handleChoiceValidation);
// eslint-disable-next-line react-hooks/refs
validatorRef.current = handleChoiceValidation;
React.useEffect(() => {
registerFieldValidator(checkboxUniqueId, () => validatorRef.current());
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (_jsxs("fieldset", { "data-sf-role": "checkboxes-field-container", className: classNames('mb-3', props.cssClass, isHidden
? StylingConfig.VisibilityClasses[VisibilityStyle.Hidden]
: StylingConfig.VisibilityClasses[VisibilityStyle.Visible]), "aria-labelledby": `choice-field-label-${checkboxUniqueId} choice-field-description-${checkboxUniqueId}`, children: [_jsx("input", { type: "hidden", "data-sf-role": "required-validator", value: props.required.toString() }), _jsx("legend", { className: "h6", id: `choice-field-label-${checkboxUniqueId}`, children: props.label }), props.instructionalText &&
_jsx("p", { className: "text-muted small", id: `choice-field-description-${checkboxUniqueId}`, children: props.instructionalText }), _jsxs("div", { className: layoutClass, children: [inputValues.map((choiceOption, idx) => {
const choiceOptionId = `choiceOption-${idx}-${inputCheckboxUniqueId}`;
return (_jsxs("div", { className: `form-check ${innerColumnClass}`, children: [_jsx("input", { className: "form-check-input", type: "checkbox", name: checkboxUniqueId, id: choiceOptionId, value: choiceOption.Value || '', "data-sf-role": "checkboxes-field-input", required: props.required && !hasValueSelected, checked: !!choiceOption.Selected, disabled: isHidden || isSkipped, onChange: handleChange }), _jsx("label", { className: "form-check-label", htmlFor: choiceOptionId, children: choiceOption.Name })] }, idx));
}), props.hasAdditionalChoice &&
_jsxs("div", { className: `form-check ${innerColumnClass}`, children: [_jsx("input", { className: "form-check-input mt-1", type: "checkbox", name: checkboxUniqueId, id: otherChoiceOptionId, "data-sf-role": "checkboxes-field-input", required: props.required && !hasValueSelected, checked: showOtherInput, value: otherInputText, onChange: handleOtherChange }), _jsx("label", { className: "form-check-label", htmlFor: otherChoiceOptionId, children: "Other" }), showOtherInput && _jsx("input", { type: "text", ref: otherChoiceInputRef, className: classNames('form-control', {
[formViewProps.invalidClass]: formViewProps.invalidClass && props.required && !otherInputText && !hasValueSelected
}), "data-sf-role": "choice-other-input", value: otherInputText, required: props.required, disabled: isHidden || isSkipped, onChange: handleOtherInputChange, onInput: handleOtherInputInput })] })] }), props.required && errorMessageText && _jsx("div", { "data-sf-role": "error-message", role: "alert", "aria-live": "assertive", className: classNames('invalid-feedback', {
[StylingConfig.VisibilityClasses[VisibilityStyle.Visible]]: true
}), children: errorMessageText })] }));
}