# 2. 런타임 호환성 이슈

# 제목 없음



# 2.1. 콤보 박스에 중복된 아이템이 있는 경우 오류 발생

#### 2.1.1. 변경 전

기존 버전에서는 콤보 박스의 리스트가 펼쳐지는 시점에 중복 값을 체크하여 리스트에 중복 오류를 표시하였습니다. 콤보 박스의 리스트에서 스크롤로 표시되지 않는 영역에 중복된값이 있는 경우 아이템 중복체크가 정상적으로 수행되지 않는 현상이 있었습니다.

#### 2.1.2. 변경 후

**1.0.2344(2020년 8월 14일 릴리즈)** 버전에서 콤보 박스를 그릴 때 중복 값이 있는지 체크한 후 오류를 표시하도록 기능이 수정되었습니다.

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/hDbimage.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/hDbimage.png)

#### 2.1.3 조치 방안

콤보 박스에 선행데이터 추가 및 데이터셋 바인딩 시 중복된 value값이 존재하지 않도록 아이템을 수정합니다.

# 2.2. 그리드 동적 컬럼 추가/삭제 시 cellIndex를 잘못 반환 받는 현상

#### 2.2.1. 변경 전

기존 버전에서 그리드 동적 컬럼 추가/삭제 작업 수행 시 삭제된 컬럼의 cellIndex를 추가된 컬럼의 cellIndex로 부여하여 cellIndex가 재사용되었습니다. 이로 인해 추가된 셀의 cellIndex가 잘못 부여되는 현상이 발생하였습니다.

#### 2.2.2. 변경 후

**1.0.3221(2021년 8월 13일 릴리즈)** 버전에서 그리드 동적 컬럼 추가/삭제 시 삭제된 컬럼의 cellIndex를 추가되는 컬럼의 cellIndex로 부여되지 않고, 각각 고유 cellIndex를 갖도록 수정되었습니다.

#### 2.2.3. 조치 방안

동적 컬럼 추가/삭제 시 삭제된 컬럼의 cellIndex를 추가되는 컬럼의 cellIndex로 부여되지 않고, 각각 고유 cellIndex를 갖기 때문에 헤더 셀 인덱스 반환 시 getCellIndices API를 통해 반환 받도록 수정합니다.

**\[과거 버전에서 동적 컬럼 삭제 시 스크립트\]**

```javascript
var vnHCellCnt = vcGrd.header.cellCount;
if (vnHCellCnt && vnHCellCnt != 0) {
	// 마지막 셀부터 시작하여 첫 번째 셀까지 순회한다.
	for (var i = vnHCellCnt; i >= 0; i--) {
		// 각 셀(열)을 삭제한다.
		vcGrd.deleteColumn(i + 1);
	}
}
```

**\[1.0.3221 이후 버전에서 동적 컬럼 삭제 시 스크립트\]**

```javascript
// 그리드의 헤더 영역에 있는 셀의 인덱스 배열을 가져온다.
var afterCol = vcGrd.header.getCellIndices();
if (afterCol && afterCol.length != 0) {
	// 배열의 두 번째 요소부터(인덱스 1) 마지막 요소까지 순회한다.
	for (var i = 1; i < afterCol.length; i++) {
		// 해당 인덱스에 위치한 셀(열)을 삭제한다.
		vcGrd.deleteColumn(afterCol[i]);
	}
}
```

# 2.3. 그리드 setCheckRowIndex API 사용 시 checked 파라미터에 다른 데이터 타입 입력 시 오류가 발생하는 현상

#### 2.3.1. 변경 전

과거 버전에서는 setCheckRowIndex API 사용 시, 두 번째 인자(checked 파라미터)에 boolean 타입이 아닌 다른 데이터 타입을 입력하더라도 체크 동작이 수행되었습니다.

#### 2.3.2. 변경 후

**1.0.3840(2022년 6월 17 릴리즈)** 버전에서 checked 파라미터에 boolean 이외의 타입을 입력할 경우 예외(Exception)가 발생하도록 기능이 수정되었습니다.

#### 2.3.3. 조치 방안

setCheckRowIndex API 사용 시, 두 번째 인자인 checked 파라미터의 값을 반드시 boolean 타입(true/false)으로 입력하도록 소스 코드를 수정합니다.

**\[과거 버전에서 setCheckRowIndex API 사용 시\]**

```javascript
grd.setCheckRowIndex(idx, 1);
```

**\[1.0.3840 이후 버전에서 setCheckRowIndex API 사용 시\]**

```javascript
grd.setCheckRowIndex(idx, true);
```

# 2.4. 선택 컨트롤의 익스프레션에서 ID 셀렉터, 앱 함수, 익스프레션 함수 사용 시 선행 데이터가 처리되지 않는 현상

#### 2.4.1. 변경 전

이전 버전에서는 선택 컨트롤(사이드 내비게이션, 트리, 메뉴, 콤보박스 등)의 setFilter, filterExp 등 익스프레션 편집창에서 ID 셀렉터, 앱 함수, 익스프레션 함수를 사용할 경우, 선행 데이터를 제외하고 필터가 수행되는 현상이 있었습니다. 이로 인해, 기존의 필터 조건 사용 시 선행데이터 값이 표시되지 않는 현상이 발생합니다.

```javascript
filterExp: year == #cmbBefYear.value && quarter == #cmbBefQuarter.value
```

#### 2.4.2. 변경 후

**1.0.4221(2023년 1월 13일 릴리즈)** 버전에서 익스프레션 수행 시 선행 데이터도 함께 처리되도록 기능이 수정되었습니다.  
이에 따라 기존 필터 조건을 그대로 사용할 경우, 선행 데이터 값이 화면에 표시되지 않는 현상이 발생할 수 있습니다.

#### 2.4.3. 조치 방안

기존 익스프레션을 선행 데이터가 포함되도록 다음과 같이 수정하시기 바랍니다.

```javascript
filterExp: value == "" || (year == #cmbAftYear.value && quarter == #cmbAftQuarter.value)
```

또한, 해당 filterExp를 사용하는 페이지를 찾기 위해 스튜디오에서 Ctrl + H 키를 눌러 검색창에 filterExp를 입력하면 관련 페이지를 빠르게 확인할 수 있습니다.

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/Ey0image.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/Ey0image.png)

# 2.5. ★ 입력 컨트롤의 value 속성이 바인딩 되지 않은 경우 value 값 반환 시 null이 반환되는 현상

#### 2.5.1. 변경 전

입력 컨트롤(인풋박스, 마스크 에디터, 서치 인풋, 텍스트 에리어, 데이트 인풋, 넘버 에디터)의 value 속성이 바인딩되지 않고 값이 설정되어 있지 않은 경우, 스크립트에서 해당 컨트롤의 value를 반환하면 null 값이 반환되었습니다.

#### 2.5.2. 변경 후

**1.0.4221 (2023년 1월 13일 릴리즈)** 버전에서 위와 같은 경우, value 값으로 빈 문자열("")이 반환되도록 기능이 수정되었습니다.  
즉, 바인딩되지 않은 value를 반환하면 null이 아닌 빈 문자열("")로 처리됩니다.

#### 2.5.3. 조치 방안

스크립트에서 해당 컨트롤의 value 값 비교 시, 더 이상 null을 기준으로 판단할 수 없으므로 "" (빈 문자열)로 비교하도록 수정해야 합니다.

**\[과거 버전에서 빈 값 비교 시 스크립트\]**

```javascript
var vcIpb = app.lookup(“ipb”);
if (vcIpb == null) {
    //수행할 스크립트
}
```

**\[1.0.4221 이후 버전에서 빈 값 비교 시 스크립트\]**

```javascript
var vcIpb = app.lookup(“ipb”);
if (vcIpb == “”) {
    //수행할 스크립트
}
```

#### 2.5.4. 추가 조치 방안

1.0.4221 이전 버전과의 호환성을 유지하기 위해서 **1.0.5306 (2024년 9월 릴리즈)** 버전부터는 defaults.js를 통해 해당 컨트롤의 기본 value 값을 null로 설정할 수 있도록 기능이 추가되었습니다.  
기본값을 null로 설정하고 싶은 경우에는 defaults.js 파일 내에서 각 컨트롤의 value 속성을 명시적으로 null로 지정하시면 됩니다.

**\[1.0.5306 이후 버전에서 기본 값(null) 설정 스크립트\]**

```javascript
var CPR_DEFAULTS = {
    controls: {
        inputbox: {
            value: null
        },
        numbereditor:{
            value: null
        },
        maskeditor:{
            value: null
        },
    }
}
```

# 2.6. 내비게이션바에서 루트 아이템 클릭 시 포커스가 유지되도록 변경

#### 2.6.1. 변경 전

기존에는 내비게이션바에서 메뉴 아이템을 선택한 후, 메뉴가 닫히면 포커스가 해제되거나 위치가 유지되지 않는 경우가 있었습니다.  
접근성 측면에서 포커스가 명확히 유지되지 않아, 키보드 또는 마우스 조작 시 사용자의 조작 흐름이 끊기는 문제가 발생할 수 있었습니다.

#### 2.6.2. 변경 후

**1.0.4523 (2023년 6월 릴리즈)** 버전에서 expandTrigger="click" 설정 시, 선택된 아이템에 포커스가 유지되도록 동작이 변경되었습니다.  
선택된 아이템에는 .cl-hover 클래스가 자동으로 설정되며, 이는 접근성 강화를 위한 개선 사항입니다.

- 키보드 조작 기준 
    - 하위 메뉴 아이템에서 엔터 키 → 메뉴가 닫히면 루트 아이템에 포커스 이동
    - 메뉴가 닫히지 않으면 선택된 아이템에 포커스 유지
    - 루트 아이템에서 엔터 키 → 선택 및 포커스 유지
- 마우스 조작 기준 
    - 하위 메뉴 아이템 클릭 → 메뉴가 닫히면 루트 아이템에 포커스 이동
    - 메뉴가 닫히지 않으면 클릭한 아이템에 포커스 유지
    - 루트 아이템 클릭 시 → 포커스 유지

#### 2.6.3. 조치 방안

기존 동작 방식으로 되돌리고자 할 경우, 다음 방법 중 하나를 선택하여 적용할 수 있습니다.

1. 스타일로 아이템 포커스 호버 스타일 개선 방법  
    선택된 아이템이 .cl-hover.cl-selected 클래스를 동시에 가질 때 시각적 포커스 스타일을 조정할 수 있습니다. ```css
    .cl-navigationbar.mega-menu {
        .cl-navigationbar-bar {
            .cl-navigationbar-item {
                &:not(.cl-disabled).cl-hover.cl-selected{
                    background-color: @selection-background;
                    color: @selection-foreground;
                }
            }
        }
    }
    ```
2. 아이템 클릭 이벤트에서 내비게이션 바 초점 해제하는 방법  
    포커스를 수동으로 제어하고 싶은 경우, selection-change 또는 item-click 이벤트 내에서 다음과 같이 제어할 수 있습니다: ```javascript
    // 포커스 해제
    navigationbar.blur();
    
    // 포커스가 다시 필요한 경우
    navigationbar.focus();
    ```

# 2.7. 입력 가능한 컨트롤이 비활성화된 경우 드래그로 값이 선택되지 않는 현상

#### 2.7.1. 변경 전

크롬 브라우저 115 버전부터, 입력 가능한 컨트롤(콤보 박스, 인풋 박스, 마스크 에디터, 데이트 인풋, 넘버 에디터, 서치 인풋)이 disabled 상태인 경우, 셀 클릭 이벤트가 발생하지 않는 현상이 나타났습니다.  
이는 크롬 자체의 동작 변화로 인해 사용자가 기대하는 이벤트 처리가 정상적으로 이루어지지 않았습니다.

#### 2.7.2. 변경 후

**1.0.4762 (2023년 11월 릴리즈)** 버전에서 해당 이슈에 대응하기 위해 disabled 상태의 컨트롤에 대해 내부적으로 해당 컨트롤의 input 태그에 pointer-events: none 속성을 적용하도록 수정되었습니다.  
이로 인해 마우스 이벤트는 발생하지만, 비활성화된 컨트롤의 값이 드래그로 선택되지 않는 현상이 추가로 발생할 수 있습니다.

#### 2.7.3. 조치 방안

- 해당 동작은 크롬 116 이상 및 파이어폭스에서도 동일하게 발생하며, 이는 HTML 스펙에 따라 브라우저가 변경된 결과입니다.
- 이전 동작을 유지하기 위해 런타임에서 disabled에 대해 커스텀 DOM 처리를 적용할 수도 있지만, 이는 브라우저 스펙 변화에 대한 대응이 어렵고, UI 및 접근성 측면에서도 표준을 따르기 어려운 문제가 있습니다.
- 따라서 eXbuilder6 런타임에서는 최소한의 영향으로 대응하기 위해 pointer-events: none 처리 방식을 사용하였으며, 이로 인해 텍스트 셀렉션, 마우스 휠 스크롤, 스크롤 버튼 클릭 등이 제한될 수 있습니다.  
    이러한 동작이 필요한 경우에는 disabled 대신 readOnly 속성 사용을 권장드립니다.

# 2.8. 행그룹 그리드 선택 모드에서 키보드 포커스 이동 변경

#### 2.8.1. 변경 전

기존에는 행그룹 그리드 디테일 행 선택 후 키보드 이동(←, →, ↑, ↓, Home, End, PageUp, PageDown) 시 선택행을 기준으로 포커스가 이동되었습니다.

#### 2.8.2. 변경 후

**1.0.4762(2023년 11월 릴리즈)** 버전부터 행그룹 그리드에서 키보드 이동 시 그룹 영역으로도 포커스가 이동됩니다. 그룹영역에서 이동시에는 포커스만 이동되며, 선택 정보는 변경되지 않습니다.

# 2.9. 선택 컨트롤에서 deleteItemByValue API로 아이템 제거 시 선택 값도 제거되도록 기능 변경

#### 2.9.1. 변경 전

선택 컨트롤에 선택된 값이 있는 경우 선택된 값을 deleteItemByValue API로 제거하고 value, values 속성으로 값 확인 시 제거된 값이 남아있는 현상이 있었습니다.

#### 2.9.2. 변경 후

**1.0.4921(2024년 1월 릴리즈)** 버전에서서 아이템 삭제 시 제거된 아이템의 선택 정보도 같이 제거되도록 기능이 변경되었습니다.

※ 변경된 컨트롤 : 라디오 버튼, 체크 박스 그룹, 콤보 박스, 링크드 콤보 박스, 링크드 리스트 박스, 메뉴, 내비게이션 바, 트리, 사이드 내비게이션

# 2.10. 그룹행 그리드의 startCollapse=true인 경우 정렬, 필터 시 그룹이 접히는 현상

#### 2.10.1. 변경 전

그룹행이 있는 그리드에서 동일 조건의 그룹이 여러 개 존재하는 경우, 행 모드 전환, 정렬, 필터 등의 동작 수행 시 그룹의 열림/닫힘 상태가 정확히 유지되지 않는 현상이 발생하였습니다.  
그룹의 확장 상태가 일관되지 않거나 예상과 다른 동작을 하는 경우가 있었습니다.

#### 2.10.2. 변경 후

**1.0.5014(2024년 4월 릴리즈)** 버전에서 해당 문제가 수정되었습니다.  
이후 버전에서는 정렬, 필터, 값 변경 등의 동작으로 인해 그룹핑이 재계산되는 경우, 그룹의 열림/닫힘 상태가 초기 상태(startCollapse 설정값)로 원복되도록 동작 방식이 변경되었습니다.

#### 2.10.3. 조치 방안

1.0.5014 이후 버전부터는 그룹 상태가 동적 변경 중에도 항상 초기 상태로 되돌아가기 때문에, 그룹이 기본적으로 닫힌 상태여야 한다면 아래와 같은 방안을 사용할 수 있습니다:

- startCollapse 속성은 false로 설정
- 화면 로드시, 아래 API를 사용하여 그룹을 수동으로 닫아 초기 상태를 설정  
    ```javascript
    grid.collapseAll();
    ```

이 방식으로 초기 그룹 접힘 상태를 유지하면서도, 정렬이나 필터 이후에도 일관된 상태를 유지할 수 있습니다.

# 2.11. 서브미션 setRequestEncoder 사용 시, request 내용이 달라진 현상

#### 2.11.1. 변경 전

서브미션의 mediaType이 application/x-www-form-urlencoded일 때 요청 데이터 인코딩 시 마지막에 불필요한 &amp;기호를 추가하던 문제와 setRequestEncoder 사용 시 인코딩이 두 번 중첩되던 문제가 있었습니다.

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/MX7image.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/MX7image.png)

#### 2.11.2. 변경 후

**1.0.5014(2024년 4월 릴리즈)** 버전에서 서브미션의 mediaType이 application/x-www-form-urlencoded일 때 마지막에 불필요한 &amp; 기호가 추가되던 문제와 setRequestEncoder 사용 시 두 번 인코딩 되는 현상이 수정되었습니다.

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/OrIimage.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/OrIimage.png)

#### 2.11.3. 조치 방안

최신 버전에서 기존의 동작으로 처리하려면 아래와 같이 수정이 필요합니다.

```javascript
var submission = app.lookup("sms");
submission.setRequestEncoder(function(api, data) {
    var dmSearch= app.lookup("dmSearch");
    var params = dmSearch.getDatas();
    var dataStr = JSON.stringify(params);
    var encodingData = encodeURIComponent(dataStr);
    return {
        content: encodingData;
    }
});
submission.send();
```

# 2.12. sstr이 빈 스타일을 걸러내지 못했던 현상

#### 2.12.1. 변경 전

컨트롤의 displayExp 등 표현식에서 sstr 사용 시 sstr(text)와 같이 스타일을 설정하지 않은 경우에도 class가 적용되는 현상이 있었습니다.

#### 2.12.2. 변경 후

**1.0.5243(2024년 8월 릴리즈)** 버전에서 컨트롤의 sstr 사용 시 스타일이 명시되지 않은 경우 class가 적용되지 않도록 개선되었습니다.

**\[적용한 스타일\]**

```css
.cl-output.user {
    span {
        color: #5d87ff;
    }
}
```

**\[스타일 적용 결과\]**  
[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/q9Dimage.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/q9Dimage.png)

#### 2.12.3. 조치 방안

기존에 sstr 사용 시 스타일이 없더라도 태그(class 포함)가 생성되던 동작은 오류에 가까운 동작으로, 다음의 스크립트를 통해 마이그레이션 작업이 필요합니다.

```javascript
var _originSSTR = cpr.expression.ExpressionEngine.INSTANCE.getFunction("sstr");
cpr.expression.ExpressionEngine.INSTANCE.registerFunction("sstr", function() {
    var args = _.toArray(arguments);
    if (args.length === 1) {
        return _originSSTR(args[0], "no-class");
    } else {
        return _originSSTR.apply(null, args);
    }
});
```

# 2.13. ★ 다이얼로그 style.css를 통해서 constraint가 변경되지 않는 현상

#### 2.13.1. 변경 전

기존에는 다이얼로그의 style.css를 통해 constraint 값을 설정할 수 있었으며, 이는 런타임에서 정상 동작하는 것처럼 보였으나 사실상 의도되지 않은 비정상적인 동작이었습니다.

#### 2.13.2. 변경 후

**1.0.5306 (2024년 9월 릴리즈)** 버전에서 floatControl API를 통해 다이얼로그를 독립적으로 띄우는 기능이 도입되었으며, 이와 함께 기존에 style.css를 통해 다이얼로그의 constraint를 설정할 수 있었던 오류가 수정되었습니다. 이제는 style.css에서 constraint 관련 속성 변경은 반영되지 않도록 차단됩니다.

#### 2.13.3. 조치방안

다이얼로그의 위치 및 크기 등 constraint 설정이 필요한 경우, DialogManager의 updateConstraintByName API를 통해 설정해주시기 바랍니다.

```javascript
DialogManager.updateConstraintByName("myDialog", {
    top: "100px",
    left: "200px",
    width: "600px",
    height: "400px"
});
```

# 2.14. 사용자 정의 속성의 json 형식으로 설정하는 경우 number 타입 입력 시 빈 값이 설정되는 현상

#### 2.14.1. 변경 전

기존에는 사용자 정의 속성(userAttr)을 json 형식으로 설정하는 경우 값에 number타입 입력 시 해당 값이 저장되었습니다. 사용자 정의 속성의 key, value 값은 string 타입으로 입력되어야 하며, 이는 사실상 의도되지 않은 비정상적인 동작입니다.

#### 2.14.2. 변경 후

**1.0.5306 (2024년 9월 릴리즈)** 버전에서 json object 설정 시 타입 검증 로직이 개선되면서 사용 자 정의 속성(userAttr) API 사용 시 string 값만 입력되도록 로직이 변경되었습니다. 기존에 string 타입 이외의 타입이 입력되는 경우 값이 저장되던 로직이 수정되어 현재는 다른 타입이 입력되는 경우 값이 저장되지 않습니다.

```javascript
var button = app.lookup("button");
var vnWidth = 123;
button.userAttr({
    "width": vnWidth
});
// 기존에는 123 반환되었으나 1.0.5306 이후에는 빈 값(“”) 반환
console.log(button.userAttr("width"));
```

#### 2.14.3. 조치 방안

사용자 정의 속성(userAttr) 사용 시 string 타입으로 값이 저장되도록 내부 로직을 수정해주시기 바랍니다.

```javascript
var button = app.lookup("button");
var vnWidth = 123;
button.userAttr({
    "width": vnWidth + “” // string 형식으로 변경
});
```

# 2.15. ★ 컨트롤이 렌더된 HTML 노드의 ID와 컨트롤 uuid 사이의 연관성 제거

#### 2.15.1. 변경 전

모든 컨트롤이 렌더된 HTML 노드의 ID로 “uuid-${컨트롤uuid}” 형태가 적용되고 있어, 앱 개발 소스코드를 가지지 않은 일반 페이지 방문자가 쉽게 컨트롤 내부 상태를 관측하는데 악용될 가능성이 있음

기존 default.js

- `useControlUUIDasHTMLId: true | false` : 컨트롤 uuid 와 노드 id를 일치시킬 것인지 여부
- `htmlIdGenMethod: "depth" | "depth-short"` : useControlUUIDasHTMLId를 false로 지정한 경우에만 작동. 컨트롤의 구조적 순서에 따라 노드 ID 생성. 자동화 스크립트 작성들을 위해 제공됨.

#### 2.15.2. 변경 후

**1.0.5306(2024년 9월 릴리즈)** 버전에서 uuidGenMethod의 기본 값을 secure로 설정하여 컨트롤의 uuid와 렌더된 HTML 노트 ID와의 연관성 제거되었습니다.

- uuidGenMethod - 노드 ID의 생성 방법을 지정하는 속성, 가용값들: 
    - "insecure" - 기존의 기본 값, 컨트롤 uuid와 노드의 id가 동일하게 부여됨.
    - "secure" - 새로운 기본 값. 노드의 id와 컨트롤 uuid 사이의 연관성이 제거됨.
    - "depth" - 컨트롤 하이에라키에 따라 하나의 고정된 식으로 발행됨. 테스트 자동화, 로봇 제어등에 사용.
    - "depth-short" - 상동, 다만 만들어지는 id가 상대적으로 더 짧음

#### 2.15.3. 조치 방안

1.0.5306 이전 버전에서는 컨트롤의 HTML 노드를 찾을 경우 컨트롤의 uuid를 사용하여 찾았습니다.

```javascript
var elContent = document.querySelector("#uuid-" + control.uuid);
```

1.0.5306 이후 버전에서는 컨트롤의 HTML 노드를 찾을 경우 컨트롤의 htmlAttr API를 사용하여 dom 속성을 추가한 후 querySelector로 해당 dom 요소를 찾아주시기 바랍니다.

```javascript
// dom에서 querySelector로 해당 컨텐츠 영역을 찾을 수 있도록 dom 속성 추가
voSelectedContent.htmlAttr("uuid", voSelectedContent.uuid);

cpr.core.DeferredUpdateManager.INSTANCE.asyncExec(function() {
  var ctrlUuid = voSelectedContent.htmlAttr("uuid");
var elContent = document.querySelector("div[data-usr-uuid = "+ ctrlUuid + "]");
});
```

또한, 프로젝트 내에서 uuid를 수정할 부분이 많은 경우 defaults.js에서 uuidGenMethod 값을 insecure로 설정하여 기존과 동일하게 사용할 수 있습니다.

```javascript
var CPR_DEFAULTS = {
    environment: {
        uuidGenMethod: "insecure"
    }
}
```

# 2.16. 메뉴 컨트롤의 아이템 선택 방법 변경

#### 2.16.1. 변경 전

메뉴 컨트롤에 selectionTarget 속성이 추가되면서 기본 동작이 변경되었습니다.

#### 2.16.2. 변경 후

**1.0.5346(2024년 10월 릴리즈)** 버전에서 메뉴 컨트롤에 selectionTarget 속성이 추가되면서 기본 동작이 변경되었습니다. 기존의 동작은 옵션(selectionTarget=all)으로 제공됩니다.

#### 2.16.3. 조치방안

이전과 동일하게 사용하고 싶을 경우 defaults.js에서 selectionTarget을 all로 설정합니다.

```javascript
var CPR_DEFAULTS = {
    controls: {
        menu: {
            selectionTarget: “all”
        }
    }
}
```

# 2.17. 아웃풋 outputType 속성으로 헤딩 타입 적용 시, 렌더링 태그 구성 변경

#### 2.17.1. 변경 전

ios에서 시맨틱 정보가 있는 태그에 스타일이 display:table-cell이 있는 경우 table-cell이 인식을 못하도록 방해하는 현상이 있었습니다.

#### 2.17.2. 변경 후

**1.0.5481(2025년 2월 릴리즈)** 버전에서 outputType 속성 적용 시 label 타입과 동일하게 아웃풋의 root 요소에 변경되도록 수정되었습니다.

※ 센스리더 달라진 점:

- 이전: tabindex 설정 시 센스리더로 탭 이동으로 읽으면 **"레이블 레이블 헤딩1"**로 읽습니다. 텍스트를 두 번 있는 것은 탭 포커스 요소로 인식되는 텍스트와 자식으로 있는 시맨틱 정보의 텍스트를 읽습니다.
- 이후: 포커스 요소가 h1으로 이동되어 시맨틱 정보가 동일한 곳에 위치되어 **"레이블 헤딩1"**로 읽습니다.

# 2.18. 컨트롤의 preventInput=true인 경우 cl-text 영역이 달라진 현상

#### 2.18.1. 변경 전

콤보 박스, 링크드 콤보박스, 데이트 인풋이 preventInput이 true인 경우 overflow: hidden이 누락되어cl-text에 표시되는 텍스트가 padding영역을 무시하고 표시되는 현상이 있었습니다.

#### 2.18.2. 변경 후

**1.0.5542 (2025년 3월 릴리즈)** 버전에서 텍스트가 표시되는 요소에 overflow: hidden이 추가되었습니다.

#### 2.18.3. 조치 방안

기존 방식처럼 표시되길 원할 경우, 컨트롤의 .cl-text.cl-preventinput &gt; div 스타일에 overflow: auto 추가해주시기 바랍니다.

# 2.19. 인풋 계열 컨트롤의 cl-text 요소 기본 padding 스타일이 다른 현상

#### 2.19.1. 변경 전

기존에는 인풋 계열 컨트롤(예: 인풋박스, 마스크 에디터, 데이트 인풋 등)의 cl-text 요소에 컨트롤별로 서로 다른 padding 값이 적용되어 있었습니다.

#### 2.19.2. 변경 후

**1.0.5542 (2025년 3월 릴리즈)** 버전에서 모든 인풋 계열 컨트롤의 cl-text 요소에 대해 padding: 0px 2px으로 통일하는 방식으로 개선되었습니다.

#### 2.19.3. 조치 방안

기존 스타일을 유지하고 싶은 경우에는, 아래 표에 따라 각 컨트롤별 이전 padding 값을 명시적으로 설정하여 기존 UI 정렬을 복원할 수 있습니다.

- 콤보 박스: 0px 3px
- 데이트 인풋: 0px 3px
- 인풋박스: 0px
- 링크드 콤보 박스: 0px 3px
- 마스크 에디터: 0px
- 넘버 에디터: 0px 1px 0px 0px
- 서치 인풋: 0px 3px
- 텍스트 에리어: 0px

```css
/* 예: 인풋박스에 기존 padding 유지 */
.cl-inputbox .cl-text {
    padding: 0px;
}
```

# 2.20. 파일 인풋의 cl-text 요소의 높이가 변경

#### 2.20.1. 변경 전

기존에는 파일 인풋(FileInput)의 cl-text 영역이 다른 입력 컨트롤들과 높이가 일치하지 않아, UI 정렬이 불균형하게 보일 수 있었습니다.

#### 2.20.2. 변경 후

**1.0.5542 (2025년 3월 릴리즈)** 버전에서 파일 인풋의 cl-text 영역이 다른 인풋 타입 컨트롤들과 동일한 높이로 표시되도록 수정되었습니다.

#### 2.20.3. 조치 방안

기존 방식처럼 표시되길 원할 경우, cl-text 클래스에 다음 스타일을 적용하여 정렬 상태를 원복 할 수 있습니다.

```css
.cl-text {
    align-self: center;
    -ms-grid-row-align: center;
}
```

# 2.21. 페이지 인덱서의 일부 속성에 유효하지 않은 값 설정 시 console.error 발생

#### 2.21.1. 변경 전

기존에는 페이지 인덱서의 일부 속성(currentPageIndex, startPageIndex, viewPageCount, pageRowCount, totalRowCount, step)에 유효하지 않은 값(null, 빈 값 등) 설정 시 페이지 인덱서가 비정상적인 값으로 렌더링되는 현상이 있었습니다.

#### 2.21.2. 변경 후

**1.0.5575(2025년 4월 릴리즈)** 버전에서 페이지 인덱서의 일부 속성에 유효성 체크 로직이 추가되었습니다. 유효하지 않은 값이 설정된 경우 console에 error log가 출력됩니다.  
변경 속성 항목: currentPageIndex, startPageIndex, viewPageCount, pageRowCount, totalRowCount, step

#### 2.21.3. 조치 방안

페이지 인덱서에 데이터 맵/셋이 바인딩 되어있는 경우 해당 맵/셋의 기본 값(defaultValue)이 빈 값으로 설정된 경우 오류가 발생할 수 있습니다. 기본 값(defaultValue)을 1또는 해당 속성의 기본 값으로 설정해주시기 바랍니다.

# 2.22. 넘버 에디터가 readOnly 상태인 경우 포커스 시 0이 표시되도록 변경

#### 2.22.1. 변경 전

넘버 에디터의 format이 “#,##0”이고 값이 빈 값인 경우 경우 기존에는 포커스가 없는 상태에서는 0이 표시되었으나 포커스 시 빈 값이 표시됨

#### 2.22.2. 변경 후

**1.0.5647(2025년 5월 릴리즈)** 버전에서 readOnly 상태인 넘버 에디터에 포커스 시에도 0이 표시되도록 수정되었습니다.

# 2.23. 그리드 내 넘버 에디터의 값이 빈 문자열인 경우 필터 다이얼로그에 포맷된 값이 표시되도록 설정

#### 2.23.1. 변경 전

그리드 내 넘버 에디터의 값이 빈 문자열인 경우 뷰잉 모드에서는 포맷된 값으로 표시되나 필터 다이얼로그에서는 빈 문자열로 표시되는 현상이 있었습니다.

#### 2.23.2. 변경 후

**1.0.5739(2025년 7월 릴리즈)** 버전에서 그리드 내 넘버 에디터의 값이 빈 문자열인 경우 필터 다이얼로그에도 포맷된 값으로 표시되도록 수정되었습니다.

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/9emimage.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/9emimage.png)

# 2.24. 콤보박스 리스트와 아이템에 padding 설정 시 텍스트가 잘리는 현상 수정

#### 2.24.1. 변경 전

콤보박스 리스트와 콤보박스 리스트 아이템에 padding 설정 시 아래 이미지와 같이 아이템 텍스트가 잘려보이는 현상이 있었습니다.

```css
.cl-combobox-list {
    padding: 10px 20px;
    .cl-combobox-item {
        padding-left: 20px;
        padding-right: 1px
        &.cl-selected {
            padding-left: 56px;
            padding-right: 1px
        }
    }
}
```

[![image.png](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/scaled-1680-/ARPimage.png)](https://bookstack.tomatosystem.co.kr/uploads/images/gallery/2025-11/ARPimage.png)

#### 2.24.2. 변경 후

**1.0.5739(2025년 7월 릴리즈)** 버전에서 콤보박스 리스트 아이템에 padding 설정 시 항상 긴 텍스트를 기준으로 padding 이 적용되도록 기능이 수정되었습니다.

# 2.25. 그리드의 selectRadio, setCheckRowIndex API 사용 시 row-radio-selected, row-check, row-uncheck 이벤트가 발생하도록 변경

#### 2.25.1. 변경 전

기존에는 그리드의 selectRadio, setCheckRowIndex API를 사용하여 columnType=radio, checkbox 컬럼 선택 시 row-radio-selected, row-check, row-uncheck 이벤트가 발생하지 않았습니다.

#### 2.25.2. 변경 후

**1.0.5819(2025년 9월 릴리즈)** 버전에서 selectRadio, setCheckRowIndex API에 emitEvent 파라미터가 추가되었습니다. emitEvent 기본 값은 true로 selectRadio API 사용 시 row-radio-selected, setCheckRowIndex API 사용 시 row-check, row-uncheck 이벤트가 발생합니다.

#### 2.25.3. 조치 방안

기존이랑 동일하게 selectRadio, setCheckRowIndex API 사용 시 이벤트 전파를 방지하고자 할 경우 EventBus의 addFilter에서 다음과 같이 작성하시기 바랍니다.

```javascript
// row-radio-selected, row-uncheck 이벤트의 경우 아래를 참고하여 스크립트 작성
cpr.events.EventBus.INSTANCE.addFilter("row-check", function(e) {
    var control = e.control;
    // setCheckRowIndex를 통해 체크 시 row-check 이벤트가 발생하지 않도록 함
    if(!e.target) {
        e.stopImmediatePropagation();
        return;
    }
});
```

# 2.26. 캘린더의 최상위 캘린더로 이동한 경우 헤더 타이틀이 비활성화되도록 변경

#### 2.26.1. 변경 전

기존에는 캘린더의 헤더 텍스트를 클릭하여 최상위 캘린더(calendarType=year)로 이동 시 헤더 텍스트가 비활성화되지 않으며, 마우스 호버 및 tab, shift+tab키 이동 시 헤더 텍스트 영역으로 포커스 이동이 가능했습니다.

#### 2.26.2. 변경 후

**1.0.5927(2025년 11월 릴리즈)** 버전에서 캘린더에 maxCalendarType 속성이 추가되면서 최상위로 이동할 수 있는 캘린더 타입을 지정할 수 있도록 기능이 개선되었습니다. 해당 속성이 추가되면서 최상위 캘린더로 이동 시 캘린더의 헤더 타이틀가 비활성화(cl-disabled)되도록 기능이 변경되어 마우스 호버 및 키보드 포커스 이동 시 헤더 타이틀에 포커스가 이동하지 않습니다.

#### 2.26.3. 조치 방안

기존 방식처럼 동작하고자 할 경우, 캘린더의 cl-calendar-header-text 클래스에 다음 스타일을 적용하여 마우스 호버 및 키보드 포커스 시 포커스 스타일이 적용되도록 원복 할 수 있습니다.

```css
//calendar.part.less
.cl-calendar {
  .cl-calendar-header-text {
    &.cl-disabled {
      cursor: default;
        &:hover,
        &.cl-hover {
          color: @selection-background;
          cursor: pointer;
      }
    }
  }
}
```

# 2.27. 컨트롤의 사용자 속성 값을 json 형식으로 설정한 경우 number 타입 입력 시 이전과 다르게 동작하는 현상

```
var button = app.lookup("button ")
button.userAttr({
	"width": 123
});
console.log(button.userAttr("width")) // 반환되는 값이 달라짐
```

#### 2.27.1. 변경 전

**1.0.5306(2024년 9월 릴리즈)** 기준 변경 전

- userAttr("width", 123) 설정 시 string만 허용한다는 오류 메시지와 함께 스크립트 오류 발생.
- userAttr({"width": 123}) 오류 메시지는 구현 되어 있으나 출력하지 않고 모든 타입이 설정 가능합니다.

#### 2.27.2 변경 후

**1.0.5306(2024년 9월 릴리즈)** 기준 변경 후

- userAttr("width", 123) 설정 시 string만 허용한다는 오류 메시지와 함께 스크립트 오류 발생.
- userAttr({"width": 123}) 오류 메시지는 구현 되어 있으나 출력하지 않고 string 타입만 설정됩니다.

# 2.28. (버전 기입필요) 그리드의 자동 행 높이(autoRowHeight) 사용시 텍스트 영역(cl-text)의 높이가 이중 계산되던 문제 수정

#### 2.28.1. 변경전

그리드 내 컨트롤의 .cl-text에 padding이 적용된 경우, 자동 행 높이(autoRowHeight) 계산 과정에서 padding 값이 두 번 적용되는 오류가 있었습니다.

컨텐츠 높이가 18px이고, `.cl-text`의 padding이 6px(상단 6px + 하단 6px)인 경우:

`계산된 행 높이 = 18px + ((6px + 6px) * 2) = 42px`

#### 2.28.2. 변경후

1.0.xxxx(2025년 12월 12일 릴리즈) 버전에서 padding이 중복 계산되지 않도록 수정되었으며, 정상적인 계산 방식은 아래와 같습니다.

`계산된 행 높이 = 18px + (6px + 6px) = 30px`

#### 2.28.3. 조치방안

기존 UI가 이중 계산된 높이를 기준으로 구성되어 있었다면, 업데이트 후 행 높이가 줄어들어 시각적으로 변화가 발생할 수 있습니다.

기존 UI 높이를 유지해야 하는 경우, `cl-text` padding 값을 조절해주시기 바랍니다.

# 2.29. (버전 기입 필요) 매트릭스 서브미션 요청 시, Dataset 내 decimal 값이 빈 값인 경우 null로 전달되던 문제

#### 2.29.1. 변경 전

매트릭스 서브미션 요청 시, DataSet의 decimal 타입 컬럼 값이 **빈 값**인 경우 서버로 전달되는 값이 null로 전달되던 문제가 있었습니다.

#### 2.29.2. 변경 후

**1.0.xxxx(2025년 12월 12일 릴리즈)** 버전에서 ""(empty string)으로 전달되도록 수정되었습니다.