jui.defineUI("ui.dropdown", [ "jquery" ], function($) { var hideAll = function() { var dd = getDropdown(); if(dd != null) { dd.hide(); } } var getDropdown = function() { var call_list = jui.get("ui.dropdown"); for(var i = 0; i < call_list.length; i++) { var ui_list = call_list[i]; for(var j = 0; j < ui_list.length; j++) { if(ui_list[j].type == "show") return ui_list[j]; } } return null; } $(function() { document.addEventListener("click", function(e) { var tn = e.target.tagName; if(tn != "LI" && tn != "INPUT" && tn != "A" && tn != "BUTTON" && tn != "I") { hideAll(); } }); window.addEventListener("keydown", function(e) { var dd = getDropdown(); if(dd != null) { dd.wheel(e.which, function() { e.preventDefault(); }); } }); }); /** * @class ui.dropdown * Dropdown is a UI component that is frequently used in multiple UI components such as combo box, navigation, table, ect * * @extends core * @alias Dropdown * @requires jquery * */ var UI = function() { var ui_list = null, index = -1; function setEventNodes(self) { var $list = $(ui_list.menu).find("li"); // 이벤트 걸린거 초기화 $list.off("click").off("hover"); // 클릭 이벤트 설정 self.addEvent($list, "click", function(e) { if($(this).hasClass("divider") || $(this).hasClass("title") || $(this).hasClass("disabled")) return; var index = getTargetIndex(this), text = $(this).text(), value = $(this).attr("value"); self.emit("change", [ { index: index, value: value, text: text }, e ]); // close가 true일 경우, 전체 드롭다운 숨기기 if(self.options.close) hideAll(); // A 태그일 경우에는 이벤트 막기 if(e.target.tagName == "A") { e.preventDefault(); } }); // 마우스 오버시 hover 클래스 제거 self.addEvent($list, "hover", function(e) { $list.removeClass("active"); }); function getTargetIndex(elem) { var result = 0; $list.each(function(i) { if(elem == this) { result = i; } }); return result; } } function selectItem(self, callback) { var $list = ui_list.menu.find("li"), $target = $list.eq(index); $list.removeClass("active"); if($target.val() != "" || $target.html() != "") { $target.addClass("active"); if(self.options.height > 0) { ui_list.menu.scrollTop(index * $target.outerHeight()); } } else { if(typeof(callback) == "function") { callback(); } } } this.init = function() { var opts = this.options; var $dd_root = $(this.root), $dd_menu = $dd_root.find("ul"), $dd_anchor = $dd_root.find(".anchor"); // 메인 설정, 없을 경우에는 root가 메인이 됨 $dd_menu = ($dd_menu.length == 0) ? $dd_root : $dd_menu; // UI 객체 추가 ui_list = { root: $dd_root, menu: $dd_menu, anchor: $dd_anchor }; // Size ui_list.root.outerWidth(ui_list.menu.outerWidth()); // Width if(opts.width > 0) { $dd_menu.outerWidth(opts.width); } // Height if(opts.height > 0) { $dd_menu.css({ "maxHeight": opts.height, "overflow": "auto" }); } // Left if(opts.left > 0) { $dd_root.css("left", opts.left); } // Top if(opts.top > 0) { $dd_root.css("top", opts.top); } // Default Styles $dd_menu.css({ "display": "block" }); $dd_root.css({ "position": "absolute", "display": "none" }); // 드롭다운 목록 갱신 if(opts.nodes.length > 0) { this.update(opts.nodes); } else { setEventNodes(this); } this.type = "hide"; // 기본 타입 설정 } /** * @method update * Changes the dropdown list * * @param {Array} nodes Dropdown list */ this.update = function(nodes) { if(!this.tpl.node) return; $(ui_list.menu).empty(); for(var i = 0; i < nodes.length; i++) { $(ui_list.menu).append(this.tpl.node(nodes[i])); } setEventNodes(this); } /** * @method hide * Hides the dropdown */ this.hide = function() { ui_list.root.hide(); this.emit("hide"); this.type = "hide"; } /** * @method show * Shows a dropdown at the specified coordinates * * @param {Integer} x * @param {Integer} y */ this.show = function(x, y) { hideAll(); ui_list.root.show(); // Anchor 옵션 처리 if(ui_list.anchor.length > 0) ui_list.root.css("margin-top", "10px"); // x, y 값이 있을 경우 if(arguments.length == 2) { this.move(x, y); } this.emit("show"); this.type = "show"; } /** * @method move * Moves a dropdown to the specified coordinates * * @param {Integer} x * @param {Integer} y */ this.move = function(x, y) { ui_list.root.css("left", x); ui_list.root.css("top", y); } /** * @method wheel * Changes a selected node upwards when the key is set to -1, or downwards when the key is set to 1. If the key is set to 0, the speciified node is selected * * @param {Integer} key * @param {Function} callback */ this.wheel = function(key, callback) { if(!this.options.keydown) return; var self = this, $list = ui_list.menu.find("li"); // 탭을 눌렀을 경우, 드롭다운 숨기기 if(key == 9) { this.hide(); return; } if(key == 38 || key == -1) { // up if(index < 1) index = $list.length - 1; else index--; selectItem(this, function() { index--; selectItem(self); }); if(callback) callback(); } if(key == 40 || key == 1) { // down if(index < $list.length - 1) index++; else index = 0; selectItem(self, function() { index++; selectItem(self); }); if(callback) callback(); } if(key == 13 || key == 0 || !key) { // enter self.addTrigger($list.eq(index), "click"); index = -1; if(callback) callback(); } } /** * @method reload * Reloads the dropdown list */ this.reload = function() { this.init(); this.emit("reload"); } } UI.setup = function() { return { /** * @cfg {Boolean} [close=true] * Closes the Auto when clicking on the dropdown list */ close: true, /** * @cfg {Boolean} [keydown=false] * It is possible to choose anything on the dropdown list with the arrow keys on the keyboard */ keydown: false, /** * @cfg {Integer} [left=0] * Sets the X coordinate of the dropdown list */ left: 0, /** * @cfg {Integer} [top=0] * Sets the Y coordinate of the dropdown list */ top: 0, /** * @cfg {Integer} [width=0] * Determines the horizontal size of a dropdown list */ width: 0, /** * @cfg {Integer} [height=0] * Determines the vertical size of a dropdown list */ height: 0, /** * @cfg {Array} nodes * Sets a dropdown list to data rather than markup */ nodes: [] } } /** * @event change * Event that occurs when anything on the dropdown list is selected * * @param {Object} data * @param {EventObject} e The event object */ /** * @event show * Event that occurs when a dropdown is shown */ /** * @event hide * Event that occurs when a dropdown is hidden */ /** * @event reload * Event that occurs when a dropdown is reloaded */ return UI; });