본문으로 건너뛰기

ContextMenu

이 컨트롤은 무엇인가요?

ContextMenu는 마우스 오른쪽 버튼 클릭(우클릭) 시 나타나는 메뉴를 만드는 컨트롤입니다. 내부적으로는 jquery-ui-contextmenu 플러그인을 감싸서 syn.uicontrols.$contextmenu 싱글턴 객체로 제공합니다.

다른 컨트롤들과 다르게 ContextMenu 자체는 화면에 아무것도 그리지 않습니다. 대신 target(메뉴가 뜰 대상)과 delegate(그 대상 안에서 실제로 우클릭을 감지할 하위 요소 셀렉터)를 지정해 두면, 사용자가 해당 요소를 우클릭했을 때 미리 정의한 menu 트리(항목/구분선/하위 메뉴)를 팝업으로 보여줍니다.

언제 사용하나요?

  • 트리 구조 컨트롤(TreeView, OrganizationView 등)의 노드를 우클릭해서 "추가/이름변경/삭제" 같은 동작을 실행할 때
  • 그리드(AUIGrid 등)의 행/셀을 우클릭해서 "복사/붙여넣기/행 삭제" 같은 동작을 제공할 때
  • 일반 div, span 같은 임의의 화면 영역에 우클릭 메뉴를 붙이고 싶을 때

실제로는 TreeView(syn_tree)나 OrganizationView(syn_organization)와 함께 쓰이는 경우가 많습니다. target에 트리/조직도 컨테이너 셀렉터를, delegate에 노드 타이틀 요소 셀렉터(예: span.fancytree-title, div.node)를 지정하는 방식입니다.

빠른 시작

<div id="divTarget">
<input type="button" value="여기를 우클릭 해보세요" />
</div>

<syn_contextmenu id="ctxSample" syn-options="{
target: '#divTarget',
delegate: 'input[type=button]',
menu: [
{ title: 'Cut', cmd: 'cut' },
{ title: 'Copy', cmd: 'copy', uiIcon: 'ui-icon-copy' },
{ title: '---' },
{
title: 'More', children: [
{ title: 'Sub 1', cmd: 'sub1' },
{ title: 'Sub 2', cmd: 'sub2' }
]
}
]
}" syn-events="['beforeOpen', 'select']"></syn_contextmenu>
'use strict';
let $samplePage = {
event: {
ctxSample_select(evt, ui) {
syn.$l.eventLog('ctxSample_select', ui.cmd);
}
}
}

핵심 포인트:

  • 마크업은 <syn_contextmenu> 커스텀 태그로 작성하고, syn-optionstarget/delegate/menu를 JSON으로 넣습니다.
  • 페이지에 <script src="/js/syn.loader.js"></script> 한 줄만 있으면 나머지 CSS/JS는 자동으로 로드됩니다.
  • 메뉴 클릭 결과는 select 이벤트의 ui.cmd 값으로 구분합니다.

예제 실행하기

example/ 폴더의 각 HTML 파일을 handstack의 wwwroot 정적 서버(예: rdy 프로젝트) 경로 아래에 두고 브라우저로 열면 바로 동작을 확인할 수 있습니다.

  • basic.html : 일반 div에 우클릭 메뉴를 붙이는 가장 단순한 예제
  • nested-menu.html : children으로 하위 메뉴(서브 메뉴)를 구성하는 예제
  • events.html : beforeOpen/select 등 이벤트를 로그로 확인하는 예제

각 예제는 화면 하단 로그 영역(syn.$l.eventLog 출력)에서 이벤트 발생 순서와 전달값을 확인할 수 있습니다.

더 알아보기

  • API 상세는 같은 폴더의 API.md를 참고하세요.
  • 실제 소스: wwwroot/uicontrols/ContextMenu/ContextMenu.js, ContextMenu.css
  • 기존 샘플: wwwroot/sample/uicontrol/contextmenu.html, wwwroot/sample/uicontrol/treeview.html (TreeView와 함께 쓰는 예)
  • jquery-ui-contextmenu 원본 문서: https://github.com/mar10/jquery-ui-contextmenu
  • 아이콘 클래스 목록(uiIcon): https://api.jqueryui.com/theming/icons/

실전 예제 페이지

/uicontrols/ContextMenu/example/ 경로의 예제를 아래 iframe에서 바로 확인할 수 있습니다.

basic.html

events.html

nested-menu.html

소스와 로드 파일

항목내용
컨트롤ContextMenu
전역 별칭syn.uicontrols.$contextmenu
버전v2025.3.1
소스uicontrols/ContextMenu/ContextMenu.js
스타일uicontrols/ContextMenu/ContextMenu.css

API 참조

싱글턴 객체: syn.uicontrols.$contextmenu 소스 파일: wwwroot/uicontrols/ContextMenu/ContextMenu.js

마크업

<syn_contextmenu id="ctxTreeItem" syn-options="{
target: '#tvlTreeView',
delegate: 'span.fancytree-title',
menu: [
{ title: 'Cut', cmd: 'cut' },
{ title: 'Copy', cmd: 'copy', uiIcon: 'ui-icon-copy' },
{ title: '---' },
{
title: 'More', children: [
{ title: 'Sub 1', cmd: 'sub1' },
{ title: 'Sub 2', cmd: 'sub2' }
]
}
]
}" syn-events="['beforeOpen', 'select']"></syn_contextmenu>
  • id는 페이지 내에서 유일해야 하며, syn.uicontrols.$contextmenu의 각종 메서드에서 이 id(elID)를 사용합니다.
  • 태그 자체는 controlLoad 실행 후 display:none으로 숨겨집니다(화면에 그려지는 요소가 아니라 동작 정의용 태그입니다).
  • ContextMenu는 자기 자신이 아니라 target으로 지정한 다른 요소 위에서 동작합니다. 따라서 target이 가리키는 요소가 마크업 상에 반드시 먼저(또는 같은 시점에) 존재해야 합니다.

Options (defaultSetting)

속성타입기본값설명
targetstring (CSS 셀렉터)'targetCSSSelector'컨텍스트 메뉴를 붙일 대상 컨테이너. 이 요소 범위 안에서 우클릭을 감지합니다.
delegatestring (CSS 셀렉터)'delegateCSSSelector'target 내부에서 실제로 메뉴를 띄울 하위 요소 셀렉터(이벤트 위임). 예: input[type=button], span.fancytree-title, div.node
autoFocusbooleantrue메뉴가 열릴 때 첫 항목에 자동으로 포커스를 줄지 여부
closeOnWindowBlurbooleantrue브라우저 창이 포커스를 잃으면 메뉴를 자동으로 닫을지 여부
hideboolean | objectfalse메뉴가 닫힐 때 애니메이션 효과 (jQuery UI hide 옵션)
showboolean | objectfalse메뉴가 열릴 때 애니메이션 효과 (jQuery UI show 옵션)
menuarray (메뉴 트리)예시 4항목아래 "menu 트리 구조" 참고
dataTypestring'string'다른 컨트롤과 형식을 맞추기 위한 공통 속성(ContextMenu는 값 개념이 없어 실질적으로 사용하지 않음)
belongID / getter / setter / controlText / validators / transactConfig / triggerConfig-null/falsesyn.uicontrols 공통 옵션(값 바인딩·유효성검사·트랜잭션 연동용). ContextMenu는 getValue/setValue/clear를 지원하지 않으므로 대부분 의미가 없습니다.

menu는 메뉴 항목 객체의 배열입니다. 각 항목은 다음 속성을 가질 수 있습니다.

속성설명
title메뉴에 표시할 텍스트. '---'을 쓰면 구분선(separator)이 됩니다.
cmd항목을 식별하는 고유 문자열. select 이벤트의 ui.cmd로 전달되어 어떤 항목이 클릭됐는지 구분합니다. 구분선/하위메뉴를 여는 부모 항목에는 필요 없습니다.
uiIconjQuery UI 아이콘 클래스명(예: 'ui-icon-copy'). 목록: https://api.jqueryui.com/theming/icons/
children하위 메뉴(서브 메뉴) 배열. 같은 구조(title/cmd/uiIcon/children)를 재귀적으로 가질 수 있습니다.
disabled(jquery-ui-contextmenu 옵션) 항목을 비활성화 상태로 시작하려면 true

예시:

menu: [
{ title: 'Cut', cmd: 'cut' },
{ title: 'Copy', cmd: 'copy', uiIcon: 'ui-icon-copy' },
{ title: '---' },
{
title: 'More', children: [
{ title: 'Sub 1', cmd: 'sub1' },
{ title: 'Sub 2', cmd: 'sub2' }
]
}
]

메서드

syn.uicontrols.$contextmenu.<메서드명>(...) 형태로 호출합니다.

메서드설명
getControl(elID)등록된 컨트롤 정보(객체 설정)를 반환. context는 jquery-ui-contextmenu가 적용된 jQuery 객체입니다.
getValue(elID, meta)지원 안 함(항상 null 반환)
setValue(elID, value, meta)지원 안 함(아무 동작 없음)
clear(elID, isControlLoad)지원 안 함(아무 동작 없음)
close(elID)열려 있는 메뉴를 닫습니다.
open(elID, targetOrEvent, extraData)메뉴를 프로그램적으로 엽니다. 버튼 클릭 등으로 강제로 메뉴를 띄울 때 사용합니다.
isOpen(elID)메뉴가 현재 열려 있는지 여부(boolean)를 반환합니다.
enableEntry(elID, cmd, flag)특정 cmd 항목을 활성화(true)/비활성화(false) 합니다.
showEntry(elID, cmd, flag)특정 cmd 항목을 보이거나(true) 숨깁니다(false).
getEntry(elID, cmd)특정 cmd 항목의 메뉴 데이터를 가져옵니다.
setEntry(elID, cmd, data)특정 cmd 항목의 데이터를 통째로 교체합니다.
updateEntry(elID, cmd, data)특정 cmd 항목의 데이터를 갱신(병합)합니다.
setTitle(elID, cmd, title)특정 cmd 항목의 표시 텍스트를 변경합니다.
setIcon(elID, cmd, icon)특정 cmd 항목의 아이콘을 변경합니다.
getMenu(elID)현재 메뉴 트리 전체 데이터를 반환합니다.
getEntryWrapper(elID, cmd)특정 cmd 항목의 DOM 래퍼 요소를 반환합니다.
setLocale(elID, translations, control, options)다국어 텍스트 적용 훅(ContextMenu는 별도 구현 없음, 빈 함수)

참고: getValue/setValue/clear는 다른 syn.uicontrols 컨트롤과 인터페이스를 맞추기 위해 존재하는 자리표시자(placeholder)일 뿐, ContextMenu에는 "값" 개념이 없어 실제로 아무 것도 하지 않습니다.

이벤트 (syn-events)

syn-events 배열에 이름을 넣으면 페이지 스크립트의 event 객체에서 {elID}_{이벤트명} 함수를 자동으로 연결해 줍니다. (이벤트 핸들러 함수 시그니처는 (evt, ui))

이벤트명발생 시점핸들러 인자
create컨텍스트 메뉴가 처음 초기화될 때 1회(evt, ui)
beforeOpen메뉴가 열리기 직전(evt, ui)ui.target으로 우클릭된 요소 확인 가능. enableEntry/showEntry로 항목을 동적으로 켜고 끄기 좋은 시점
open메뉴가 화면에 열린 직후(evt, ui)
select메뉴 항목을 클릭(선택)했을 때(evt, ui)ui.cmd로 어떤 항목이 선택됐는지 판별
close메뉴가 닫힐 때(evt, ui)

핸들러 등록 예:

let $samplePage = {
event: {
ctxSample_beforeOpen(evt, ui) {
syn.$l.eventLog('ctxSample_beforeOpen', ui.target ? ui.target.id : '');
},
ctxSample_select(evt, ui) {
syn.$l.eventLog('ctxSample_select', ui.cmd);
}
}
}

참고

  • 내부적으로 jQuery의 .contextmenu(setting) / .contextmenu('메서드명', ...) 호출을 그대로 감싼 구조이므로, 더 자세한 옵션/메서드/이벤트 원본 설명은 jquery-ui-contextmenu 문서를 참고하세요: https://github.com/mar10/jquery-ui-contextmenu
  • TreeView(syn_tree)나 OrganizationView(syn_organization)와 함께 쓸 때는 beforeOpen 이벤트에서 evt.target(또는 ui.target)으로 우클릭된 노드를 찾아 enableEntry/showEntry로 항목을 동적으로 제어하는 패턴이 자주 쓰입니다.
  • 메뉴를 버튼 클릭 등 우클릭이 아닌 방식으로 띄우고 싶다면 open(elID, targetOrEvent, extraData) 메서드를 사용하세요.