├── .travis.yml ├── API.md ├── LICENSE ├── README.md ├── bower.json ├── deploy.sh ├── dist ├── ax5dialog.css ├── ax5dialog.js ├── ax5dialog.min.js └── ax5dialog.min.js.map ├── karma.conf.js ├── package.json ├── src ├── ax5dialog.js ├── ax5dialog.scss ├── modules │ └── ax5dialog-tmpl.js └── scss │ ├── _ax5dialog.scss │ └── _ax5dialog_variables.scss └── test ├── README.md ├── bower.json ├── index.html ├── test.dialog.html └── test.dialog.js /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "4" 4 | before_script: 5 | - export CHROME_BIN=chromium-browser 6 | - export DISPLAY=:99.0 7 | - sh -e /etc/init.d/xvfb start -------------------------------------------------------------------------------- /API.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## ax5dialog 4 | **Kind**: global class 5 | **Author:** tom@axisj.com 6 | 7 | * [ax5dialog](#ax5dialog) 8 | * [.setConfig(config)](#ax5dialog.setConfig) ⇒ [ax5dialog](#ax5dialog) 9 | * [.alert(config, [callback])](#ax5dialog.alert) ⇒ [ax5dialog](#ax5dialog) 10 | * [.confirm(config, [callback])](#ax5dialog.confirm) ⇒ [ax5dialog](#ax5dialog) 11 | * [.prompt(config, [callback])](#ax5dialog.prompt) ⇒ [ax5dialog](#ax5dialog) 12 | * [.close()](#ax5dialog.close) ⇒ [ax5dialog](#ax5dialog) 13 | 14 | 15 | 16 | ### ax5dialog.setConfig(config) ⇒ [ax5dialog](#ax5dialog) 17 | Preferences of dialog UI 18 | 19 | **Kind**: static method of [ax5dialog](#ax5dialog) 20 | 21 | | Param | Type | Default | Description | 22 | | --- | --- | --- | --- | 23 | | config | Object | | 클래스 속성값 | 24 | | [config.theme] | String | "default" | | 25 | | [config.width] | Number | 300 | | 26 | | [config.title] | String | "" | | 27 | | [config.zIndex] | Number | | | 28 | | [config.onStateChanged] | function | | `onStateChanged` function can be defined in setConfig method or new ax5.ui.dialog initialization method. However, you can us to define an event function after initialization, if necessary | 29 | | [config.lang] | Object | | | 30 | | [config.lang.ok] | String | "ok" | | 31 | | [config.lang.cancel] | String | "cancel" | | 32 | | [config.animateTime] | Number | 150 | | 33 | | [config.autoCloseTime] | Number | 0 | 0보다 크면 autoCloseTime 프레임후에 dialog auto close | 34 | 35 | **Example** 36 | ``` 37 | var dialog = new ax5.ui.dialog(); 38 | dialog.setConfig({ 39 | title: "app dialog title", 40 | zIndex: 5000, 41 | onStateChanged: function () { 42 | if (this.state === "open") { 43 | mask.open(); 44 | } 45 | else if (this.state === "close") { 46 | mask.close(); 47 | } 48 | } 49 | }); 50 | ``` 51 | 52 | 53 | ### ax5dialog.alert(config, [callback]) ⇒ [ax5dialog](#ax5dialog) 54 | open the dialog of alert type 55 | 56 | **Kind**: static method of [ax5dialog](#ax5dialog) 57 | 58 | | Param | Type | Default | Description | 59 | | --- | --- | --- | --- | 60 | | config | Object | String | | dialog 속성을 json으로 정의하거나 msg만 전달 | 61 | | [config.theme] | String | "default" | | 62 | | [config.width] | Number | 300 | | 63 | | [config.title] | String | "" | | 64 | | [config.zIndex] | Number | | | 65 | | [config.onStateChanged] | function | | | 66 | | [config.lang] | Object | | | 67 | | [config.lang.ok] | String | "ok" | | 68 | | [config.lang.cancel] | String | "cancel" | | 69 | | [config.animateTime] | Number | 150 | | 70 | | [config.autoCloseTime] | Number | 0 | 0보다 크면 autoCloseTime 프레임후에 dialog auto close | 71 | | [config.additionalContent] | function | String | | | 72 | | [callback] | function | | 사용자 확인 이벤트시 호출될 callback 함수 | 73 | 74 | **Example** 75 | ``` 76 | myDialog.alert({ 77 | title: 'app title', 78 | msg: 'alert' 79 | }, function(){}); 80 | ``` 81 | 82 | 83 | ### ax5dialog.confirm(config, [callback]) ⇒ [ax5dialog](#ax5dialog) 84 | open the dialog of confirm type 85 | 86 | **Kind**: static method of [ax5dialog](#ax5dialog) 87 | 88 | | Param | Type | Default | Description | 89 | | --- | --- | --- | --- | 90 | | config | Object | String | | dialog 속성을 json으로 정의하거나 msg만 전달 | 91 | | [config.theme] | String | "default" | | 92 | | [config.width] | Number | 300 | | 93 | | [config.title] | String | "" | | 94 | | [config.zIndex] | Number | | | 95 | | [config.onStateChanged] | function | | | 96 | | [config.lang] | Object | | | 97 | | [config.lang.ok] | String | "ok" | | 98 | | [config.lang.cancel] | String | "cancel" | | 99 | | [config.animateTime] | Number | 150 | | 100 | | [config.autoCloseTime] | Number | 0 | 0보다 크면 autoCloseTime 프레임후에 dialog auto close | 101 | | [config.additionalContent] | function | String | | | 102 | | [callback] | function | | 사용자 확인 이벤트시 호출될 callback 함수 | 103 | 104 | **Example** 105 | ``` 106 | myDialog.confirm({ 107 | title: 'app title', 108 | msg: 'confirm', 109 | additionalContent: function () { 110 | return "
추가정보
"; 111 | } 112 | }, function(){}); 113 | ``` 114 | 115 | 116 | ### ax5dialog.prompt(config, [callback]) ⇒ [ax5dialog](#ax5dialog) 117 | open the dialog of prompt type 118 | 119 | **Kind**: static method of [ax5dialog](#ax5dialog) 120 | 121 | | Param | Type | Default | Description | 122 | | --- | --- | --- | --- | 123 | | config | Object | String | | dialog 속성을 json으로 정의하거나 msg만 전달 | 124 | | [config.theme] | String | "default" | | 125 | | [config.width] | Number | 300 | | 126 | | [config.title] | String | "" | | 127 | | [config.zIndex] | Number | | | 128 | | [config.onStateChanged] | function | | | 129 | | [config.lang] | Object | | | 130 | | [config.lang.ok] | String | "ok" | | 131 | | [config.lang.cancel] | String | "cancel" | | 132 | | [config.animateTime] | Number | 150 | | 133 | | [config.autoCloseTime] | Number | 0 | 0보다 크면 autoCloseTime 프레임후에 dialog auto close | 134 | | [config.additionalContent] | function | String | | | 135 | | [callback] | function | | 사용자 확인 이벤트시 호출될 callback 함수 | 136 | 137 | **Example** 138 | ``` 139 | myDialog.prompt({ 140 | title: 'app title', 141 | msg: 'alert' 142 | }, function(){}); 143 | ``` 144 | 145 | 146 | ### ax5dialog.close() ⇒ [ax5dialog](#ax5dialog) 147 | close the dialog 148 | 149 | **Kind**: static method of [ax5dialog](#ax5dialog) 150 | **Example** 151 | ``` 152 | myDialog.close(); 153 | ``` 154 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2016 Thomas Jang, Brant and Team AXISJ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![ax5ui-travis-passing](https://travis-ci.org/ax5ui/ax5ui-dialog.svg?branch=master) 2 | [![npm version](https://badge.fury.io/js/ax5ui-dialog.svg)](https://badge.fury.io/js/ax5ui-dialog) 3 | [![](https://img.shields.io/npm/dm/ax5ui-dialog.svg)](https://www.npmjs.com/package/ax5ui-dialog) 4 | 5 | # ax5ui-dialog 6 | "dialog" displays information on a popup window and also enables users to enter input values. 7 | 8 | > *Dependencies* 9 | > * _[jQuery 1.X+](http://jquery.com/)_ 10 | > * _[ax5core](http://ax5.io/ax5core)_ 11 | > * _[bootstrap](http://getbootstrap.com/)_ 12 | 13 | 14 | ### Install with bower 15 | ```sh 16 | bower install ax5ui-dialog 17 | ``` 18 | [bower](http://bower.io/#install-bower) is web front-end package manager. 19 | When you install `bower`, it will be installed under the `bower_components` folder to resolve the plug-in dependencies. 20 | (You can change the folder location. [.bowerrc](http://bower.io/docs/config/#bowerrc-specification) ) 21 | 22 | It is recommended that you install by using `bower`. 23 | If you've never used bower, please refer to [http://bower.io/#install-bower](http://bower.io/#install-bower). 24 | 25 | ### Install with npm 26 | If you do not use bower, it also can be installed by using npm as an alternative. 27 | In case of npm, which is the package manager for the front end, you need to solve the problem of plug-in dependencies. 28 | 29 | ```sh 30 | npm install jquery 31 | npm install ax5core 32 | npm install ax5ui-dialog 33 | ``` 34 | 35 | After downloading the install file of npm, you will need to copy it to the location where you want to use as a resource for the project. 36 | If the copy process is inconvenient, it also can be done easily by using `gulp` or `grunt`. 37 | 38 | ### Download code 39 | - [ax5core Github releases](https://github.com/ax5ui/ax5core/releases) 40 | - [ax5ui-dialog Github releases](https://github.com/ax5ui/ax5ui-dialog/releases) 41 | 42 | 43 | ### Insert "ax5dialog" in HTML HEAD. 44 | Folder location can be any for your project. However, please be sure to assign the right path in the project. 45 | 46 | ```html 47 | 48 | 49 | 50 | 51 | ``` 52 | 53 | **CDN urls** 54 | This is a list of CDN urls for ax5ui-dialog. ax5ui offers the CDN services through rawgit. 55 | ``` 56 | https://cdn.rawgit.com/ax5ui/ax5ui-dialog/master/dist/ax5dialog.css 57 | https://cdn.rawgit.com/ax5ui/ax5ui-dialog/master/dist/ax5dialog.js 58 | https://cdn.rawgit.com/ax5ui/ax5ui-dialog/master/dist/ax5dialog.min.js 59 | ``` 60 | 61 | 62 | ### Basic Usage 63 | ```js 64 | var myDialog = new ax5.ui.dialog({ 65 | title: ' Default alert', 66 | onStateChanged: function(){ 67 | 68 | } 69 | }); 70 | 71 | $('#btn').click(function () { 72 | myDialog.alert({ 73 | msg: 'Alert message' 74 | }, function () { 75 | console.log(this); 76 | }); 77 | }); 78 | ``` 79 | 80 | * * * 81 | 82 | ### Preview 83 | - [See Demonstration](http://ax5.io/ax5ui-dialog/demo/index.html) 84 | 85 | If you have any questions, please refer to the following [gitHub](https://github.com/ax5ui/ax5ui-kernel) 86 | 87 | ## Question 88 | - https://jsdev.kr/c/axisj/ax5ui 89 | - https://github.com/ax5ui/ax5ui-kernel/issues 90 | 91 | [![axisj-contributed](https://img.shields.io/badge/AXISJ.com-Contributed-green.svg)](https://github.com/axisj) 92 | ![](https://img.shields.io/badge/Seowoo-Mondo&Thomas-red.svg) -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-dialog", 3 | "version": "1.4.131", 4 | "description": "A dialog plugin that works with Bootstrap & jQuery", 5 | "authors": [ 6 | "ThomasJ " 7 | ], 8 | "main": "dist/ax5dialog.js", 9 | "keywords": [ 10 | "bootstrap", 11 | "jquery", 12 | "ax5ui", 13 | "plugin", 14 | "bootstrap jQuery plugins", 15 | "dialog", 16 | "ax5ui-dialog", 17 | "javascript ui" 18 | ], 19 | "dependencies": { 20 | "jquery": "", 21 | "ax5core": ">=1.4.115" 22 | }, 23 | "license": "MIT", 24 | "homepage": "ax5.io" 25 | } -------------------------------------------------------------------------------- /deploy.sh: -------------------------------------------------------------------------------- 1 | VERSION=`jq '.version' package.json | sed -e 's/^"//' -e 's/"$//'` 2 | 3 | git tag -a $VERSION -m $VERSION || true 4 | 5 | git push origin HEAD:master --follow-tags --force || true 6 | 7 | npm publish || true 8 | -------------------------------------------------------------------------------- /dist/ax5dialog.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Copyright (c) 2017. tom@axisj.com 3 | * - github.com/thomasjang 4 | * - www.axisj.com 5 | *//*! 6 | * Copyright (c) 2017. tom@axisj.com 7 | * - github.com/thomasjang 8 | * - www.axisj.com 9 | */fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857;color:#555}.form-control{box-sizing:border-box;display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;-o-transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s;transition:border-color ease-in-out 0.15s,box-shadow ease-in-out 0.15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control::-ms-expand{border:0;background-color:transparent}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio: 0){input[type="date"].form-control,input[type="time"].form-control,input[type="datetime-local"].form-control,input[type="month"].form-control{line-height:34px}input[type="date"].input-sm,.input-group-sm>input[type="date"].form-control,.input-group-sm>input[type="date"].input-group-addon,.input-group-sm>.input-group-btn>input[type="date"].btn,.input-group-sm input[type="date"],input[type="time"].input-sm,.input-group-sm>input[type="time"].form-control,.input-group-sm>input[type="time"].input-group-addon,.input-group-sm>.input-group-btn>input[type="time"].btn,.input-group-sm input[type="time"],input[type="datetime-local"].input-sm,.input-group-sm>input[type="datetime-local"].form-control,.input-group-sm>input[type="datetime-local"].input-group-addon,.input-group-sm>.input-group-btn>input[type="datetime-local"].btn,.input-group-sm input[type="datetime-local"],input[type="month"].input-sm,.input-group-sm>input[type="month"].form-control,.input-group-sm>input[type="month"].input-group-addon,.input-group-sm>.input-group-btn>input[type="month"].btn,.input-group-sm input[type="month"]{line-height:30px}input[type="date"].input-lg,.input-group-lg>input[type="date"].form-control,.input-group-lg>input[type="date"].input-group-addon,.input-group-lg>.input-group-btn>input[type="date"].btn,.input-group-lg input[type="date"],input[type="time"].input-lg,.input-group-lg>input[type="time"].form-control,.input-group-lg>input[type="time"].input-group-addon,.input-group-lg>.input-group-btn>input[type="time"].btn,.input-group-lg input[type="time"],input[type="datetime-local"].input-lg,.input-group-lg>input[type="datetime-local"].form-control,.input-group-lg>input[type="datetime-local"].input-group-addon,.input-group-lg>.input-group-btn>input[type="datetime-local"].btn,.input-group-lg input[type="datetime-local"],input[type="month"].input-lg,.input-group-lg>input[type="month"].form-control,.input-group-lg>input[type="month"].input-group-addon,.input-group-lg>.input-group-btn>input[type="month"].btn,.input-group-lg input[type="month"]{line-height:46px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="radio"].disabled,fieldset[disabled] input[type="radio"],input[type="checkbox"][disabled],input[type="checkbox"].disabled,fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,fieldset[disabled] .radio-inline,.checkbox-inline.disabled,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,fieldset[disabled] .radio label,.checkbox.disabled label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0;min-height:34px}.form-control-static.input-lg,.input-group-lg>.form-control-static.form-control,.input-group-lg>.form-control-static.input-group-addon,.input-group-lg>.input-group-btn>.form-control-static.btn,.form-control-static.input-sm,.input-group-sm>.form-control-static.form-control,.input-group-sm>.form-control-static.input-group-addon,.input-group-sm>.input-group-btn>.form-control-static.btn{padding-left:0;padding-right:0}.input-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,.input-group-sm>select.form-control,.input-group-sm>select.input-group-addon,.input-group-sm>.input-group-btn>select.btn{height:30px;line-height:30px}textarea.input-sm,.input-group-sm>textarea.form-control,.input-group-sm>textarea.input-group-addon,.input-group-sm>.input-group-btn>textarea.btn,select[multiple].input-sm,.input-group-sm>select[multiple].form-control,.input-group-sm>select[multiple].input-group-addon,.input-group-sm>.input-group-btn>select[multiple].btn{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm textarea.form-control,.form-group-sm select[multiple].form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33333;border-radius:6px}select.input-lg,.input-group-lg>select.form-control,.input-group-lg>select.input-group-addon,.input-group-lg>.input-group-btn>select.btn{height:46px;line-height:46px}textarea.input-lg,.input-group-lg>textarea.form-control,.input-group-lg>textarea.input-group-addon,.input-group-lg>.input-group-btn>textarea.btn,select[multiple].input-lg,.input-group-lg>select[multiple].form-control,.input-group-lg>select[multiple].input-group-addon,.input-group-lg>.input-group-btn>select[multiple].btn{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg textarea.form-control,.form-group-lg select[multiple].form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.33333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback,.input-group-lg>.form-control+.form-control-feedback,.input-group-lg>.input-group-addon+.form-control-feedback,.input-group-lg>.input-group-btn>.btn+.form-control-feedback,.input-group-lg+.form-control-feedback,.form-group-lg .form-control+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback,.input-group-sm>.form-control+.form-control-feedback,.input-group-sm>.input-group-addon+.form-control-feedback,.input-group-sm>.input-group-btn>.btn+.form-control-feedback,.input-group-sm+.form-control-feedback,.form-group-sm .form-control+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;border-color:#3c763d;background-color:#dff0d8}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;border-color:#8a6d3b;background-color:#fcf8e3}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;border-color:#a94442;background-color:#f2dede}.has-error .form-control-feedback{color:#a94442}.has-feedback label ~ .form-control-feedback{top:25px}.has-feedback label.sr-only ~ .form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width: 768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}.form-horizontal .form-group:before,.form-horizontal .form-group:after{content:" ";display:table}.form-horizontal .form-group:after{clear:both}@media (min-width: 768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width: 768px){.form-horizontal .form-group-lg .control-label{padding-top:11px;font-size:18px}}@media (min-width: 768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group .form-control:focus{z-index:3}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:normal;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.input-group-addon.btn{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.input-group-addon.btn{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}@-webkit-keyframes ax-dialog{0%{opacity:0.0;-webkit-transform:scale(1)}1%{opacity:0.0;-webkit-transform:scale(0.3)}100%{opacity:1.0;-webkit-transform:scale(1)}}@-moz-keyframes ax-dialog{0%{opacity:0.0;-moz-transform:scale(1)}1%{opacity:0.0;-moz-transform:scale(0.3)}100%{opacity:1.0;-moz-transform:scale(1)}}@keyframes ax-dialog{0%{opacity:0.0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}1%{opacity:0.0;-webkit-transform:scale(0.3);-moz-transform:scale(0.3);-ms-transform:scale(0.3);-o-transform:scale(0.3);transform:scale(0.3)}100%{opacity:1.0;-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1)}}@-webkit-keyframes ax-dialog-destroy{from{-webkit-transform:scale(1);opacity:1.0}to{-webkit-transform:scale(0.5);opacity:0.0}}@-moz-keyframes ax-dialog-destroy{from{-moz-transform:scale(1);opacity:1.0}to{-moz-transform:scale(0.5);opacity:0.0}}@keyframes ax-dialog-destroy{from{-webkit-transform:scale(1);-moz-transform:scale(1);-ms-transform:scale(1);-o-transform:scale(1);transform:scale(1);opacity:1.0}to{-webkit-transform:scale(0.5);-moz-transform:scale(0.5);-ms-transform:scale(0.5);-o-transform:scale(0.5);transform:scale(0.5);opacity:0.0}}.ax5-ui-dialog{-webkit-animation:ax-dialog .15s cubic-bezier(0.645, 0.045, 0.355, 1);-o-animation:ax-dialog .15s cubic-bezier(0.645, 0.045, 0.355, 1);animation:ax-dialog .15s cubic-bezier(0.645, 0.045, 0.355, 1);-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);box-sizing:border-box;background-color:#fff;border:1px solid #ddd;border-radius:4px;box-shadow:0px 0px 3px 0px rgba(0,0,0,0.175);z-index:2000;position:fixed;left:0px;top:0px;overflow:hidden;border:1px solid #ddd}.ax5-ui-dialog .ax-dialog-header{font-weight:600;padding:10px 15px;border-bottom:1px solid transparent}.ax5-ui-dialog .ax-dialog-header .badge{font-size:0.8em;color:#f5f5f5;background-color:#333}.ax5-ui-dialog .ax-dialog-body{padding:15px;text-align:center}.ax5-ui-dialog .ax-dialog-body .ax-dialog-msg{padding-top:15px;padding-bottom:15px}.ax5-ui-dialog .ax-dialog-body .ax-dialog-prompt{text-align:left;padding-bottom:7.5px}.ax5-ui-dialog .ax-dialog-body .ax-dialog-buttons{margin-top:15px}.ax5-ui-dialog .ax-dialog-body .ax-dialog-buttons button:not(:last-child){margin-right:3px}.ax5-ui-dialog .ax-dialog-body [data-dialog-els="additional-content"]{margin-top:15px}.ax5-ui-dialog .ax-dialog-header{color:#333;background:#f5f5f5}.ax5-ui-dialog .ax-dialog-header .badge{color:#f5f5f5;background-color:#333}.ax5-ui-dialog.primary{border:1px solid #ddd}.ax5-ui-dialog.primary .ax-dialog-header{color:#fff;background:#337ab7}.ax5-ui-dialog.primary .ax-dialog-header .badge{color:#337ab7;background-color:#fff}.ax5-ui-dialog.success{border:1px solid #ddd}.ax5-ui-dialog.success .ax-dialog-header{color:#3c763d;background:#dff0d8}.ax5-ui-dialog.success .ax-dialog-header .badge{color:#dff0d8;background-color:#3c763d}.ax5-ui-dialog.info{border:1px solid #ddd}.ax5-ui-dialog.info .ax-dialog-header{color:#31708f;background:#d9edf7}.ax5-ui-dialog.info .ax-dialog-header .badge{color:#d9edf7;background-color:#31708f}.ax5-ui-dialog.warning{border:1px solid #ddd}.ax5-ui-dialog.warning .ax-dialog-header{color:#8a6d3b;background:#fcf8e3}.ax5-ui-dialog.warning .ax-dialog-header .badge{color:#fcf8e3;background-color:#8a6d3b}.ax5-ui-dialog.danger{border:1px solid #ddd}.ax5-ui-dialog.danger .ax-dialog-header{color:#a94442;background:#f2dede}.ax5-ui-dialog.danger .ax-dialog-header .badge{color:#f2dede;background-color:#a94442}.ax5-ui-dialog.destroy{-webkit-animation:ax-dialog-destroy .15s cubic-bezier(0.645, 0.045, 0.355, 1) forwards;-o-animation:ax-dialog-destroy .15s cubic-bezier(0.645, 0.045, 0.355, 1) forwards;animation:ax-dialog-destroy .15s cubic-bezier(0.645, 0.045, 0.355, 1) forwards} 10 | -------------------------------------------------------------------------------- /dist/ax5dialog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | // ax5.ui.dialog 4 | (function () { 5 | 6 | var UI = ax5.ui; 7 | var U = ax5.util; 8 | var DIALOG = void 0; 9 | 10 | UI.addClass({ 11 | className: "dialog" 12 | }, function () { 13 | /** 14 | * @class ax5dialog 15 | * @classdesc 16 | * @author tom@axisj.com 17 | * @example 18 | * ```js 19 | * var dialog = new ax5.ui.dialog(); 20 | * var mask = new ax5.ui.mask(); 21 | * dialog.setConfig({ 22 | * zIndex: 5000, 23 | * onStateChanged: function () { 24 | * if (this.state === "open") { 25 | * mask.open(); 26 | * } 27 | * else if (this.state === "close") { 28 | * mask.close(); 29 | * } 30 | * } 31 | * }); 32 | * 33 | * dialog.alert({ 34 | * theme: 'default', 35 | * title: 'Alert default', 36 | * msg: theme + ' color' 37 | * }, function () { 38 | * console.log(this); 39 | * }); 40 | * ``` 41 | */ 42 | var ax5dialog = function ax5dialog() { 43 | var self = this, 44 | cfg = void 0; 45 | 46 | this.instanceId = ax5.getGuid(); 47 | this.config = { 48 | id: 'ax5-dialog-' + this.instanceId, 49 | clickEventName: "click", //(('ontouchstart' in document.documentElement) ? "touchend" : "click"), 50 | theme: 'default', 51 | width: 300, 52 | title: '', 53 | msg: '', 54 | lang: { 55 | "ok": "ok", "cancel": "cancel" 56 | }, 57 | animateTime: 150, 58 | autoCloseTime: 0 59 | }; 60 | this.activeDialog = null; 61 | this.autoCloseTimer = null; 62 | this.queue = []; 63 | 64 | cfg = this.config; 65 | 66 | var onStateChanged = function onStateChanged(opts, that) { 67 | if (opts && opts.onStateChanged) { 68 | opts.onStateChanged.call(that, that); 69 | } else if (this.onStateChanged) { 70 | this.onStateChanged.call(that, that); 71 | } 72 | 73 | that = null; 74 | return true; 75 | }; 76 | /** 77 | * @private ax5dialog.getContent 78 | * @param {String} dialogId 79 | * @param {Object} opts 80 | * @returns dialogDisplay 81 | */ 82 | var getContent = function getContent(dialogId, opts) { 83 | 84 | var data = { 85 | dialogId: dialogId, 86 | title: opts.title || cfg.title || "", 87 | msg: (opts.msg || cfg.msg || "").replace(/\n/g, "
"), 88 | input: opts.input, 89 | btns: opts.btns, 90 | '_crlf': function _crlf() { 91 | return this.replace(/\n/g, "
"); 92 | }, 93 | additionalContent: function (additionalContent) { 94 | if (U.isFunction(additionalContent)) { 95 | return additionalContent.call(opts); 96 | } else { 97 | return additionalContent; 98 | } 99 | }(opts.additionalContent) 100 | }; 101 | 102 | try { 103 | return DIALOG.tmpl.get.call(this, "dialogDisplay", data); 104 | } finally { 105 | data = null; 106 | } 107 | }; 108 | /** 109 | * @private ax5dialog.open 110 | * @param {Object} opts 111 | * @param callback 112 | */ 113 | var open = function open(opts, callback) { 114 | var pos = {}, 115 | box = void 0; 116 | 117 | opts.id = opts.id || cfg.id; 118 | 119 | box = { 120 | width: opts.width 121 | }; 122 | jQuery(document.body).append(getContent.call(this, opts.id, opts)); 123 | 124 | this.dialogConfig = opts; 125 | this.activeDialog = jQuery('#' + opts.id); 126 | this.activeDialog.css({ width: box.width }); 127 | 128 | if (typeof callback === "undefined") { 129 | callback = opts.callback; 130 | } 131 | 132 | // dialog 높이 구하기 - 너비가 정해지면 높이가 변경 될 것. 133 | opts.height = box.height = this.activeDialog.height(); 134 | 135 | //- position 정렬 136 | if (typeof opts.position === "undefined" || opts.position === "center") { 137 | pos.top = jQuery(window).height() / 2 - box.height / 2; 138 | pos.left = jQuery(window).width() / 2 - box.width / 2; 139 | } else { 140 | pos.left = opts.position.left || 0; 141 | pos.top = opts.position.top || 0; 142 | } 143 | if (cfg.zIndex) { 144 | pos["z-index"] = cfg.zIndex; 145 | } 146 | this.activeDialog.css(pos); 147 | 148 | // bind button event 149 | if (opts.dialogType === "prompt") { 150 | this.activeDialog.find("[data-dialog-prompt]").get(0).focus(); 151 | } else { 152 | this.activeDialog.find("[data-dialog-btn]").get(0).focus(); 153 | } 154 | 155 | this.activeDialog.find("[data-dialog-btn]").on(cfg.clickEventName, function (e) { 156 | btnOnClick.call(this, e || window.event, opts, callback); 157 | }.bind(this)); 158 | 159 | // bind key event 160 | jQuery(window).bind("keydown.ax5dialog", function (e) { 161 | onKeyup.call(this, e || window.event, opts, callback); 162 | }.bind(this)); 163 | 164 | jQuery(window).bind("resize.ax5dialog", function (e) { 165 | align.call(this, e || window.event); 166 | }.bind(this)); 167 | 168 | onStateChanged.call(this, opts, { 169 | self: this, 170 | state: "open" 171 | }); 172 | 173 | if (opts.autoCloseTime) { 174 | this.autoCloseTimer = setTimeout(function () { 175 | self.close(); 176 | }, opts.autoCloseTime); 177 | } 178 | 179 | pos = null; 180 | box = null; 181 | }; 182 | var align = function align(e) { 183 | if (!this.activeDialog) return this; 184 | var opts = self.dialogConfig, 185 | box = { 186 | width: opts.width, 187 | height: opts.height 188 | }; 189 | 190 | //- position 정렬 191 | if (typeof opts.position === "undefined" || opts.position === "center") { 192 | box.top = window.innerHeight / 2 - box.height / 2; 193 | box.left = window.innerWidth / 2 - box.width / 2; 194 | } else { 195 | box.left = opts.position.left || 0; 196 | box.top = opts.position.top || 0; 197 | } 198 | if (box.left < 0) box.left = 0; 199 | if (box.top < 0) box.top = 0; 200 | 201 | this.activeDialog.css(box); 202 | 203 | opts = null; 204 | box = null; 205 | 206 | return this; 207 | }; 208 | var btnOnClick = function btnOnClick(e, opts, callback, target, k) { 209 | var that = void 0, 210 | emptyKey = null; 211 | 212 | if (e.srcElement) e.target = e.srcElement; 213 | 214 | target = U.findParentNode(e.target, function (target) { 215 | if (target.getAttribute("data-dialog-btn")) { 216 | return true; 217 | } 218 | }); 219 | 220 | if (target) { 221 | k = target.getAttribute("data-dialog-btn"); 222 | 223 | that = { 224 | self: this, 225 | key: k, value: opts.btns[k], 226 | dialogId: opts.id, 227 | btnTarget: target 228 | }; 229 | if (opts.dialogType === "prompt") { 230 | that.input = {}; 231 | for (var oi in opts.input) { 232 | that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val(); 233 | if (opts.input[oi].required && (that.input[oi] == "" || that.input[oi] == null)) { 234 | emptyKey = oi; 235 | break; 236 | } 237 | } 238 | } 239 | if (opts.btns[k].onClick) { 240 | opts.btns[k].onClick.call(that, k); 241 | } else if (opts.dialogType === "alert") { 242 | if (callback) callback.call(that, k); 243 | this.close({ doNotCallback: true }); 244 | } else if (opts.dialogType === "confirm") { 245 | if (callback) callback.call(that, k); 246 | this.close({ doNotCallback: true }); 247 | } else if (opts.dialogType === "prompt") { 248 | if (k === 'ok') { 249 | if (emptyKey) { 250 | this.activeDialog.find('[data-dialog-prompt="' + emptyKey + '"]').get(0).focus(); 251 | return false; 252 | } 253 | } 254 | if (callback) callback.call(that, k); 255 | this.close({ doNotCallback: true }); 256 | } 257 | } 258 | 259 | that = null; 260 | opts = null; 261 | callback = null; 262 | target = null; 263 | k = null; 264 | }; 265 | var onKeyup = function onKeyup(e, opts, callback, target, k) { 266 | var that = void 0, 267 | emptyKey = null; 268 | 269 | if (e.keyCode == ax5.info.eventKeys.ESC) { 270 | this.close(); 271 | } 272 | if (opts.dialogType === "prompt") { 273 | if (e.keyCode == ax5.info.eventKeys.RETURN) { 274 | that = { 275 | self: this, 276 | key: k, value: opts.btns[k], 277 | dialogId: opts.id, 278 | btnTarget: target 279 | }; 280 | that.input = {}; 281 | 282 | for (var oi in opts.input) { 283 | that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val(); 284 | if (opts.input[oi].required && (that.input[oi] == "" || that.input[oi] == null)) { 285 | emptyKey = oi; 286 | break; 287 | } 288 | } 289 | if (emptyKey) { 290 | that = null; 291 | emptyKey = null; 292 | return false; 293 | } 294 | if (callback) callback.call(that, k); 295 | this.close({ doNotCallback: true }); 296 | } 297 | } 298 | 299 | that = null; 300 | emptyKey = null; 301 | opts = null; 302 | callback = null; 303 | target = null; 304 | k = null; 305 | }; 306 | 307 | /** 308 | * Preferences of dialog UI 309 | * @method ax5dialog.setConfig 310 | * @param {Object} config - 클래스 속성값 311 | * @param {String} [config.theme="default"] 312 | * @param {Number} [config.width=300] 313 | * @param {String} [config.title=""] 314 | * @param {Number} [config.zIndex] 315 | * @param {Function} [config.onStateChanged] - `onStateChanged` function can be defined in setConfig method or new ax5.ui.dialog initialization method. However, you can us to define an 316 | * event function after initialization, if necessary 317 | * @param {Object} [config.lang] 318 | * @param {String} [config.lang.ok="ok"] 319 | * @param {String} [config.lang.cancel="cancel"] 320 | * @param {Number} [config.animateTime=150] 321 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 322 | * @returns {ax5dialog} 323 | * @example 324 | * ``` 325 | * var dialog = new ax5.ui.dialog(); 326 | * dialog.setConfig({ 327 | * title: "app dialog title", 328 | * zIndex: 5000, 329 | * onStateChanged: function () { 330 | * if (this.state === "open") { 331 | * mask.open(); 332 | * } 333 | * else if (this.state === "close") { 334 | * mask.close(); 335 | * } 336 | * } 337 | * }); 338 | * ``` 339 | */ 340 | //== class body start 341 | this.init = function () { 342 | this.onStateChanged = cfg.onStateChanged; 343 | // this.onLoad = cfg.onLoad; 344 | }; 345 | 346 | /** 347 | * open the dialog of alert type 348 | * @method ax5dialog.alert 349 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 350 | * @param {String} [config.theme="default"] 351 | * @param {Number} [config.width=300] 352 | * @param {String} [config.title=""] 353 | * @param {Number} [config.zIndex] 354 | * @param {Function} [config.onStateChanged] 355 | * @param {Object} [config.lang] 356 | * @param {String} [config.lang.ok="ok"] 357 | * @param {String} [config.lang.cancel="cancel"] 358 | * @param {Number} [config.animateTime=150] 359 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 360 | * @param {Function|String} [config.additionalContent] 361 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 362 | * @returns {ax5dialog} 363 | * @example 364 | * ``` 365 | * myDialog.alert({ 366 | * title: 'app title', 367 | * msg: 'alert' 368 | * }, function(){}); 369 | * ``` 370 | */ 371 | this.alert = function (opts, callback, tryCount) { 372 | if (U.isString(opts)) { 373 | opts = { 374 | title: cfg.title, 375 | msg: opts 376 | }; 377 | } 378 | 379 | opts = jQuery.extend(true, {}, cfg, opts); 380 | opts.dialogType = "alert"; 381 | opts.theme = opts.theme || cfg.theme || ""; 382 | opts.callback = callback; 383 | 384 | if (typeof opts.btns === "undefined") { 385 | opts.btns = { 386 | ok: { label: cfg.lang["ok"], theme: opts.theme } 387 | }; 388 | } 389 | 390 | if (this.activeDialog) { 391 | this.queue.push(opts); 392 | } else { 393 | open.call(this, opts, callback); 394 | } 395 | return this; 396 | }; 397 | 398 | /** 399 | * open the dialog of confirm type 400 | * @method ax5dialog.confirm 401 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 402 | * @param {String} [config.theme="default"] 403 | * @param {Number} [config.width=300] 404 | * @param {String} [config.title=""] 405 | * @param {Number} [config.zIndex] 406 | * @param {Function} [config.onStateChanged] 407 | * @param {Object} [config.lang] 408 | * @param {String} [config.lang.ok="ok"] 409 | * @param {String} [config.lang.cancel="cancel"] 410 | * @param {Number} [config.animateTime=150] 411 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 412 | * @param {Function|String} [config.additionalContent] 413 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 414 | * @returns {ax5dialog} 415 | * @example 416 | * ``` 417 | * myDialog.confirm({ 418 | * title: 'app title', 419 | * msg: 'confirm', 420 | * additionalContent: function () { 421 | * return "
추가정보
"; 422 | * } 423 | * }, function(){}); 424 | * ``` 425 | */ 426 | this.confirm = function (opts, callback, tryCount) { 427 | if (U.isString(opts)) { 428 | opts = { 429 | title: cfg.title, 430 | msg: opts 431 | }; 432 | } 433 | 434 | opts = jQuery.extend(true, {}, cfg, opts); 435 | opts.dialogType = "confirm"; 436 | opts.theme = opts.theme || cfg.theme || ""; 437 | opts.callback = callback; 438 | 439 | if (typeof opts.btns === "undefined") { 440 | opts.btns = { 441 | ok: { label: cfg.lang["ok"], theme: opts.theme }, 442 | cancel: { label: cfg.lang["cancel"] } 443 | }; 444 | } 445 | 446 | if (this.activeDialog) { 447 | this.queue.push(opts); 448 | } else { 449 | open.call(this, opts, callback); 450 | } 451 | 452 | return this; 453 | }; 454 | 455 | /** 456 | * open the dialog of prompt type 457 | * @method ax5dialog.prompt 458 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 459 | * @param {String} [config.theme="default"] 460 | * @param {Number} [config.width=300] 461 | * @param {String} [config.title=""] 462 | * @param {Number} [config.zIndex] 463 | * @param {Function} [config.onStateChanged] 464 | * @param {Object} [config.lang] 465 | * @param {String} [config.lang.ok="ok"] 466 | * @param {String} [config.lang.cancel="cancel"] 467 | * @param {Number} [config.animateTime=150] 468 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 469 | * @param {Function|String} [config.additionalContent] 470 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 471 | * @returns {ax5dialog} 472 | * @example 473 | * ``` 474 | * myDialog.prompt({ 475 | * title: 'app title', 476 | * msg: 'alert' 477 | * }, function(){}); 478 | * ``` 479 | */ 480 | this.prompt = function (opts, callback, tryCount) { 481 | if (U.isString(opts)) { 482 | opts = { 483 | title: cfg.title, 484 | msg: opts 485 | }; 486 | } 487 | 488 | opts = jQuery.extend(true, {}, cfg, opts); 489 | opts.dialogType = "prompt"; 490 | opts.theme = opts.theme || cfg.theme || ""; 491 | opts.callback = callback; 492 | 493 | if (typeof opts.input === "undefined") { 494 | opts.input = { 495 | value: { label: "" } 496 | }; 497 | } 498 | if (typeof opts.btns === "undefined") { 499 | opts.btns = { 500 | ok: { label: cfg.lang["ok"], theme: opts.theme }, 501 | cancel: { label: cfg.lang["cancel"] } 502 | }; 503 | } 504 | 505 | if (this.activeDialog) { 506 | this.queue.push(opts); 507 | } else { 508 | open.call(this, opts, callback); 509 | } 510 | 511 | return this; 512 | }; 513 | 514 | /** 515 | * close the dialog 516 | * @method ax5dialog.close 517 | * @returns {ax5dialog} 518 | * @example 519 | * ``` 520 | * myDialog.close(); 521 | * ``` 522 | */ 523 | this.close = function (_option) { 524 | var opts = void 0, 525 | that = void 0; 526 | 527 | if (this.activeDialog) { 528 | if (this.autoCloseTimer) clearTimeout(this.autoCloseTimer); 529 | 530 | opts = self.dialogConfig; 531 | 532 | this.activeDialog.addClass("destroy"); 533 | jQuery(window).unbind("keydown.ax5dialog"); 534 | jQuery(window).unbind("resize.ax5dialog"); 535 | 536 | setTimeout(function () { 537 | if (this.activeDialog) { 538 | this.activeDialog.remove(); 539 | this.activeDialog = null; 540 | } 541 | 542 | that = { 543 | self: this, 544 | state: "close", 545 | dialogId: opts.id 546 | }; 547 | 548 | if (opts.callback && (!_option || !_option.doNotCallback)) { 549 | opts.callback.call(that); 550 | } 551 | 552 | if (opts && opts.onStateChanged) { 553 | opts.onStateChanged.call(that, that); 554 | } else if (this.onStateChanged) { 555 | this.onStateChanged.call(that, that); 556 | } 557 | 558 | if (this.queue && this.queue.length) { 559 | open.call(this, this.queue.shift()); 560 | } 561 | 562 | opts = null; 563 | that = null; 564 | }.bind(this), cfg.animateTime); 565 | } 566 | return this; 567 | }; 568 | 569 | // 클래스 생성자 570 | this.main = function () { 571 | 572 | UI.dialog_instance = UI.dialog_instance || []; 573 | UI.dialog_instance.push(this); 574 | 575 | if (arguments && U.isObject(arguments[0])) { 576 | this.setConfig(arguments[0]); 577 | } 578 | }.apply(this, arguments); 579 | }; 580 | return ax5dialog; 581 | }()); 582 | 583 | DIALOG = ax5.ui.dialog; 584 | })(); 585 | 586 | // ax5.ui.dialog.tmpl 587 | (function () { 588 | 589 | var DIALOG = ax5.ui.dialog; 590 | 591 | var dialogDisplay = function dialogDisplay(columnKeys) { 592 | return " \n
\n
\n {{{title}}}\n
\n
\n
{{{msg}}}
\n \n {{#input}}\n
\n {{#@each}}\n
\n {{#@value.label}}\n \n {{/@value.label}}\n \n {{#@value.help}}\n

{{#_crlf}}{{.}}{{/_crlf}}

\n {{/@value.help}}\n
\n {{/@each}}\n
\n {{/input}}\n \n
\n
\n {{#btns}}\n {{#@each}}\n \n {{/@each}}\n {{/btns}}\n
\n
\n \n {{#additionalContent}}\n
{{{.}}}
\n {{/additionalContent}}\n
\n
\n "; 593 | }; 594 | 595 | DIALOG.tmpl = { 596 | "dialogDisplay": dialogDisplay, 597 | get: function get(tmplName, data, columnKeys) { 598 | return ax5.mustache.render(DIALOG.tmpl[tmplName].call(this, columnKeys), data); 599 | } 600 | }; 601 | })(); -------------------------------------------------------------------------------- /dist/ax5dialog.min.js: -------------------------------------------------------------------------------- 1 | "use strict";!function(){var t=ax5.ui,i=ax5.util,e=void 0;t.addClass({className:"dialog"},function(){var l=function(){var l=this,n=void 0;this.instanceId=ax5.getGuid(),this.config={id:"ax5-dialog-"+this.instanceId,clickEventName:"click",theme:"default",width:300,title:"",msg:"",lang:{ok:"ok",cancel:"cancel"},animateTime:150,autoCloseTime:0},this.activeDialog=null,this.autoCloseTimer=null,this.queue=[],n=this.config;var a=function(t,i){return t&&t.onStateChanged?t.onStateChanged.call(i,i):this.onStateChanged&&this.onStateChanged.call(i,i),i=null,!0},o=function(t,l){var a={dialogId:t,title:l.title||n.title||"",msg:(l.msg||n.msg||"").replace(/\n/g,"
"),input:l.input,btns:l.btns,_crlf:function(){return this.replace(/\n/g,"
")},additionalContent:function(t){return i.isFunction(t)?t.call(l):t}(l.additionalContent)};try{return e.tmpl.get.call(this,"dialogDisplay",a)}finally{a=null}},d=function(t,i){var e={},d=void 0;t.id=t.id||n.id,d={width:t.width},jQuery(document.body).append(o.call(this,t.id,t)),this.dialogConfig=t,this.activeDialog=jQuery("#"+t.id),this.activeDialog.css({width:d.width}),"undefined"==typeof i&&(i=t.callback),t.height=d.height=this.activeDialog.height(),"undefined"==typeof t.position||"center"===t.position?(e.top=jQuery(window).height()/2-d.height/2,e.left=jQuery(window).width()/2-d.width/2):(e.left=t.position.left||0,e.top=t.position.top||0),n.zIndex&&(e["z-index"]=n.zIndex),this.activeDialog.css(e),"prompt"===t.dialogType?this.activeDialog.find("[data-dialog-prompt]").get(0).focus():this.activeDialog.find("[data-dialog-btn]").get(0).focus(),this.activeDialog.find("[data-dialog-btn]").on(n.clickEventName,function(e){u.call(this,e||window.event,t,i)}.bind(this)),jQuery(window).bind("keydown.ax5dialog",function(e){c.call(this,e||window.event,t,i)}.bind(this)),jQuery(window).bind("resize.ax5dialog",function(t){s.call(this,t||window.event)}.bind(this)),a.call(this,t,{self:this,state:"open"}),t.autoCloseTime&&(this.autoCloseTimer=setTimeout(function(){l.close()},t.autoCloseTime)),e=null,d=null},s=function(t){if(!this.activeDialog)return this;var i=l.dialogConfig,e={width:i.width,height:i.height};return"undefined"==typeof i.position||"center"===i.position?(e.top=window.innerHeight/2-e.height/2,e.left=window.innerWidth/2-e.width/2):(e.left=i.position.left||0,e.top=i.position.top||0),e.left<0&&(e.left=0),e.top<0&&(e.top=0),this.activeDialog.css(e),i=null,e=null,this},u=function(t,e,l,n,a){var o=void 0,d=null;if(t.srcElement&&(t.target=t.srcElement),n=i.findParentNode(t.target,function(t){if(t.getAttribute("data-dialog-btn"))return!0})){if(a=n.getAttribute("data-dialog-btn"),o={self:this,key:a,value:e.btns[a],dialogId:e.id,btnTarget:n},"prompt"===e.dialogType){o.input={};for(var s in e.input)if(o.input[s]=this.activeDialog.find("[data-dialog-prompt="+s+"]").val(),e.input[s].required&&(""==o.input[s]||null==o.input[s])){d=s;break}}if(e.btns[a].onClick)e.btns[a].onClick.call(o,a);else if("alert"===e.dialogType)l&&l.call(o,a),this.close({doNotCallback:!0});else if("confirm"===e.dialogType)l&&l.call(o,a),this.close({doNotCallback:!0});else if("prompt"===e.dialogType){if("ok"===a&&d)return this.activeDialog.find('[data-dialog-prompt="'+d+'"]').get(0).focus(),!1;l&&l.call(o,a),this.close({doNotCallback:!0})}}o=null,e=null,l=null,n=null,a=null},c=function(t,i,e,l,n){var a=void 0,o=null;if(t.keyCode==ax5.info.eventKeys.ESC&&this.close(),"prompt"===i.dialogType&&t.keyCode==ax5.info.eventKeys.RETURN){a={self:this,key:n,value:i.btns[n],dialogId:i.id,btnTarget:l},a.input={};for(var d in i.input)if(a.input[d]=this.activeDialog.find("[data-dialog-prompt="+d+"]").val(),i.input[d].required&&(""==a.input[d]||null==a.input[d])){o=d;break}if(o)return a=null,o=null,!1;e&&e.call(a,n),this.close({doNotCallback:!0})}a=null,o=null,i=null,e=null,l=null,n=null};this.init=function(){this.onStateChanged=n.onStateChanged},this.alert=function(t,e,l){return i.isString(t)&&(t={title:n.title,msg:t}),t=jQuery.extend(!0,{},n,t),t.dialogType="alert",t.theme=t.theme||n.theme||"",t.callback=e,"undefined"==typeof t.btns&&(t.btns={ok:{label:n.lang.ok,theme:t.theme}}),this.activeDialog?this.queue.push(t):d.call(this,t,e),this},this.confirm=function(t,e,l){return i.isString(t)&&(t={title:n.title,msg:t}),t=jQuery.extend(!0,{},n,t),t.dialogType="confirm",t.theme=t.theme||n.theme||"",t.callback=e,"undefined"==typeof t.btns&&(t.btns={ok:{label:n.lang.ok,theme:t.theme},cancel:{label:n.lang.cancel}}),this.activeDialog?this.queue.push(t):d.call(this,t,e),this},this.prompt=function(t,e,l){return i.isString(t)&&(t={title:n.title,msg:t}),t=jQuery.extend(!0,{},n,t),t.dialogType="prompt",t.theme=t.theme||n.theme||"",t.callback=e,"undefined"==typeof t.input&&(t.input={value:{label:""}}),"undefined"==typeof t.btns&&(t.btns={ok:{label:n.lang.ok,theme:t.theme},cancel:{label:n.lang.cancel}}),this.activeDialog?this.queue.push(t):d.call(this,t,e),this},this.close=function(t){var i=void 0,e=void 0;return this.activeDialog&&(this.autoCloseTimer&&clearTimeout(this.autoCloseTimer),i=l.dialogConfig,this.activeDialog.addClass("destroy"),jQuery(window).unbind("keydown.ax5dialog"),jQuery(window).unbind("resize.ax5dialog"),setTimeout(function(){this.activeDialog&&(this.activeDialog.remove(),this.activeDialog=null),e={self:this,state:"close",dialogId:i.id},!i.callback||t&&t.doNotCallback||i.callback.call(e),i&&i.onStateChanged?i.onStateChanged.call(e,e):this.onStateChanged&&this.onStateChanged.call(e,e),this.queue&&this.queue.length&&d.call(this,this.queue.shift()),i=null,e=null}.bind(this),n.animateTime)),this},this.main=function(){t.dialog_instance=t.dialog_instance||[],t.dialog_instance.push(this),arguments&&i.isObject(arguments[0])&&this.setConfig(arguments[0])}.apply(this,arguments)};return l}()),e=ax5.ui.dialog}(),function(){var t=ax5.ui.dialog,i=function(t){return' \n
\n
\n {{{title}}}\n
\n
\n
{{{msg}}}
\n \n {{#input}}\n
\n {{#@each}}\n
\n {{#@value.label}}\n \n {{/@value.label}}\n \n {{#@value.help}}\n

{{#_crlf}}{{.}}{{/_crlf}}

\n {{/@value.help}}\n
\n {{/@each}}\n
\n {{/input}}\n \n
\n
\n {{#btns}}\n {{#@each}}\n \n {{/@each}}\n {{/btns}}\n
\n
\n \n {{#additionalContent}}\n
{{{.}}}
\n {{/additionalContent}}\n
\n
\n '};t.tmpl={dialogDisplay:i,get:function(i,e,l){return ax5.mustache.render(t.tmpl[i].call(this,l),e)}}}(); 2 | //# sourceMappingURL=ax5dialog.min.js.map 3 | -------------------------------------------------------------------------------- /dist/ax5dialog.min.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["ax5dialog.js","ax5dialog-tmpl.js"],"names":["UI","ax5","ui","U","util","DIALOG","addClass","className","ax5dialog","self","this","cfg","instanceId","getGuid","config","id","clickEventName","theme","width","title","msg","lang","ok","cancel","animateTime","autoCloseTime","activeDialog","autoCloseTimer","queue","onStateChanged","opts","that","call","getContent","dialogId","data","replace","input","btns","_crlf","additionalContent","isFunction","tmpl","get","open","callback","pos","box","jQuery","document","body","append","dialogConfig","css","height","position","top","window","left","zIndex","dialogType","find","focus","on","e","btnOnClick","event","bind","onKeyup","align","state","setTimeout","close","innerHeight","innerWidth","target","k","emptyKey","srcElement","findParentNode","getAttribute","key","value","btnTarget","oi","val","required","onClick","doNotCallback","keyCode","info","eventKeys","ESC","RETURN","init","alert","tryCount","isString","extend","label","push","confirm","prompt","_option","clearTimeout","unbind","remove","length","shift","main","dialog_instance","arguments","isObject","setConfig","apply","dialog","dialogDisplay","columnKeys","tmplName","mustache","render"],"mappings":"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","file":"ax5dialog.min.js","sourcesContent":["// ax5.ui.dialog\n(function () {\n\n let UI = ax5.ui;\n let U = ax5.util;\n let DIALOG;\n\n UI.addClass({\n className: \"dialog\"\n }, (function () {\n /**\n * @class ax5dialog\n * @classdesc\n * @author tom@axisj.com\n * @example\n * ```js\n * var dialog = new ax5.ui.dialog();\n * var mask = new ax5.ui.mask();\n * dialog.setConfig({\n * zIndex: 5000,\n * onStateChanged: function () {\n * if (this.state === \"open\") {\n * mask.open();\n * }\n * else if (this.state === \"close\") {\n * mask.close();\n * }\n * }\n * });\n *\n * dialog.alert({\n * theme: 'default',\n * title: 'Alert default',\n * msg: theme + ' color'\n * }, function () {\n * console.log(this);\n * });\n * ```\n */\n let ax5dialog = function () {\n let self = this, cfg;\n\n this.instanceId = ax5.getGuid();\n this.config = {\n id: 'ax5-dialog-' + this.instanceId,\n clickEventName: \"click\", //(('ontouchstart' in document.documentElement) ? \"touchend\" : \"click\"),\n theme: 'default',\n width: 300,\n title: '',\n msg: '',\n lang: {\n \"ok\": \"ok\", \"cancel\": \"cancel\"\n },\n animateTime: 150,\n autoCloseTime: 0\n };\n this.activeDialog = null;\n this.autoCloseTimer = null;\n this.queue = [];\n\n cfg = this.config;\n\n const onStateChanged = function (opts, that) {\n if (opts && opts.onStateChanged) {\n opts.onStateChanged.call(that, that);\n }\n else if (this.onStateChanged) {\n this.onStateChanged.call(that, that);\n }\n\n that = null;\n return true;\n };\n /**\n * @private ax5dialog.getContent\n * @param {String} dialogId\n * @param {Object} opts\n * @returns dialogDisplay\n */\n const getContent = function (dialogId, opts) {\n\n let data = {\n dialogId: dialogId,\n title: (opts.title || cfg.title || \"\"),\n msg: (opts.msg || cfg.msg || \"\").replace(/\\n/g, \"
\"),\n input: opts.input,\n btns: opts.btns,\n '_crlf': function () {\n return this.replace(/\\n/g, \"
\");\n },\n additionalContent: (function (additionalContent) {\n if (U.isFunction(additionalContent)) {\n return additionalContent.call(opts);\n }\n else {\n return additionalContent;\n }\n })(opts.additionalContent)\n };\n\n try {\n return DIALOG.tmpl.get.call(this, \"dialogDisplay\", data);\n }\n finally {\n data = null;\n }\n };\n /**\n * @private ax5dialog.open\n * @param {Object} opts\n * @param callback\n */\n const open = function (opts, callback) {\n let pos = {}, box;\n\n opts.id = (opts.id || cfg.id);\n\n box = {\n width: opts.width\n };\n jQuery(document.body).append(getContent.call(this, opts.id, opts));\n\n this.dialogConfig = opts;\n this.activeDialog = jQuery('#' + opts.id);\n this.activeDialog.css({width: box.width});\n\n if (typeof callback === \"undefined\") {\n callback = opts.callback;\n }\n\n // dialog 높이 구하기 - 너비가 정해지면 높이가 변경 될 것.\n opts.height = box.height = this.activeDialog.height();\n\n //- position 정렬\n if (typeof opts.position === \"undefined\" || opts.position === \"center\") {\n pos.top = jQuery(window).height() / 2 - box.height / 2;\n pos.left = jQuery(window).width() / 2 - box.width / 2;\n }\n else {\n pos.left = opts.position.left || 0;\n pos.top = opts.position.top || 0;\n }\n if (cfg.zIndex) {\n pos[\"z-index\"] = cfg.zIndex;\n }\n this.activeDialog.css(pos);\n\n // bind button event\n if (opts.dialogType === \"prompt\") {\n this.activeDialog.find(\"[data-dialog-prompt]\").get(0).focus();\n }\n else {\n this.activeDialog.find(\"[data-dialog-btn]\").get(0).focus();\n }\n\n this.activeDialog.find(\"[data-dialog-btn]\").on(cfg.clickEventName, (function (e) {\n btnOnClick.call(this, e || window.event, opts, callback);\n }).bind(this));\n\n // bind key event\n jQuery(window).bind(\"keydown.ax5dialog\", (function (e) {\n onKeyup.call(this, e || window.event, opts, callback);\n }).bind(this));\n\n jQuery(window).bind(\"resize.ax5dialog\", (function (e) {\n align.call(this, e || window.event);\n }).bind(this));\n\n onStateChanged.call(this, opts, {\n self: this,\n state: \"open\"\n });\n\n if (opts.autoCloseTime) {\n this.autoCloseTimer = setTimeout(function () {\n self.close();\n }, opts.autoCloseTime);\n }\n\n pos = null;\n box = null;\n };\n const align = function (e) {\n if (!this.activeDialog) return this;\n let opts = self.dialogConfig,\n box = {\n width: opts.width,\n height: opts.height\n };\n\n //- position 정렬\n if (typeof opts.position === \"undefined\" || opts.position === \"center\") {\n box.top = window.innerHeight / 2 - box.height / 2;\n box.left = window.innerWidth / 2 - box.width / 2;\n }\n else {\n box.left = opts.position.left || 0;\n box.top = opts.position.top || 0;\n }\n if (box.left < 0) box.left = 0;\n if (box.top < 0) box.top = 0;\n\n this.activeDialog.css(box);\n\n opts = null;\n box = null;\n\n return this;\n };\n const btnOnClick = function (e, opts, callback, target, k) {\n let that,\n emptyKey = null;\n\n if (e.srcElement) e.target = e.srcElement;\n\n target = U.findParentNode(e.target, function (target) {\n if (target.getAttribute(\"data-dialog-btn\")) {\n return true;\n }\n });\n\n if (target) {\n k = target.getAttribute(\"data-dialog-btn\");\n\n that = {\n self: this,\n key: k, value: opts.btns[k],\n dialogId: opts.id,\n btnTarget: target\n };\n if (opts.dialogType === \"prompt\") {\n that.input = {};\n for (let oi in opts.input) {\n that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val();\n if (opts.input[oi].required && (that.input[oi] == \"\" || that.input[oi] == null)) {\n emptyKey = oi;\n break;\n }\n }\n }\n if (opts.btns[k].onClick) {\n opts.btns[k].onClick.call(that, k);\n }\n else if (opts.dialogType === \"alert\") {\n if (callback) callback.call(that, k);\n this.close({doNotCallback: true});\n }\n else if (opts.dialogType === \"confirm\") {\n if (callback) callback.call(that, k);\n this.close({doNotCallback: true});\n }\n else if (opts.dialogType === \"prompt\") {\n if (k === 'ok') {\n if (emptyKey) {\n this.activeDialog.find('[data-dialog-prompt=\"' + emptyKey + '\"]').get(0).focus();\n return false;\n }\n }\n if (callback) callback.call(that, k);\n this.close({doNotCallback: true});\n }\n }\n\n that = null;\n opts = null;\n callback = null;\n target = null;\n k = null;\n };\n const onKeyup = function (e, opts, callback, target, k) {\n let that,\n emptyKey = null;\n\n if (e.keyCode == ax5.info.eventKeys.ESC) {\n this.close();\n }\n if (opts.dialogType === \"prompt\") {\n if (e.keyCode == ax5.info.eventKeys.RETURN) {\n that = {\n self: this,\n key: k, value: opts.btns[k],\n dialogId: opts.id,\n btnTarget: target\n };\n that.input = {};\n\n for (let oi in opts.input) {\n that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val();\n if (opts.input[oi].required && (that.input[oi] == \"\" || that.input[oi] == null)) {\n emptyKey = oi;\n break;\n }\n }\n if (emptyKey) {\n that = null;\n emptyKey = null;\n return false;\n }\n if (callback) callback.call(that, k);\n this.close({doNotCallback: true});\n }\n }\n\n that = null;\n emptyKey = null;\n opts = null;\n callback = null;\n target = null;\n k = null;\n };\n\n /**\n * Preferences of dialog UI\n * @method ax5dialog.setConfig\n * @param {Object} config - 클래스 속성값\n * @param {String} [config.theme=\"default\"]\n * @param {Number} [config.width=300]\n * @param {String} [config.title=\"\"]\n * @param {Number} [config.zIndex]\n * @param {Function} [config.onStateChanged] - `onStateChanged` function can be defined in setConfig method or new ax5.ui.dialog initialization method. However, you can us to define an\n * event function after initialization, if necessary\n * @param {Object} [config.lang]\n * @param {String} [config.lang.ok=\"ok\"]\n * @param {String} [config.lang.cancel=\"cancel\"]\n * @param {Number} [config.animateTime=150]\n * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close\n * @returns {ax5dialog}\n * @example\n * ```\n * var dialog = new ax5.ui.dialog();\n * dialog.setConfig({\n * title: \"app dialog title\",\n * zIndex: 5000,\n * onStateChanged: function () {\n * if (this.state === \"open\") {\n * mask.open();\n * }\n * else if (this.state === \"close\") {\n * mask.close();\n * }\n * }\n * });\n * ```\n */\n //== class body start\n this.init = function () {\n this.onStateChanged = cfg.onStateChanged;\n // this.onLoad = cfg.onLoad;\n\n };\n\n /**\n * open the dialog of alert type\n * @method ax5dialog.alert\n * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달\n * @param {String} [config.theme=\"default\"]\n * @param {Number} [config.width=300]\n * @param {String} [config.title=\"\"]\n * @param {Number} [config.zIndex]\n * @param {Function} [config.onStateChanged]\n * @param {Object} [config.lang]\n * @param {String} [config.lang.ok=\"ok\"]\n * @param {String} [config.lang.cancel=\"cancel\"]\n * @param {Number} [config.animateTime=150]\n * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close\n * @param {Function|String} [config.additionalContent]\n * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수\n * @returns {ax5dialog}\n * @example\n * ```\n * myDialog.alert({\n * title: 'app title',\n * msg: 'alert'\n * }, function(){});\n * ```\n */\n this.alert = function (opts, callback, tryCount) {\n if (U.isString(opts)) {\n opts = {\n title: cfg.title,\n msg: opts\n }\n }\n\n opts = jQuery.extend(true, {}, cfg, opts);\n opts.dialogType = \"alert\";\n opts.theme = (opts.theme || cfg.theme || \"\");\n opts.callback = callback;\n\n if (typeof opts.btns === \"undefined\") {\n opts.btns = {\n ok: {label: cfg.lang[\"ok\"], theme: opts.theme}\n };\n }\n\n if (this.activeDialog) {\n this.queue.push(opts);\n } else {\n open.call(this, opts, callback);\n }\n return this;\n };\n\n /**\n * open the dialog of confirm type\n * @method ax5dialog.confirm\n * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달\n * @param {String} [config.theme=\"default\"]\n * @param {Number} [config.width=300]\n * @param {String} [config.title=\"\"]\n * @param {Number} [config.zIndex]\n * @param {Function} [config.onStateChanged]\n * @param {Object} [config.lang]\n * @param {String} [config.lang.ok=\"ok\"]\n * @param {String} [config.lang.cancel=\"cancel\"]\n * @param {Number} [config.animateTime=150]\n * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close\n * @param {Function|String} [config.additionalContent]\n * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수\n * @returns {ax5dialog}\n * @example\n * ```\n * myDialog.confirm({\n * title: 'app title',\n * msg: 'confirm',\n * additionalContent: function () {\n * return \"
추가정보
\";\n * }\n * }, function(){});\n * ```\n */\n this.confirm = function (opts, callback, tryCount) {\n if (U.isString(opts)) {\n opts = {\n title: cfg.title,\n msg: opts\n }\n }\n\n opts = jQuery.extend(true, {}, cfg, opts);\n opts.dialogType = \"confirm\";\n opts.theme = (opts.theme || cfg.theme || \"\");\n opts.callback = callback;\n\n if (typeof opts.btns === \"undefined\") {\n opts.btns = {\n ok: {label: cfg.lang[\"ok\"], theme: opts.theme},\n cancel: {label: cfg.lang[\"cancel\"]}\n };\n }\n\n if (this.activeDialog) {\n this.queue.push(opts);\n } else {\n open.call(this, opts, callback);\n }\n\n return this;\n };\n\n /**\n * open the dialog of prompt type\n * @method ax5dialog.prompt\n * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달\n * @param {String} [config.theme=\"default\"]\n * @param {Number} [config.width=300]\n * @param {String} [config.title=\"\"]\n * @param {Number} [config.zIndex]\n * @param {Function} [config.onStateChanged]\n * @param {Object} [config.lang]\n * @param {String} [config.lang.ok=\"ok\"]\n * @param {String} [config.lang.cancel=\"cancel\"]\n * @param {Number} [config.animateTime=150]\n * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close\n * @param {Function|String} [config.additionalContent]\n * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수\n * @returns {ax5dialog}\n * @example\n * ```\n * myDialog.prompt({\n * title: 'app title',\n * msg: 'alert'\n * }, function(){});\n * ```\n */\n this.prompt = function (opts, callback, tryCount) {\n if (U.isString(opts)) {\n opts = {\n title: cfg.title,\n msg: opts\n }\n }\n\n opts = jQuery.extend(true, {}, cfg, opts);\n opts.dialogType = \"prompt\";\n opts.theme = (opts.theme || cfg.theme || \"\");\n opts.callback = callback;\n\n if (typeof opts.input === \"undefined\") {\n opts.input = {\n value: {label: \"\"}\n };\n }\n if (typeof opts.btns === \"undefined\") {\n opts.btns = {\n ok: {label: cfg.lang[\"ok\"], theme: opts.theme},\n cancel: {label: cfg.lang[\"cancel\"]}\n };\n }\n\n if (this.activeDialog) {\n this.queue.push(opts);\n } else {\n open.call(this, opts, callback);\n }\n\n return this;\n };\n\n /**\n * close the dialog\n * @method ax5dialog.close\n * @returns {ax5dialog}\n * @example\n * ```\n * myDialog.close();\n * ```\n */\n this.close = function (_option) {\n let opts, that;\n\n if (this.activeDialog) {\n if (this.autoCloseTimer) clearTimeout(this.autoCloseTimer);\n\n opts = self.dialogConfig;\n\n this.activeDialog.addClass(\"destroy\");\n jQuery(window).unbind(\"keydown.ax5dialog\");\n jQuery(window).unbind(\"resize.ax5dialog\");\n\n setTimeout((function () {\n if (this.activeDialog) {\n this.activeDialog.remove();\n this.activeDialog = null;\n }\n\n that = {\n self: this,\n state: \"close\",\n dialogId: opts.id\n };\n\n if (opts.callback && (!_option || !_option.doNotCallback)) {\n opts.callback.call(that);\n }\n\n if (opts && opts.onStateChanged) {\n opts.onStateChanged.call(that, that);\n }\n else if (this.onStateChanged) {\n this.onStateChanged.call(that, that);\n }\n\n if (this.queue && this.queue.length) {\n open.call(this, this.queue.shift());\n }\n\n opts = null;\n that = null;\n }).bind(this), cfg.animateTime);\n }\n return this;\n };\n\n // 클래스 생성자\n this.main = (function () {\n\n UI.dialog_instance = UI.dialog_instance || [];\n UI.dialog_instance.push(this);\n\n if (arguments && U.isObject(arguments[0])) {\n this.setConfig(arguments[0]);\n }\n }).apply(this, arguments);\n };\n return ax5dialog;\n })());\n\n DIALOG = ax5.ui.dialog;\n})();\n","// ax5.ui.dialog.tmpl\n(function () {\n\n var DIALOG = ax5.ui.dialog;\n\n var dialogDisplay = function(columnKeys) {\n return ` \n
\n
\n {{{title}}}\n
\n
\n
{{{msg}}}
\n \n {{#input}}\n
\n {{#@each}}\n
\n {{#@value.label}}\n \n {{/@value.label}}\n \n {{#@value.help}}\n

{{#_crlf}}{{.}}{{/_crlf}}

\n {{/@value.help}}\n
\n {{/@each}}\n
\n {{/input}}\n \n
\n
\n {{#btns}}\n {{#@each}}\n \n {{/@each}}\n {{/btns}}\n
\n
\n \n {{#additionalContent}}\n
{{{.}}}
\n {{/additionalContent}}\n
\n
\n `;\n };\n\n DIALOG.tmpl = {\n \"dialogDisplay\": dialogDisplay,\n get: function (tmplName, data, columnKeys) {\n return ax5.mustache.render(DIALOG.tmpl[tmplName].call(this, columnKeys), data);\n }\n };\n\n})();"]} -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016. tom@axisj.com 3 | * - github.com/thomasjang 4 | * - www.axisj.com 5 | */ 6 | 7 | // Karma configuration 8 | // Generated on Wed Sep 21 2016 00:37:04 GMT+0900 (KST) 9 | 10 | module.exports = function (config) { 11 | var configuration = { 12 | // base path that will be used to resolve all patterns (eg. files, exclude) 13 | basePath: '', 14 | 15 | // frameworks to use 16 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter 17 | frameworks: ['mocha'], 18 | 19 | // list of files / patterns to load in the browser 20 | files: [ 21 | 'https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js', 22 | 'https://cdnjs.cloudflare.com/ajax/libs/should.js/11.1.2/should.min.js', 23 | 'https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js', 24 | 'https://cdn.rawgit.com/ax5ui/ax5core/master/dist/ax5core.min.js', 25 | 'dist/ax5dialog.js', 26 | 'test/test.*.js' 27 | ], 28 | // list of files to exclude 29 | exclude: [], 30 | // preprocess matching files before serving them to the browser 31 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor 32 | preprocessors: {}, 33 | // test results reporter to use 34 | // possible values: 'dots', 'progress' 35 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter 36 | reporters: ['progress'], 37 | // web server port 38 | port: 9876, 39 | // enable / disable colors in the output (reporters and logs) 40 | colors: true, 41 | // level of logging 42 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 43 | logLevel: config.LOG_INFO, 44 | // enable / disable watching file and executing tests whenever any file changes 45 | autoWatch: true, 46 | // start these browsers 47 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher 48 | //browsers: ['Chrome', 'Firefox', 'PhantomJS'], 49 | browsers: ['Chrome', 'Firefox', 'PhantomJS'], 50 | customLaunchers: { 51 | Chrome_travis_ci: { 52 | base: 'Chrome', 53 | flags: ['--no-sandbox'] 54 | } 55 | }, 56 | singleRun: true, 57 | concurrency: Infinity 58 | }; 59 | 60 | if (process.env.TRAVIS) { 61 | configuration.browsers = ['PhantomJS']; 62 | } 63 | 64 | config.set(configuration); 65 | } 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-dialog", 3 | "version": "1.4.131", 4 | "description": "A dialog plugin that works with Bootstrap & jQuery", 5 | "license": "MIT", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/ax5ui/ax5ui-dialog" 9 | }, 10 | "author": { 11 | "name": "Thomas Jang", 12 | "email": "tom@axisj.com", 13 | "url": "ax5.io" 14 | }, 15 | "scripts": { 16 | "test": "karma start karma.conf.js" 17 | }, 18 | "keywords": [ 19 | "bootstrap", 20 | "jquery", 21 | "ax5ui", 22 | "plugin", 23 | "bootstrap jQuery plugins", 24 | "dialog", 25 | "ax5ui-dialog", 26 | "javascript ui" 27 | ], 28 | "dependencies": { 29 | "jquery": "", 30 | "ax5core": ">=1.4.115" 31 | }, 32 | "devDependencies": { 33 | "karma": "^1.3.0", 34 | "karma-mocha": "^1.2.0", 35 | "karma-phantomjs-launcher": "^1.0.2", 36 | "mocha": "^3.1.0", 37 | "phantomjs-prebuilt": "^2.1.13", 38 | "webdriverio": "^4.6.1" 39 | } 40 | } -------------------------------------------------------------------------------- /src/ax5dialog.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.dialog 2 | (function () { 3 | 4 | let UI = ax5.ui; 5 | let U = ax5.util; 6 | let DIALOG; 7 | 8 | UI.addClass({ 9 | className: "dialog" 10 | }, (function () { 11 | /** 12 | * @class ax5dialog 13 | * @classdesc 14 | * @author tom@axisj.com 15 | * @example 16 | * ```js 17 | * var dialog = new ax5.ui.dialog(); 18 | * var mask = new ax5.ui.mask(); 19 | * dialog.setConfig({ 20 | * zIndex: 5000, 21 | * onStateChanged: function () { 22 | * if (this.state === "open") { 23 | * mask.open(); 24 | * } 25 | * else if (this.state === "close") { 26 | * mask.close(); 27 | * } 28 | * } 29 | * }); 30 | * 31 | * dialog.alert({ 32 | * theme: 'default', 33 | * title: 'Alert default', 34 | * msg: theme + ' color' 35 | * }, function () { 36 | * console.log(this); 37 | * }); 38 | * ``` 39 | */ 40 | let ax5dialog = function () { 41 | let self = this, cfg; 42 | 43 | this.instanceId = ax5.getGuid(); 44 | this.config = { 45 | id: 'ax5-dialog-' + this.instanceId, 46 | clickEventName: "click", //(('ontouchstart' in document.documentElement) ? "touchend" : "click"), 47 | theme: 'default', 48 | width: 300, 49 | title: '', 50 | msg: '', 51 | lang: { 52 | "ok": "ok", "cancel": "cancel" 53 | }, 54 | animateTime: 150, 55 | autoCloseTime: 0 56 | }; 57 | this.activeDialog = null; 58 | this.autoCloseTimer = null; 59 | this.queue = []; 60 | 61 | cfg = this.config; 62 | 63 | const onStateChanged = function (opts, that) { 64 | if (opts && opts.onStateChanged) { 65 | opts.onStateChanged.call(that, that); 66 | } 67 | else if (this.onStateChanged) { 68 | this.onStateChanged.call(that, that); 69 | } 70 | 71 | that = null; 72 | return true; 73 | }; 74 | /** 75 | * @private ax5dialog.getContent 76 | * @param {String} dialogId 77 | * @param {Object} opts 78 | * @returns dialogDisplay 79 | */ 80 | const getContent = function (dialogId, opts) { 81 | 82 | let data = { 83 | dialogId: dialogId, 84 | title: (opts.title || cfg.title || ""), 85 | msg: (opts.msg || cfg.msg || "").replace(/\n/g, "
"), 86 | input: opts.input, 87 | btns: opts.btns, 88 | '_crlf': function () { 89 | return this.replace(/\n/g, "
"); 90 | }, 91 | additionalContent: (function (additionalContent) { 92 | if (U.isFunction(additionalContent)) { 93 | return additionalContent.call(opts); 94 | } 95 | else { 96 | return additionalContent; 97 | } 98 | })(opts.additionalContent) 99 | }; 100 | 101 | try { 102 | return DIALOG.tmpl.get.call(this, "dialogDisplay", data); 103 | } 104 | finally { 105 | data = null; 106 | } 107 | }; 108 | /** 109 | * @private ax5dialog.open 110 | * @param {Object} opts 111 | * @param callback 112 | */ 113 | const open = function (opts, callback) { 114 | let pos = {}, box; 115 | 116 | opts.id = (opts.id || cfg.id); 117 | 118 | box = { 119 | width: opts.width 120 | }; 121 | jQuery(document.body).append(getContent.call(this, opts.id, opts)); 122 | 123 | this.dialogConfig = opts; 124 | this.activeDialog = jQuery('#' + opts.id); 125 | this.activeDialog.css({width: box.width}); 126 | 127 | if (typeof callback === "undefined") { 128 | callback = opts.callback; 129 | } 130 | 131 | // dialog 높이 구하기 - 너비가 정해지면 높이가 변경 될 것. 132 | opts.height = box.height = this.activeDialog.height(); 133 | 134 | //- position 정렬 135 | if (typeof opts.position === "undefined" || opts.position === "center") { 136 | pos.top = jQuery(window).height() / 2 - box.height / 2; 137 | pos.left = jQuery(window).width() / 2 - box.width / 2; 138 | } 139 | else { 140 | pos.left = opts.position.left || 0; 141 | pos.top = opts.position.top || 0; 142 | } 143 | if (cfg.zIndex) { 144 | pos["z-index"] = cfg.zIndex; 145 | } 146 | this.activeDialog.css(pos); 147 | 148 | // bind button event 149 | if (opts.dialogType === "prompt") { 150 | this.activeDialog.find("[data-dialog-prompt]").get(0).focus(); 151 | } 152 | else { 153 | this.activeDialog.find("[data-dialog-btn]").get(0).focus(); 154 | } 155 | 156 | this.activeDialog.find("[data-dialog-btn]").on(cfg.clickEventName, (function (e) { 157 | btnOnClick.call(this, e || window.event, opts, callback); 158 | }).bind(this)); 159 | 160 | // bind key event 161 | jQuery(window).bind("keydown.ax5dialog", (function (e) { 162 | onKeyup.call(this, e || window.event, opts, callback); 163 | }).bind(this)); 164 | 165 | jQuery(window).bind("resize.ax5dialog", (function (e) { 166 | align.call(this, e || window.event); 167 | }).bind(this)); 168 | 169 | onStateChanged.call(this, opts, { 170 | self: this, 171 | state: "open" 172 | }); 173 | 174 | if (opts.autoCloseTime) { 175 | this.autoCloseTimer = setTimeout(function () { 176 | self.close(); 177 | }, opts.autoCloseTime); 178 | } 179 | 180 | pos = null; 181 | box = null; 182 | }; 183 | const align = function (e) { 184 | if (!this.activeDialog) return this; 185 | let opts = self.dialogConfig, 186 | box = { 187 | width: opts.width, 188 | height: opts.height 189 | }; 190 | 191 | //- position 정렬 192 | if (typeof opts.position === "undefined" || opts.position === "center") { 193 | box.top = window.innerHeight / 2 - box.height / 2; 194 | box.left = window.innerWidth / 2 - box.width / 2; 195 | } 196 | else { 197 | box.left = opts.position.left || 0; 198 | box.top = opts.position.top || 0; 199 | } 200 | if (box.left < 0) box.left = 0; 201 | if (box.top < 0) box.top = 0; 202 | 203 | this.activeDialog.css(box); 204 | 205 | opts = null; 206 | box = null; 207 | 208 | return this; 209 | }; 210 | const btnOnClick = function (e, opts, callback, target, k) { 211 | let that, 212 | emptyKey = null; 213 | 214 | if (e.srcElement) e.target = e.srcElement; 215 | 216 | target = U.findParentNode(e.target, function (target) { 217 | if (target.getAttribute("data-dialog-btn")) { 218 | return true; 219 | } 220 | }); 221 | 222 | if (target) { 223 | k = target.getAttribute("data-dialog-btn"); 224 | 225 | that = { 226 | self: this, 227 | key: k, value: opts.btns[k], 228 | dialogId: opts.id, 229 | btnTarget: target 230 | }; 231 | if (opts.dialogType === "prompt") { 232 | that.input = {}; 233 | for (let oi in opts.input) { 234 | that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val(); 235 | if (opts.input[oi].required && (that.input[oi] == "" || that.input[oi] == null)) { 236 | emptyKey = oi; 237 | break; 238 | } 239 | } 240 | } 241 | if (opts.btns[k].onClick) { 242 | opts.btns[k].onClick.call(that, k); 243 | } 244 | else if (opts.dialogType === "alert") { 245 | if (callback) callback.call(that, k); 246 | this.close({doNotCallback: true}); 247 | } 248 | else if (opts.dialogType === "confirm") { 249 | if (callback) callback.call(that, k); 250 | this.close({doNotCallback: true}); 251 | } 252 | else if (opts.dialogType === "prompt") { 253 | if (k === 'ok') { 254 | if (emptyKey) { 255 | this.activeDialog.find('[data-dialog-prompt="' + emptyKey + '"]').get(0).focus(); 256 | return false; 257 | } 258 | } 259 | if (callback) callback.call(that, k); 260 | this.close({doNotCallback: true}); 261 | } 262 | } 263 | 264 | that = null; 265 | opts = null; 266 | callback = null; 267 | target = null; 268 | k = null; 269 | }; 270 | const onKeyup = function (e, opts, callback, target, k) { 271 | let that, 272 | emptyKey = null; 273 | 274 | if (e.keyCode == ax5.info.eventKeys.ESC) { 275 | this.close(); 276 | } 277 | if (opts.dialogType === "prompt") { 278 | if (e.keyCode == ax5.info.eventKeys.RETURN) { 279 | that = { 280 | self: this, 281 | key: k, value: opts.btns[k], 282 | dialogId: opts.id, 283 | btnTarget: target 284 | }; 285 | that.input = {}; 286 | 287 | for (let oi in opts.input) { 288 | that.input[oi] = this.activeDialog.find('[data-dialog-prompt=' + oi + ']').val(); 289 | if (opts.input[oi].required && (that.input[oi] == "" || that.input[oi] == null)) { 290 | emptyKey = oi; 291 | break; 292 | } 293 | } 294 | if (emptyKey) { 295 | that = null; 296 | emptyKey = null; 297 | return false; 298 | } 299 | if (callback) callback.call(that, k); 300 | this.close({doNotCallback: true}); 301 | } 302 | } 303 | 304 | that = null; 305 | emptyKey = null; 306 | opts = null; 307 | callback = null; 308 | target = null; 309 | k = null; 310 | }; 311 | 312 | /** 313 | * Preferences of dialog UI 314 | * @method ax5dialog.setConfig 315 | * @param {Object} config - 클래스 속성값 316 | * @param {String} [config.theme="default"] 317 | * @param {Number} [config.width=300] 318 | * @param {String} [config.title=""] 319 | * @param {Number} [config.zIndex] 320 | * @param {Function} [config.onStateChanged] - `onStateChanged` function can be defined in setConfig method or new ax5.ui.dialog initialization method. However, you can us to define an 321 | * event function after initialization, if necessary 322 | * @param {Object} [config.lang] 323 | * @param {String} [config.lang.ok="ok"] 324 | * @param {String} [config.lang.cancel="cancel"] 325 | * @param {Number} [config.animateTime=150] 326 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 327 | * @returns {ax5dialog} 328 | * @example 329 | * ``` 330 | * var dialog = new ax5.ui.dialog(); 331 | * dialog.setConfig({ 332 | * title: "app dialog title", 333 | * zIndex: 5000, 334 | * onStateChanged: function () { 335 | * if (this.state === "open") { 336 | * mask.open(); 337 | * } 338 | * else if (this.state === "close") { 339 | * mask.close(); 340 | * } 341 | * } 342 | * }); 343 | * ``` 344 | */ 345 | //== class body start 346 | this.init = function () { 347 | this.onStateChanged = cfg.onStateChanged; 348 | // this.onLoad = cfg.onLoad; 349 | 350 | }; 351 | 352 | /** 353 | * open the dialog of alert type 354 | * @method ax5dialog.alert 355 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 356 | * @param {String} [config.theme="default"] 357 | * @param {Number} [config.width=300] 358 | * @param {String} [config.title=""] 359 | * @param {Number} [config.zIndex] 360 | * @param {Function} [config.onStateChanged] 361 | * @param {Object} [config.lang] 362 | * @param {String} [config.lang.ok="ok"] 363 | * @param {String} [config.lang.cancel="cancel"] 364 | * @param {Number} [config.animateTime=150] 365 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 366 | * @param {Function|String} [config.additionalContent] 367 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 368 | * @returns {ax5dialog} 369 | * @example 370 | * ``` 371 | * myDialog.alert({ 372 | * title: 'app title', 373 | * msg: 'alert' 374 | * }, function(){}); 375 | * ``` 376 | */ 377 | this.alert = function (opts, callback, tryCount) { 378 | if (U.isString(opts)) { 379 | opts = { 380 | title: cfg.title, 381 | msg: opts 382 | } 383 | } 384 | 385 | opts = jQuery.extend(true, {}, cfg, opts); 386 | opts.dialogType = "alert"; 387 | opts.theme = (opts.theme || cfg.theme || ""); 388 | opts.callback = callback; 389 | 390 | if (typeof opts.btns === "undefined") { 391 | opts.btns = { 392 | ok: {label: cfg.lang["ok"], theme: opts.theme} 393 | }; 394 | } 395 | 396 | if (this.activeDialog) { 397 | this.queue.push(opts); 398 | } else { 399 | open.call(this, opts, callback); 400 | } 401 | return this; 402 | }; 403 | 404 | /** 405 | * open the dialog of confirm type 406 | * @method ax5dialog.confirm 407 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 408 | * @param {String} [config.theme="default"] 409 | * @param {Number} [config.width=300] 410 | * @param {String} [config.title=""] 411 | * @param {Number} [config.zIndex] 412 | * @param {Function} [config.onStateChanged] 413 | * @param {Object} [config.lang] 414 | * @param {String} [config.lang.ok="ok"] 415 | * @param {String} [config.lang.cancel="cancel"] 416 | * @param {Number} [config.animateTime=150] 417 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 418 | * @param {Function|String} [config.additionalContent] 419 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 420 | * @returns {ax5dialog} 421 | * @example 422 | * ``` 423 | * myDialog.confirm({ 424 | * title: 'app title', 425 | * msg: 'confirm', 426 | * additionalContent: function () { 427 | * return "
추가정보
"; 428 | * } 429 | * }, function(){}); 430 | * ``` 431 | */ 432 | this.confirm = function (opts, callback, tryCount) { 433 | if (U.isString(opts)) { 434 | opts = { 435 | title: cfg.title, 436 | msg: opts 437 | } 438 | } 439 | 440 | opts = jQuery.extend(true, {}, cfg, opts); 441 | opts.dialogType = "confirm"; 442 | opts.theme = (opts.theme || cfg.theme || ""); 443 | opts.callback = callback; 444 | 445 | if (typeof opts.btns === "undefined") { 446 | opts.btns = { 447 | ok: {label: cfg.lang["ok"], theme: opts.theme}, 448 | cancel: {label: cfg.lang["cancel"]} 449 | }; 450 | } 451 | 452 | if (this.activeDialog) { 453 | this.queue.push(opts); 454 | } else { 455 | open.call(this, opts, callback); 456 | } 457 | 458 | return this; 459 | }; 460 | 461 | /** 462 | * open the dialog of prompt type 463 | * @method ax5dialog.prompt 464 | * @param {Object|String} config - dialog 속성을 json으로 정의하거나 msg만 전달 465 | * @param {String} [config.theme="default"] 466 | * @param {Number} [config.width=300] 467 | * @param {String} [config.title=""] 468 | * @param {Number} [config.zIndex] 469 | * @param {Function} [config.onStateChanged] 470 | * @param {Object} [config.lang] 471 | * @param {String} [config.lang.ok="ok"] 472 | * @param {String} [config.lang.cancel="cancel"] 473 | * @param {Number} [config.animateTime=150] 474 | * @param {Number} [config.autoCloseTime=0] - 0보다 크면 autoCloseTime 프레임후에 dialog auto close 475 | * @param {Function|String} [config.additionalContent] 476 | * @param {Function} [callback] - 사용자 확인 이벤트시 호출될 callback 함수 477 | * @returns {ax5dialog} 478 | * @example 479 | * ``` 480 | * myDialog.prompt({ 481 | * title: 'app title', 482 | * msg: 'alert' 483 | * }, function(){}); 484 | * ``` 485 | */ 486 | this.prompt = function (opts, callback, tryCount) { 487 | if (U.isString(opts)) { 488 | opts = { 489 | title: cfg.title, 490 | msg: opts 491 | } 492 | } 493 | 494 | opts = jQuery.extend(true, {}, cfg, opts); 495 | opts.dialogType = "prompt"; 496 | opts.theme = (opts.theme || cfg.theme || ""); 497 | opts.callback = callback; 498 | 499 | if (typeof opts.input === "undefined") { 500 | opts.input = { 501 | value: {label: ""} 502 | }; 503 | } 504 | if (typeof opts.btns === "undefined") { 505 | opts.btns = { 506 | ok: {label: cfg.lang["ok"], theme: opts.theme}, 507 | cancel: {label: cfg.lang["cancel"]} 508 | }; 509 | } 510 | 511 | if (this.activeDialog) { 512 | this.queue.push(opts); 513 | } else { 514 | open.call(this, opts, callback); 515 | } 516 | 517 | return this; 518 | }; 519 | 520 | /** 521 | * close the dialog 522 | * @method ax5dialog.close 523 | * @returns {ax5dialog} 524 | * @example 525 | * ``` 526 | * myDialog.close(); 527 | * ``` 528 | */ 529 | this.close = function (_option) { 530 | let opts, that; 531 | 532 | if (this.activeDialog) { 533 | if (this.autoCloseTimer) clearTimeout(this.autoCloseTimer); 534 | 535 | opts = self.dialogConfig; 536 | 537 | this.activeDialog.addClass("destroy"); 538 | jQuery(window).unbind("keydown.ax5dialog"); 539 | jQuery(window).unbind("resize.ax5dialog"); 540 | 541 | setTimeout((function () { 542 | if (this.activeDialog) { 543 | this.activeDialog.remove(); 544 | this.activeDialog = null; 545 | } 546 | 547 | that = { 548 | self: this, 549 | state: "close", 550 | dialogId: opts.id 551 | }; 552 | 553 | if (opts.callback && (!_option || !_option.doNotCallback)) { 554 | opts.callback.call(that); 555 | } 556 | 557 | if (opts && opts.onStateChanged) { 558 | opts.onStateChanged.call(that, that); 559 | } 560 | else if (this.onStateChanged) { 561 | this.onStateChanged.call(that, that); 562 | } 563 | 564 | if (this.queue && this.queue.length) { 565 | open.call(this, this.queue.shift()); 566 | } 567 | 568 | opts = null; 569 | that = null; 570 | }).bind(this), cfg.animateTime); 571 | } 572 | return this; 573 | }; 574 | 575 | // 클래스 생성자 576 | this.main = (function () { 577 | 578 | UI.dialog_instance = UI.dialog_instance || []; 579 | UI.dialog_instance.push(this); 580 | 581 | if (arguments && U.isObject(arguments[0])) { 582 | this.setConfig(arguments[0]); 583 | } 584 | }).apply(this, arguments); 585 | }; 586 | return ax5dialog; 587 | })()); 588 | 589 | DIALOG = ax5.ui.dialog; 590 | })(); 591 | -------------------------------------------------------------------------------- /src/ax5dialog.scss: -------------------------------------------------------------------------------- 1 | @import "node_modules/ax5core/src/_ax5.scss"; 2 | 3 | @import "scss/ax5dialog_variables"; 4 | @import "scss/ax5dialog"; 5 | -------------------------------------------------------------------------------- /src/modules/ax5dialog-tmpl.js: -------------------------------------------------------------------------------- 1 | // ax5.ui.dialog.tmpl 2 | (function () { 3 | 4 | var DIALOG = ax5.ui.dialog; 5 | 6 | var dialogDisplay = function(columnKeys) { 7 | return ` 8 |
9 |
10 | {{{title}}} 11 |
12 |
13 |
{{{msg}}}
14 | 15 | {{#input}} 16 |
17 | {{#@each}} 18 |
19 | {{#@value.label}} 20 | 21 | {{/@value.label}} 22 | 23 | {{#@value.help}} 24 |

{{#_crlf}}{{.}}{{/_crlf}}

25 | {{/@value.help}} 26 |
27 | {{/@each}} 28 |
29 | {{/input}} 30 | 31 |
32 |
33 | {{#btns}} 34 | {{#@each}} 35 | 36 | {{/@each}} 37 | {{/btns}} 38 |
39 |
40 | 41 | {{#additionalContent}} 42 |
{{{.}}}
43 | {{/additionalContent}} 44 |
45 |
46 | `; 47 | }; 48 | 49 | DIALOG.tmpl = { 50 | "dialogDisplay": dialogDisplay, 51 | get: function (tmplName, data, columnKeys) { 52 | return ax5.mustache.render(DIALOG.tmpl[tmplName].call(this, columnKeys), data); 53 | } 54 | }; 55 | 56 | })(); -------------------------------------------------------------------------------- /src/scss/_ax5dialog.scss: -------------------------------------------------------------------------------- 1 | @mixin ax-dialog() { 2 | box-sizing: $ax5dialog-box-model; 3 | background-color: $ax5dialog-bg; 4 | border: $ax5dialog-inner-border; 5 | border-radius: $ax5dialog-border-radius; 6 | box-shadow: $ax5dialog-box-shaodw; 7 | 8 | z-index: $ax5dialog-z-index; 9 | position: fixed; 10 | left: 0px; 11 | top: 0px; 12 | overflow: hidden; 13 | } 14 | 15 | @mixin ax-dialog-section() { 16 | .ax-dialog-header { 17 | //font-size: 1em; 18 | font-weight: 600; 19 | padding: $ax5dialog-header-padding; 20 | border-bottom: 1px solid transparent; 21 | .badge { 22 | font-size: 0.8em; 23 | color: $ax5dialog-default-header-bg; 24 | background-color: $ax5dialog-default-text; 25 | } 26 | } 27 | .ax-dialog-body { 28 | padding: $ax5dialog-body-padding; 29 | text-align: center; 30 | .ax-dialog-msg { 31 | padding-top: $ax5dialog-body-padding; 32 | padding-bottom: $ax5dialog-body-padding; 33 | } 34 | .ax-dialog-prompt { 35 | text-align: left; 36 | padding-bottom: $ax5dialog-body-padding/2; 37 | } 38 | .ax-dialog-buttons { 39 | margin-top: $ax5dialog-body-padding; 40 | button { 41 | &:not(:last-child) { 42 | margin-right: 3px; 43 | } 44 | } 45 | } 46 | [data-dialog-els="additional-content"] { 47 | margin-top: $ax5dialog-body-padding; 48 | } 49 | } 50 | } 51 | 52 | @mixin dialog-variant($text-color, $border, $header-bg-color) { 53 | 54 | border: $ax5dialog-inner-border; 55 | 56 | .ax-dialog-header { 57 | color: $text-color; 58 | background: $header-bg-color; 59 | .badge { 60 | color: $header-bg-color; 61 | background-color: $text-color; 62 | } 63 | } 64 | .ax-dialog-body { 65 | 66 | } 67 | } 68 | 69 | @include keyframes(ax-dialog) { 70 | 0% { 71 | opacity: 0.0; 72 | @include transform(scale(1)); 73 | } 74 | 1% { 75 | opacity: 0.0; 76 | @include transform(scale(0.3)); 77 | } 78 | 100% { 79 | opacity: 1.0; 80 | @include transform(scale(1)); 81 | } 82 | } 83 | 84 | @include keyframes(ax-dialog-destroy) { 85 | from { 86 | @include transform(scale(1)); 87 | opacity: 1.0; 88 | } 89 | to { 90 | @include transform(scale(0.5)); 91 | opacity: 0.0; 92 | } 93 | } 94 | 95 | // mixins --------------------------------------------- end 96 | 97 | .ax5-ui-dialog { 98 | @include animation(ax-dialog $ax5dialog-easing-time-open $ease-in-out-cubic); 99 | @include transform(translateZ(0)); 100 | 101 | @include ax-dialog(); 102 | @include ax-dialog-section(); 103 | 104 | @include dialog-variant($ax5dialog-default-text, $ax5dialog-default-border, $ax5dialog-default-header-bg); 105 | 106 | &.primary { 107 | @include dialog-variant($ax5dialog-primary-text, $ax5dialog-primary-border, $ax5dialog-primary-header-bg); 108 | } 109 | &.success { 110 | @include dialog-variant($ax5dialog-success-text, $ax5dialog-success-border, $ax5dialog-success-header-bg); 111 | } 112 | &.info { 113 | @include dialog-variant($ax5dialog-info-text, $ax5dialog-info-border, $ax5dialog-info-header-bg); 114 | } 115 | &.warning { 116 | @include dialog-variant($ax5dialog-warning-text, $ax5dialog-warning-border, $ax5dialog-warning-header-bg); 117 | } 118 | &.danger { 119 | @include dialog-variant($ax5dialog-danger-text, $ax5dialog-danger-border, $ax5dialog-danger-header-bg); 120 | } 121 | 122 | &.destroy { 123 | @include animation(ax-dialog-destroy $ax5dialog-easing-time-close $ease-in-out-cubic forwards); 124 | } 125 | } -------------------------------------------------------------------------------- /src/scss/_ax5dialog_variables.scss: -------------------------------------------------------------------------------- 1 | //============== ax5dialog 2 | 3 | $ax5dialog-z-index: 2000 !default; 4 | $ax5dialog-box-model: border-box !default; 5 | $ax5dialog-bg: $panel-bg !default; 6 | $ax5dialog-box-shaodw: 0px 0px 3px 0px rgba(0, 0, 0, 0.175) !default; 7 | $ax5dialog-body-padding: $panel-body-padding !default; 8 | $ax5dialog-header-padding: $panel-heading-padding !default; 9 | $ax5dialog-footer-padding: $panel-footer-padding !default; 10 | $ax5dialog-border-radius: $panel-border-radius !default; 11 | $ax5dialog-easing-time-open: 0.15s !default; 12 | $ax5dialog-easing-time-close: 0.15s !default; 13 | 14 | //** Border color for elements within dialog 15 | $ax5dialog-inner-border: 1px solid $panel-inner-border !default; 16 | $ax5dialog-footer-bg: $panel-footer-bg !default; 17 | 18 | $ax5dialog-default-text: $panel-default-text !default; 19 | $ax5dialog-default-border: 1px solid $panel-default-border !default; 20 | $ax5dialog-default-header-bg: $panel-default-heading-bg !default; 21 | 22 | $ax5dialog-primary-text: $panel-primary-text !default; 23 | $ax5dialog-primary-border: 1px solid $panel-primary-border !default; 24 | $ax5dialog-primary-header-bg: $panel-primary-heading-bg !default; 25 | 26 | $ax5dialog-success-text: $panel-success-text !default; 27 | $ax5dialog-success-border: 1px solid $panel-success-border !default; 28 | $ax5dialog-success-header-bg: $panel-success-heading-bg !default; 29 | 30 | $ax5dialog-info-text: $panel-info-text !default; 31 | $ax5dialog-info-border: 1px solid $panel-info-border !default; 32 | $ax5dialog-info-header-bg: $panel-info-heading-bg !default; 33 | 34 | $ax5dialog-warning-text: $panel-warning-text !default; 35 | $ax5dialog-warning-border: 1px solid $panel-warning-border !default; 36 | $ax5dialog-warning-header-bg: $panel-warning-heading-bg !default; 37 | 38 | $ax5dialog-danger-text: $panel-danger-text !default; 39 | $ax5dialog-danger-border: 1px solid $panel-danger-border !default; 40 | $ax5dialog-danger-header-bg: $panel-danger-heading-bg !default; -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # STEP 01 2 | ``` 3 | $ bower install 4 | ``` 5 | `test/bower_components` folder is created, plug-ins required will be downloaded. 6 | 7 | # STEP 02 8 | It'll add the plugin resources to html> head. 9 | ```html 10 | 11 | 12 | 13 | 14 | Title 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /test/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ax5ui-dialog-tester", 3 | "dependencies": { 4 | "jquery": "^1.11.0", 5 | "ax5core": ">=1.4.115", 6 | "ax5ui-mask": ">=1.3.0", 7 | "bootstrap": "^3.3.6", 8 | "font-awesome": "" 9 | }, 10 | "devDependencies": { 11 | "should": "^11.1.0", 12 | "lodash": "^4.16.2" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 20 | 22 | 24 | 25 | 27 | 28 |
29 |
30 | 33 | 36 | 39 | 40 | 43 | 45 |
46 |
47 | 49 | 51 | 53 | 54 | 56 | 58 |
59 |
60 | 62 |
63 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /test/test.dialog.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ax5.util TYPE testing 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /test/test.dialog.js: -------------------------------------------------------------------------------- 1 | describe('dialog Alert TEST', function(){ 2 | var dialog; 3 | var that; 4 | beforeEach(function(){ 5 | dialog = new ax5.ui.dialog({ 6 | title: "AX5 Dialog", 7 | animateTime: 10, 8 | onStateChanged: function () { 9 | that = this; 10 | } 11 | }); 12 | }); 13 | 14 | var shouldClosed = function(dialog, assertMessage, done){ 15 | setTimeout(function(){ 16 | var dialogDom = $('#' + dialog.config.id).get(0); 17 | // close check 18 | should(dialogDom).Undefined(assertMessage); 19 | that.state.should.equal('close'); 20 | done(); 21 | }, dialog.config.animateTime + 10); 22 | } 23 | 24 | it('Basic Alert expect open, close', function(done){ 25 | dialog.alert('Alert message', function(){ 26 | shouldClosed(dialog, 'dialog close fail.', done); 27 | }); 28 | 29 | console.log(that); 30 | // open check 31 | //dialog.activeDialog.attr('data-ax5-ui').should.equal('dialog', 'dialog open fail.'); 32 | that.state.should.equal('open'); 33 | dialog.close(); 34 | }); 35 | 36 | it('Basic Alert expect open, close by click event', function(done){ 37 | dialog.alert('Alert message', function(){ 38 | shouldClosed(dialog, 'dialog close by click event fail.', done); 39 | }); 40 | 41 | // open check 42 | //dialog.activeDialog.attr('data-ax5-ui').should.equal('dialog', 'dialog open fail.'); 43 | that.state.should.equal('open'); 44 | 45 | // close click event fire 46 | dialog.activeDialog.find('[data-dialog-btn="ok"]').click(); 47 | }); 48 | }); 49 | 50 | 51 | describe('dialog Confirm TEST', function(){ 52 | var dialog; 53 | var that; 54 | beforeEach(function(){ 55 | dialog = new ax5.ui.dialog({ 56 | title: "AX5 Confirm", 57 | animateTime: 10, 58 | onStateChanged: function () { 59 | that = this; 60 | } 61 | }); 62 | }); 63 | 64 | var shouldClosed = function(dialog, assertMessage, done){ 65 | setTimeout(function(){ 66 | var dialogDom = $('#' + dialog.config.id).get(0); 67 | // close check 68 | should(dialogDom).Undefined(assertMessage); 69 | 70 | that.state.should.equal('close'); 71 | done(); 72 | }, dialog.config.animateTime + 10); 73 | }; 74 | 75 | describe('dialog Confirm Basic Usages TEST', function(){ 76 | it('ok button click expect "ok"', function(done){ 77 | dialog.confirm('confirm ok', function(){ 78 | should(this.key).equal("ok"); 79 | shouldClosed(dialog, 'dialog close fail.', done); 80 | }); 81 | 82 | // open check 83 | //dialog.activeDialog.attr('data-ax5-ui').should.equal('dialog', 'dialog open fail.'); 84 | that.state.should.equal('open'); 85 | dialog.activeDialog.find('[data-dialog-btn="ok"]').click(); // ok click event fire 86 | }); 87 | 88 | it('cancel button click expect "cancel"', function(done){ 89 | dialog.confirm('Confirm cancel', function(){ 90 | should(this.key).equal("cancel"); 91 | shouldClosed(dialog, 'dialog close fail.', done); 92 | }); 93 | 94 | // open check 95 | //dialog.activeDialog.attr('data-ax5-ui').should.equal('dialog', 'dialog open fail.'); 96 | that.state.should.equal('open'); 97 | dialog.activeDialog.find('[data-dialog-btn="cancel"]').click(); // cancel click event fire 98 | }); 99 | }); 100 | 101 | describe('dialog Confirm Custom Buttons TEST', function(){ 102 | it('Custom Buttons expect Delete, Cancel, Other', function(done){ 103 | dialog.confirm({ 104 | msg: 'Confirm message', 105 | btns: { 106 | del: { 107 | label:'Delete', theme:'warning', onClick: function(key){ 108 | should(key).equal('del'); 109 | dialog.close(); 110 | } 111 | }, 112 | cancel: { 113 | label:'Cancel', onClick: function(key){ 114 | should(key).equal('cancel'); 115 | dialog.close(); 116 | } 117 | }, 118 | other: { 119 | label:'Other', onClick: function(key){ 120 | should(key).equal('other'); 121 | dialog.close(); 122 | } 123 | } 124 | } 125 | }, function(key){ 126 | shouldClosed(dialog, 'dialog close fail.', done); 127 | }); 128 | 129 | // open check 130 | //dialog.activeDialog.attr('data-ax5-ui').should.equal('dialog', 'dialog open fail.'); 131 | that.state.should.equal('open'); 132 | dialog.activeDialog.find('[data-dialog-btn="del"]').click(); // del click event fire 133 | }); 134 | }); 135 | }); 136 | 137 | 138 | describe('dialog Prompt TEST', function() { 139 | it('Prompt Basic Usages value expect test1', function(done) { 140 | var data1 = 'test1'; 141 | var dialog = new ax5.ui.dialog(); 142 | dialog.setConfig({ 143 | title: "XXX", 144 | theme: "danger" 145 | }); 146 | 147 | dialog.prompt({ 148 | title: "Confirm Title", 149 | msg: 'Confirm message' 150 | }, function(){ 151 | should.equal(this.input.value, data1); 152 | 153 | done(); 154 | }); 155 | 156 | dialog.activeDialog.find('input[data-dialog-prompt="value"]').val(data1); 157 | 158 | dialog.activeDialog.find('button[data-dialog-btn="ok"]').trigger('click'); 159 | }); 160 | 161 | it('Prompt Custom Input value expect test2, test3', function(done) { 162 | var data1 = "test2"; 163 | var data2 = "test3"; 164 | var dialog = new ax5.ui.dialog(); 165 | 166 | dialog.prompt({ 167 | theme: 'info', 168 | title: 'Custom Prompt test', 169 | msg: 'data1, data2', 170 | input: { 171 | data1: {label: "data1의 라벨"}, 172 | data2: {label: "data2의 라벨"} 173 | } 174 | }, function () { 175 | var inputValue1 = this.input.data1; 176 | var inputValue2 = this.input.data2; 177 | 178 | inputValue1.should.equal(data1); 179 | inputValue2.should.equal(data2); 180 | 181 | done(); 182 | }); 183 | 184 | dialog.activeDialog.find('input[data-dialog-prompt="data1"]').val(data1); 185 | dialog.activeDialog.find('input[data-dialog-prompt="data2"]').val(data2); 186 | 187 | dialog.activeDialog.find('button[data-dialog-btn="ok"]').trigger('click'); 188 | }); 189 | }); 190 | --------------------------------------------------------------------------------