123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415 |
- // Generated by CoffeeScript 2.0.0-beta4
- (function() {
- // ------------------------------------------------------------------------
- // 變數與常數設置
- // ------------------------------------------------------------------------
- // 模組名稱。
- var Attribute, ClassName, EVENT_NAMESPACE, Error, Event, Key, MODULE_NAMESPACE, NAME, Selector, Settings, ZIndex;
- NAME = 'dropdown';
- // 模組事件鍵名。
- EVENT_NAMESPACE = `.${NAME}`;
- // 模組命名空間。
- MODULE_NAMESPACE = `module-${NAME}`;
- // 模組設定。
- Settings = {
- // 消音所有提示,甚至是錯誤訊息。
- silent: false,
- // 顯示除錯訊息。
- debug: true,
- // 監聽 DOM 結構異動並自動重整快取。
- observeChanges: true,
- // 當選單的值被變動時所會呼叫的回呼函式。
- onChange: (value, text, element) => {},
- // 當多選選單多選了一個值所會呼叫的回呼函式。
- onAdd: (addedValue, addedText, addedElement) => {},
- // 當多選選單有一個值被移除時所會呼叫的回呼函式。
- onRemove: (removedValue, removedText, removedElement) => {},
- // 當使用者在多選選單自創了一個新的值所會呼叫的回呼函式。
- onLabelCreate: function(value, text) {
- return this;
- },
-
- // 當上述函式回傳下列物件時就修改元素。
- // {
- // image : ''
- // icon : ''
- // emphasis: ''
- // class : ''
- // element : @
- // }
- // 當使用者再多選選單移除了一個值所會呼叫的回呼函式。
- onLabelRemove: (value, text) => {},
- // 當使用者選取或按壓多選選單其中一個標籤時所會呼叫的回呼函式。
- onLabelSelect: (value, text, element) => {},
- // 當使用者在選單中輸入文字時所呼叫的回呼函式。
- onInput: () => {},
- // 當沒有相符搜尋內容所會呼叫的回呼函式。
- onNoResults: () => {},
- // 當選單展開時所呼叫的回呼函式,回傳 `false` 會避免選單顯示。
- onShow: () => {
- return true;
- },
- // 當選單隱藏時所呼叫的回呼函式,回傳 `false` 會避免選單顯示。
- onHide: () => {
- return true;
- },
- // 當使用者按下選單中其中一個選項時所呼叫的回呼函式。
- onSelect: (value, element) => {},
- // 用以初始化選單內容的選項,當這個選項是 `false` 而不是陣列的時候會從 HTML 架構初始化。
- values: false,
- // 是否允許重新選取,當設為 `true` 時,就算使用者選取了正在選取的值,仍會呼叫 `onChange`。
- allowReselection: false,
- // 是否允許使用者擅自新增選單值。
- allowAdditions: false,
- // 當使用者新增了值並移除後,是否要在選單中隱藏這個值。
- hideAdditions: true,
- // 搜尋的底限字數,超過此字數才會開始搜尋。
- minCharacters: 1,
- // 搜尋時的依據,可用:`both` 符合文字或值、`value` 符合值、`text` 符合文字。
- match: 'both',
- // 是否要進行全文搜尋,若為 `true` 只要搜尋的值符合選項文字其中即可;`false` 則會強迫搜尋的值必須和選項文字開頭相符。
- fullTextSearch: false,
- // 是否要使用標籤而非純計數文字。
- useLabels: true,
- // 多選選單是否使用標籤?若設置為 `false` 會以「已選擇 x 個」純文字替代標籤。
- useLabels: true,
- // 多選選單最多可以選擇幾個項目?設置為 `0` 表示無限。
- maxSelections: 0
- };
- // 事件名稱。
- Event = {
- CHANGE: `change${EVENT_NAMESPACE}`,
- ADD: `add${EVENT_NAMESPACE}`,
- REMOVE: `remove${EVENT_NAMESPACE}`,
- LABEL_CREATE: `labelcreate${EVENT_NAMESPACE}`,
- LABEL_REMOVE: `labelremove${EVENT_NAMESPACE}`,
- LABEL_SELECT: `labelselect${EVENT_NAMESPACE}`,
- INPUT: `input${EVENT_NAMESPACE}`,
- NO_RESULT: `noresult${EVENT_NAMESPACE}`,
- SHOW: `show${EVENT_NAMESPACE}`,
- HIDE: `hide${EVENT_NAMESPACE}`,
- SELECT: `select${EVENT_NAMESPACE}`,
- CLICK: `click${EVENT_NAMESPACE}`,
- ANIMATIONEND: `animationend${EVENT_NAMESPACE}`
- };
- // 樣式名稱。
- ClassName = {
- VISIBLE: 'visible',
- HIDDEN: 'hidden',
- ANIMATING: 'animating',
- DROPDOWN: 'dropdown',
- TEXT: 'text',
- ICON: 'icon',
- IMAGE: 'image',
- ITEM: 'item',
- MENU: 'menu',
- UPWARD: 'upward',
- DOWNWARD: 'downward',
- LEFTWARD: 'leftward',
- RIGHTWARD: 'rightward',
- SELECTION: 'selection',
- MULTIPLE: 'multiple',
- LABELS: 'labels',
- CLOSE: 'close',
- DEFAULT_LABEL: 'ts compact label',
- DEFAULT_BUTTON: 'ts tiny close button',
- FILTERED: 'filtered',
- PLACEHOLDER: 'placeholder',
- SELECTED: 'selected',
- ACTIVE: 'active',
- ADDITION_ITEM: 'addition item'
- };
- // 選擇器名稱。
- Selector = {
- OPTION: 'option',
- DROPDOWN: '.ts.dropdown',
- VISIBLE_DROPDOWN: '.ts.visible.dropdown',
- DEFAULT_BUTTON: '.ts.tiny.close.button',
- LABELS: '.labels',
- SELF_LABELS: ':scope > .labels',
- SEARCH: 'input.search',
- ITEM: '.item:not(.addition)',
- ACTIVE_ITEM: '.active.item',
- UNSELECTED_ITEM: '.item:not(.selected):not(.addition)',
- ACTIVE_ITEM_UNFILTERED: '.active.item:not(.filtered):not(.addition)',
- ITEM_NOT_FILTERED: '.item:not(.filtered):not(.addition)',
- FILTERED: '.filtered',
- TEXT: '.text',
- LABEL: '.labels .label',
- MESSAGE: '.message',
- MENU: '.menu',
- ADDITION_ITEM: '.addition.item',
- SELECT: 'select',
- SELECTED_ITEM: '.item.selected',
- BODY: 'body',
- SELECTABLE_OPTION: 'select option:not([selected]):not([value=""])',
- SPECIFIED_OPTION: (v) => {
- return `select option[value='${v}']`;
- },
- SPECIFIED_ITEM: (v) => {
- return `.menu .item[data-value='${v}']`;
- },
- SPECIFIED_LABEL: (v) => {
- return `.labels .label[data-value='${v}']`;
- }
- };
- // 鍵盤按鍵代號。
- Key = {
- ENTER: 13,
- BACKSPACE: 8,
- UP: 38,
- DOWN: 40,
- LEFT: 37,
- RIGHT: 39
- };
- // Z 索引
- ZIndex = {
- MENU: 9,
- ACTIVE: 10,
- HOVERED: 11
- };
- // 元素資訊標籤。
- Attribute = {
- VALUE: 'data-value'
- };
- // 錯誤訊息。
- Error = {};
- // ------------------------------------------------------------------------
- // 模組註冊
- // ------------------------------------------------------------------------
- ts.register({NAME, MODULE_NAMESPACE, Error, Settings}, ({$allModules, $this, element, debug, settings}) => {
- var $body, duration, id, module;
- // ------------------------------------------------------------------------
- // 區域變數
- // ------------------------------------------------------------------------
- $body = ts(Selector.BODY);
- id = $this.uniqueID();
- duration = 300;
- // ------------------------------------------------------------------------
- // 模組定義
- // ------------------------------------------------------------------------
- return module = {
- setup: {
- menu: (values) => {}
- },
- change: {
- values: (values) => {}
- },
- refresh: () => {},
- toggle: () => {
- if (module.is.visible()) {
- return module.hide();
- } else {
- return module.show();
- }
- },
- animate: {
- expand: (callback) => {
- module.set.zIndex(ZIndex.ACTIVE);
- return $this.removeClass(ClassName.HIDDEN).addClass(`${ClassName.VISIBLE} ${ClassName.ANIMATING}`).off(Event.ANIMATIONEND).one(Event.ANIMATIONEND, () => {
- if (callback != null) {
- return callback.call();
- }
- }).emulate(Event.ANIMATIONEND, duration);
- },
- contract: (callback) => {
- module.set.zIndex(ZIndex.MENU);
- return $this.removeClass(ClassName.VISIBLE).addClass(`${ClassName.HIDDEN} ${ClassName.ANIMATING}`).off(Event.ANIMATIONEND).one(Event.ANIMATIONEND, () => {
- if (callback != null) {
- return callback.call();
- }
- }).emulate(Event.ANIMATIONEND, duration);
- }
- },
- show: () => {
- if (module.is.visible()) {
- return;
- }
- if (module.trigger.show() === false) {
- return;
- }
- module.set.direction();
- return module.animate.expand(() => {
- if (module.is.visible()) {
- return $this.removeClass(ClassName.ANIMATING);
- }
- });
- },
- hide: () => {
- if (module.is.hidden()) {
- return;
- }
- if (module.trigger.hide() === false) {
- return;
- }
- module.set.direction();
- return module.animate.contract(() => {
- if (!module.is.hidden()) {
- return;
- }
- return $this.removeClass(`${ClassName.ANIMATING} ${ClassName.HIDDEN} ${ClassName.UPWARD} ${ClassName.DOWNWARD} ${ClassName.LEFTWARD} ${ClassName.RIGHTWARD}`);
- });
- },
- clear: () => {},
- hideOthers: () => {},
- restore: {
- defaults: () => {},
- default: {
- text: () => {},
- value: () => {}
- },
- placeholder: {
- text: () => {}
- }
- },
- save: {
- defaults: () => {}
- },
- set: {
- selected: (value) => {},
- exactly: (value) => {},
- text: (text) => {},
- value: (value) => {},
- active: () => {},
- visible: () => {},
- zIndex: (z) => {
- return $this.css('z-index', z);
- },
- direction: () => {
- var height, heightHalf, position, width, widthHalf;
- position = $this.rect();
- width = window.innerWidth;
- widthHalf = width / 2;
- height = window.innerHeight;
- heightHalf = height / 2;
- if (position.left < widthHalf && position.top < heightHalf) {
- return $this.addClass(`${ClassName.DOWNWARD} ${ClassName.RIGHTWARD}`);
- } else if (position.left < widthHalf && position.top > heightHalf) {
- return $this.addClass(`${ClassName.UPWARD} ${ClassName.RIGHTWARD}`);
- } else if (position.left > widthHalf && position.top > heightHalf) {
- return $this.addClass(`${ClassName.UPWARD} ${ClassName.LEFTWARD}`);
- } else if (position.left > widthHalf && position.top < heightHalf) {
- return $this.addClass(`${ClassName.DOWNWARD} ${ClassName.LEFTWARD}`);
- }
- }
- },
- remove: {
- selected: (value) => {}
- },
- get: {
- text: () => {},
- value: () => {},
- item: (value) => {},
- default: {
- text: () => {}
- },
- placeholder: {
- text: () => {}
- }
- },
- determine: {
- intent: () => {},
- select: {
- action: (text, value) => {}
- }
- },
- remove: {
- active: () => {},
- visible: () => {}
- },
- is: {
- selection: () => {},
- animated: () => {},
- visible: () => {
- return $this.hasClass(ClassName.VISIBLE);
- },
- hidden: () => {
- return !module.is.visible();
- }
- },
- listener: {
- body: (target) => {
- var isSelfChild;
- // Multiple Tag delete button
- // if $target.hasClass('close')
- // return
- isSelfChild = $this.is(target) || $this.contains(target);
- if (!isSelfChild) {
- return module.hide();
- }
- }
- },
- trigger: {
- select: (event) => {
- var item, value;
- value = ts(event.target).attr(Attribute.VALUE);
- item = event.target;
- debug('發生 SELECT 事件', value);
- return settings.onSelect.call(element, value, item);
- },
- show: () => {
- debug('發生 SHOW 事件', element);
- return settings.onShow.call(element);
- },
- hide: () => {
- debug('發生 HIDE 事件', element);
- return settings.onHide.call(element);
- }
- },
- bind: {
- events: () => {
- $body.on(`${Event.CLICK}${id}`, (event) => {
- //debug '發生 CLICK 事件', element
- return module.listener.body(event.target);
- });
- $this.on(Event.CLICK, (event) => {
- //debug "發生 CLICK 事件", element
- return module.toggle();
- });
- return $this.on(Event.CLICK, Selector.ITEM, (event) => {
- //debug "發生 CLICK 事件", element
- return module.trigger.select(event);
- });
- }
- },
- // $this.on Event.CHANGE, (event, context) =>
- // debug "發生 CHANGE 事件", context
- // settings.onChange.call context, event
- // ------------------------------------------------------------------------
- // 基礎方法
- // ------------------------------------------------------------------------
- initialize: () => {
- debug('初始化下拉式選單', element);
- return module.bind.events();
- },
- instantiate: () => {
- return debug('實例化下拉式選單', element);
- },
- refresh: () => {
- return $allModules;
- },
- destroy: () => {
- debug('摧毀下拉式選單', element);
- $body.off(`${Event.CLICK}${id}`);
- $this.removeData(MODULE_NAMESPACE).off(EVENT_NAMESPACE);
- return $allModules;
- }
- };
- });
- }).call(this);
|