2. 작성을 위한 사용자 정의 구성 요소의 속성 정의

사용자 정의 구성 요소에는 양식 작성자가 구성할 수 있는 속성을 지정하는 구성 요소 모델이 포함되어 있습니다. 이러한 속성은 범용 편집기의 속성 대화 상자에 표시되므로 작성자가 레이블, 유효성 검사 규칙, 스타일 및 기타 속성과 같은 설정을 조정할 수 있습니다. 속성을 정의하려면 다음 작업을 수행하십시오.

  1. /blocks/form/components/range/_range.json 파일로 이동하여 사용자 정의 구성 요소에 대한 구성 요소 모델을 추가합니다.

  2. 구성 요소 모델 추가

    사용자 정의 구성 요소의 구성 요소 모델을 정의하려면 관련 필드를 _range.json 파일에 추가해야 합니다.

    1. 새 모델 만들기

      • 모델 배열에서 새 오브젝트를 추가하고 구성 요소 정의에서 이전에 구성된 fd:viewType속성과 일치하도록 구성 요소 모델의 id를 설정합니다.
      • 이 오브젝트 내에 필드 배열을 포함합니다.
    2. 속성 대화 상자의 필드 정의

      • 필드 배열의 각 오브젝트는 컨테이너 유형의 구성 요소여야 하며, 이를 통해 속성 대화 상자에 탭으로 표시될 수 있습니다.
      • 일부 필드는 models/form-common에서 재사용 가능한 속성을 참조할 수 있습니다.
    3. 기존 구성 요소 모델을 참조로 사용

      • 선택한 fieldType에 해당하는 기존 구성 요소 모델의 내용을 복사하고 필요에 따라 수정할 수 있습니다. 예를 들어 number-input 구성 요소는 확장되어 범위 구성 요소를 생성하므로 models/form-components/_number-input.json의 모델 배열을 참조로 사용할 수 있습니다.

    구성 요소 모델을 추가한 후 _range.json 파일은 다음과 같습니다.

    "models": [
    {
      "id": "range",
      "fields": [
        {
          "component": "container",
          "name": "basic",
          "label": "Basic",
          "collapsible": false,
          "...": "../../../../models/form-common/_basic-input-fields.json"
        },
        {
          "...": "../../../../models/form-common/_help-container.json"
        },
        {
          "component": "container",
          "name": "validation",
          "label": "Validation",
          "collapsible": true,
          "...": "../../../../models/form-common/_number-validation-fields.json"
        }
      ]
    }
    ]
    
    NOTE
    사용자 정의 구성 요소의 속성 대화 상자에 새 필드를 추가하려면 정의 스키마를 준수해야 합니다.

    사용자 정의 구성 요소에 사용자 정의 속성을 추가하여 기능을 확장할 수도 있습니다.

사용자 정의 구성 요소에 대한 사용자 정의 속성 추가

사용자 정의 속성을 사용하면 구성 요소의 속성 대화 상자에 설정된 값을 기반으로 특정 동작을 정의할 수 있습니다. 이는 구성 요소의 기능과 사용자 정의 옵션을 확장하는 데 도움이 됩니다.

이 예제에서는 Range 구성 요소에 Step Value를 사용자 정의 속성으로 추가합니다.

단계 값 사용자 정의 속성

단계 값 사용자 정의 속성을 추가하려면 구성 요소 모델에 _<component>.json 파일의 다음 코드 줄을 추가합니다.

      {
      "component": "number",
      "name": "stepValue",
      "label": "Step Value",
      "valueType": "number"
      }

JSON 코드 조각은 범위 구성 요소에 대해 단계 값 ​이라는 사용자 지정 속성을 정의합니다. 다음은 각 필드에 대한 분류입니다.

  • component: 속성 대화 상자에 사용되는 입력 필드 형식을 지정합니다. 이 경우 number은(는) 필드가 숫자 값을 허용함을 나타냅니다.
  • name: 구성 요소의 논리에서 해당 속성을 참조하는 데 사용되는 속성의 식별자입니다. 여기서 stepValue은(는) 범위에 대한 단계 값 설정을 나타냅니다.
  • label: 속성 대화 상자에 표시되는 속성의 표시 이름입니다.
  • valueType: 속성에 필요한 데이터 형식을 정의합니다. number을(를) 사용하면 숫자 입력만 허용됩니다.

이제 stepValue을(를) range.js의 JSON 속성에서 사용자 지정 속성으로 사용하고 런타임 시 해당 값을 기반으로 동적 동작을 구현할 수 있습니다.

따라서 구성 요소 정의, 구성 요소 모델 및 사용자 지정 속성을 추가한 후 최종 _range.json 파일은 다음과 같습니다.

 {
  "definitions": [
    {
      "title": "Range",
      "id": "range",
      "plugins": {
        "xwalk": {
          "page": {
            "resourceType": "core/fd/components/form/numberinput/v1/numberinput",
            "template": {
              "jcr:title": "Range",
              "fieldType": "number-input",
              "fd:viewType": "range",
              "enabled": true,
              "visible": true
            }
          }
        }
      }
    }
  ],
  "models": [
    {
      "id": "range",
      "fields": [
        {
          "component": "container",
          "name": "basic",
          "label": "Basic",
          "collapsible": false,
          "...": "../../../../models/form-common/_basic-input-fields.json"
         {
           "component": "number",
           "name": "stepValue",
            "label": "Step Value",
             "valueType": "number"
}
        },
        {
          "...": "../../../../models/form-common/_help-container.json"
        },
        {
          "component": "container",
          "name": "validation",
          "label": "Validation",
          "collapsible": true,
          "...": "../../../../models/form-common/_number-validation-fields.json"
        }
      ]
    }
  ]
}

구성 요소 정의 및 모델

3. WYSIWYG 구성 요소 목록에 사용자 정의 구성 요소 표시

필터는 범용 편집기에서 사용자 정의 구성 요소를 사용할 수 있는 섹션을 정의합니다. 이를 통해 구성 요소는 구조와 사용성을 유지하면서 적절한 섹션에서만 사용할 수 있습니다.

WYSIWYG에서 양식 작성 중 사용 가능한 구성 요소 목록에 사용자 정의 구성 요소가 표시되도록 하려면:

  1. /blocks/form/_form.json 파일로 이동합니다.
  2. id="form"이 있는 오브젝트 내에서 구성 요소 배열을 찾습니다.
  3. id="form"을 사용하여 definitions[]fd:viewType 값을 오브젝트의 구성 요소 배열에 추가합니다.
 "filters": [
    {
      "id": "form",
      "components": [
        "captcha",
        "checkbox",
        "checkbox-group",
        "date-input",
        "drop-down",
        "email",
        "file-input",
        "form-accordion",
        "form-button",
        "form-fragment",
        "form-image",
        "form-modal",
        "form-reset-button",
        "form-submit-button",
        "number-input",
        "panel",
        "plain-text",
        "radio-group",
        "rating",
        "telephone-input",
        "text-input",
        "tnc",
        "wizard",
        "range"
      ]
    }
  ]

구성 요소 필터

4. 사용자 정의 구성 요소 등록

양식 블록이 양식 작성 중에 사용자 정의 구성 요소를 인식하고 구성 요소 모델에 정의된 속성을 로드할 수 있도록 하려면 구성 요소 정의의 fd:viewType 값을 mappings.js 파일에 추가합니다.
구성 요소를 등록하려면 다음 작업을 수행하십시오.

  1. /blocks/form/mappings.js 파일로 이동합니다.
  2. customComponents[] 배열을 찾습니다.
  3. definitions[] 배열의 fd:viewType 값을 customComponents[] 배열에 추가합니다.
let customComponents = ["range"];
const OOTBComponentDecorators = ['file-input',
                                 'wizard',
                                 'modal', 'tnc',
                                'toggleable-link',
                                'rating',
                                'datetime',
                                'list',
                                'location',
                                'accordion'];

구성 요소 매핑

위의 단계를 완료하면 사용자 정의 구성 요소가 범용 편집기 내의 양식 구성 요소 목록에 나타납니다. 그런 다음 양식 섹션으로 끌어다 놓을 수 있습니다.

범위 구성 요소

아래 스크린샷에는 양식 작성자가 구성할 수 있는 속성을 지정하는 구성 요소 모델에 추가된 range 구성 요소의 속성이 표시됩니다.

범위 구성 요소의 속성

이제 스타일링과 기능을 추가하여 사용자 정의 구성 요소의 런타임 동작을 정의할 수 있습니다.

5. 사용자 정의 구성 요소에 대한 런타임 동작 추가

양식 필드의 스타일링에 설명된 대로 미리 정의된 마크업을 사용하여 사용자 정의 구성 요소를 수정할 수 있습니다. 이는 구성 요소의 모양을 향상시키기 위해 사용자 정의 CSS(Cascading Style Sheets)와 사용자 정의 코드를 사용하여 달성할 수 있습니다. 구성 요소에 런타임 동작을 추가하려면 다음 작업을 수행하십시오.

  1. 스타일링을 추가하려면 /blocks/form/components/range/range.css 파일로 이동하여 다음 코드 라인을 추가합니다.

    /** Styling for range */
    main .form .range-widget-wrapper.decorated input[type="range"] {
    margin: unset;
    padding: unset;
    appearance: none;
    height: 5px;
    border-radius: 5px;
    border: none;
    background-image: linear-gradient(to right, #ADD8E6 calc(100% * var(--current-steps)/var(--total-steps)), #C5C5C5 calc(100% * var(--current-steps)/var(--total-steps)));
    }
    
    main .form .range-widget-wrapper.decorated input[type="range"]:focus {
    outline: none;
    }
    
    .range-widget-wrapper.decorated input[type="range"]::-webkit-slider-thumb {
    appearance: none;
    width: 25px;
    height: 25px;
    border-radius: 50%;
    background: #00008B; /* Dark Blue */
    border: 3px solid #00008B; /* Dark Blue */
    cursor: pointer;
    outline: 3px solid #fff;
    }
    
    .range-widget-wrapper.decorated input[type="range"]:focus::-webkit-slider-thumb {
    border-color: #00008B; /* Dark Blue */
    }
    
    .range-widget-wrapper.decorated .range-bubble {
    color: #00008B; /* Dark Blue */
    font-size: 20px;
    line-height: 28px;
    position: relative;
    display: inline-block;
    padding-bottom: 12px;
    font-weight: bold;
    }
    
    .range-widget-wrapper.decorated .range-min,
    .range-widget-wrapper.decorated .range-max {
    font-size: 14px;
    line-height: 22px;
    color: #494f50;
    margin-top: 16px;
    display: inline-block;
    }
    
    .range-widget-wrapper.decorated .range-max {
    float: right;
    }
    

    이 코드는 사용자 정의 구성 요소의 스타일링과 시각적 모양을 정의하는 데 도움이 됩니다.

  2. 기능을 추가하려면 /blocks/form/components/range/range.js 파일로 이동하여 다음 코드 라인을 추가합니다.

    function updateBubble(input, element) {
    const step = input.step || 1;
    const max = input.max || 0;
    const min = input.min || 1;
    const value = input.value || 1;
    const current = Math.ceil((value - min) / step);
    const total = Math.ceil((max - min) / step);
    const bubble = element.querySelector('.range-bubble');
    // during initial render the width is 0. Hence using a default here.
    const bubbleWidth = bubble.getBoundingClientRect().width || 31;
    const left = `${(current / total) * 100}% - ${(current / total) * bubbleWidth}px`;
    bubble.innerText = `${value}`;
    const steps = {
        '--total-steps': Math.ceil((max - min) / step),
        '--current-steps': Math.ceil((value - min) / step),
    };
    const style = Object.entries(steps).map(([varName, varValue]) => `${varName}:${varValue}`).join(';');
    bubble.style.left = `calc(${left})`;
    element.setAttribute('style', style);
    }
    
    export default async function decorate(fieldDiv, fieldJson) {
    console.log('RANGE DIV: ', fieldDiv);
    console.log('RANGE JSON: fieldJson', fieldJson);
     const input = fieldDiv.querySelector('input');
    // modify the type in case it is not range.
    input.type = 'range';
    input.min = input.min || 10;
    input.max = input.max || 1000;
    // create a wrapper div to provide the min/max and current value
    const div = document.createElement('div');
    div.className = 'range-widget-wrapper decorated';
    input.after(div);
    const hover = document.createElement('span');
    hover.className = 'range-bubble';
    const rangeMinEl = document.createElement('span');
    rangeMinEl.className = 'range-min';
    const rangeMaxEl = document.createElement('span');
    rangeMaxEl.className = 'range-max';
    rangeMinEl.innerText = `${input.min || 1}`;
    rangeMaxEl.innerText = `${input.max}`;
    div.appendChild(hover);
    // move the input element within the wrapper div
    div.appendChild(input);
    div.appendChild(rangeMinEl);
    div.appendChild(rangeMaxEl);
    input.addEventListener('input', (e) => {
    updateBubble(e.target, div);
    });
    updateBubble(input, div);
    return fieldDiv;
    }
    

    사용자 정의 구성 요소가 사용자 입력과 상호 작용하는 방식, 데이터를 처리하는 방식, 범용 편집기의 양식 블록과 통합되는 방식을 제어합니다.

    사용자 정의 스타일링과 기능을 통합한 후 범위 구성 요소의 모양과 동작이 향상되었습니다. 업데이트된 디자인은 적용된 스타일을 반영하며, 추가된 기능은 보다 역동적이면서 인터랙티브한 사용자 경험을 보장합니다.
    아래 스크린샷은 업데이트된 범위 구성 요소를 보여 줍니다.

범위 구성 요소 스타일

자주 묻는 질문

  • component.css와 form.css 모두에 스타일링을 추가하면 어떤 것이 우선시됩니까?
    스타일이 component.cssforms.css 모두에서 정의될 때, component.css가 우선됩니다. 이는 구성 요소 수준의 스타일이 더 구체적이고 forms.css의 글로벌 스타일을 재정의하기 때문입니다.

  • 내 사용자 정의 구성 요소가 범용 편집기의 사용 가능한 구성 요소 목록에 표시되지 않습니다. 이를 어떻게 수정할 수 있습니까?
    사용자 정의 구성 요소가 나타나지 않는 경우 다음 파일을 확인하여 구성 요소가 올바르게 등록되었는지 확인합니다.

    • component-definition.json: 구성 요소가 올바르게 정의되었는지 확인합니다.
    • component-filters.json: 해당 섹션에서 구성 요소가 허용되는지 확인합니다.
    • component-models.json: 구성 요소 모델이 올바르게 구성되었는지 확인합니다.

모범 사례

추가 바이트

지원되는 resourceType

필드 유형리소스 유형
text-inputcore/fd/components/form/textinput/v1/textinput
number-inputcore/fd/components/form/numberinput/v1/numberinput
date-inputcore/fd/components/form/datepicker/v1/datepicker
패널core/fd/components/form/panelcontainer/v1/panelcontainer
확인란core/fd/components/form/checkbox/v1/checkbox
drop-downcore/fd/components/form/dropdown/v1/dropdown
radio-groupcore/fd/components/form/radiobutton/v1/radiobutton
plain-textcore/fd/components/form/text/v1/text
file-inputcore/fd/components/form/fileinput/v2/fileinput
이메일core/fd/components/form/emailinput/v1/emailinput
이미지core/fd/components/form/image/v1/image
버튼core/fd/components/form/button/v1/button

지원되는 fieldTypes

양식에 지원되는 fieldTypes는 다음과 같습니다.

  • text-input
  • number-input
  • date-input
  • 패널
  • 확인란
  • drop-down
  • radio-group
  • plain-text
  • file-input
  • 이메일
  • 이미지
  • 버튼

Experience Manager