├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── bower.json ├── bs3.html ├── composer.json ├── css ├── bootstrap-modal-bs3patch.css └── bootstrap-modal.css ├── img └── ajax-loader.gif ├── index.html ├── js ├── bootstrap-modal.js └── bootstrap-modalmanager.js ├── modal_ajax_test.html └── params.json /.gitattributes: -------------------------------------------------------------------------------- 1 | *.html linguist-vendored 2 | css/* linguist-vendored=false 3 | js/* linguist-vendored=false 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | [Dd]ebug/ 46 | [Rr]elease/ 47 | *_i.c 48 | *_p.c 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.vspscc 63 | .builds 64 | *.dotCover 65 | 66 | ## TODO: If you have NuGet Package Restore enabled, uncomment this 67 | #packages/ 68 | 69 | # Visual C++ cache files 70 | ipch/ 71 | *.aps 72 | *.ncb 73 | *.opensdf 74 | *.sdf 75 | 76 | # Visual Studio profiler 77 | *.psess 78 | *.vsp 79 | 80 | # ReSharper is a .NET coding add-in 81 | _ReSharper* 82 | 83 | # Installshield output folder 84 | [Ee]xpress 85 | 86 | # DocProject is a documentation generator add-in 87 | DocProject/buildhelp/ 88 | DocProject/Help/*.HxT 89 | DocProject/Help/*.HxC 90 | DocProject/Help/*.hhc 91 | DocProject/Help/*.hhk 92 | DocProject/Help/*.hhp 93 | DocProject/Help/Html2 94 | DocProject/Help/html 95 | 96 | # Click-Once directory 97 | publish 98 | 99 | # Others 100 | [Bb]in 101 | [Oo]bj 102 | sql 103 | TestResults 104 | *.Cache 105 | ClientBin 106 | stylecop.* 107 | ~$* 108 | *.dbmdl 109 | Generated_Code #added for RIA/Silverlight projects 110 | 111 | # Backup & report files from converting an old project file to a newer 112 | # Visual Studio version. Backup files are not needed, because we have git ;-) 113 | _UpgradeReport_Files/ 114 | Backup*/ 115 | UpgradeLog*.XML 116 | 117 | 118 | 119 | ############ 120 | ## Windows 121 | ############ 122 | 123 | # Windows image file caches 124 | Thumbs.db 125 | 126 | # Folder config file 127 | Desktop.ini 128 | 129 | 130 | ############# 131 | ## Python 132 | ############# 133 | 134 | *.py[co] 135 | 136 | # Packages 137 | *.egg 138 | *.egg-info 139 | dist 140 | build 141 | eggs 142 | parts 143 | bin 144 | var 145 | sdist 146 | develop-eggs 147 | .installed.cfg 148 | 149 | # Installer logs 150 | pip-log.txt 151 | 152 | # Unit test / coverage reports 153 | .coverage 154 | .tox 155 | 156 | #Translations 157 | *.mo 158 | 159 | #Mr Developer 160 | .mr.developer.cfg 161 | 162 | # Mac crap 163 | .DS_Store 164 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Note**: Since this plugin was created to solve a lot of the issues with BS2, it still uses the BS2 markup syntax. Currently I believe the default BS3 modal addresses some of the bigger issues and is not worth maintaining two versions of this plugin. 2 | 3 | 4 | Bootstrap Modal v2.2.6 5 | ============= 6 | 7 | See live demo [here](http://jschr.github.com/bootstrap-modal/). 8 | 9 | Extends Bootstrap's native modals to provide additional functionality. Introduces a **ModalManager** class that operates behind the scenes to handle multiple modals by listening on their events. 10 | 11 | A single ModalManager is created by default on body and can be accessed through the jQuery plugin interface. 12 | ```javascript 13 | $('body').modalmanager('loading'); 14 | ``` 15 | Bootstrap-Modal can be used as a replacement for Bootstrap's Modal class or as a patch to the library. 16 | 17 | 18 | Bootstrap 3 19 | ----------- 20 | 21 | If you're using BS3, I've provided a compatible css patch. Include `bootstrap-modal-bs3patch.css` **before** the main `bootstrap-modal.css` file to use this plugin with Bootstrap 3. 22 | 23 | If you're using the loading spinner functionality you may also need to change the default template to be compatible in js: 24 | ```html 25 | $.fn.modal.defaults.spinner = $.fn.modalmanager.defaults.spinner = 26 | '
' + 27 | '
' + 28 | '
' + 29 | '
' + 30 | '
'; 31 | ``` 32 | 33 | 34 | Overview 35 | ----------- 36 | 37 | + Backwards compatible 38 | + Responsive 39 | + Stackable 40 | + Full width 41 | + Load content via AJAX 42 | + Disable background scrolling 43 | 44 | Installation 45 | ----------- 46 | + Include `css/bootstrap-modal.css` after the main bootstrap css files. 47 | + Include `js/bootstrap-modalmanager.js` and `js/bootstrap-modal.js` after the main bootstrap js files. 48 | ```html 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | ``` 57 | Options 58 | ----------- 59 | 60 | In addition to the standard bootstrap options, you now have access to the following options 61 | 62 | **Modal** 63 | 64 | + **width** 65 | Set the initial width of the modal. 66 | 67 | + **height** 68 | Set the initial height of the modal. 69 | 70 | + **maxHeight** 71 | Set the max-height of the modal-body. 72 | 73 | + **loading** 74 | Toggle the loading state. 75 | 76 | + **spinner** 77 | Provide a custom image or animation for the loading spinner. 78 | 79 | + **backdropTemplate** 80 | Provide a custom modal backdrop. 81 | 82 | + **consumeTab** 83 | Used to enable tabindexing for modals with `data-tabindex`. This is set to true by default. 84 | 85 | + **focusOn** 86 | The element or selector to set the focus to once the modal is shown. 87 | 88 | + **replace** 89 | If set to true, the modal will replace the topmost modal when opened. 90 | 91 | + **attentionAnimation** 92 | Set the animation used by the `attention` method. Any animation in [animate.css](http://daneden.me/animate/) is supported but only the *shake* animation is included by default. 93 | 94 | + **modalOverflow** 95 | Set this property to true for modals with highly dynamic content. This will force the modal to behave as if it is larger than the viewport. 96 | 97 | + **manager** 98 | Set the modal's manager. By default this is set to the `GlobalModalManager` and will most likely not need to be overridden. 99 | 100 | **ModalManager** 101 | 102 | + **loading** 103 | Toggle the loading state. 104 | 105 | + **backdropLimit** 106 | Limit the amount of backdrops that will appear on the page at the same time. 107 | 108 | + **spinner** 109 | Provide a custom image or animation for the loading spinner. 110 | 111 | + **backdropTemplate** 112 | Provide a custom modalmanager backdrop. This backdrop is used when `$element.modalmanager('loading')` is called. 113 | 114 | Getting a reference to the modal manager 115 | ----------- 116 | 117 | If you did not created your own ModalManager, perhaps you'll need a reference to it. That can be easily accomplished using the following snippet: 118 | 119 | ```javascript 120 | var modalManager = $("body").data("modalmanager"); 121 | var openModals = modalManager.getOpenModals(); 122 | modalManager.removeLoading(); 123 | ``` 124 | 125 | After that, you'll be able to call any methods that modal manager has, such as: 126 | 127 | * removeLoading (remove the loading and backdrop window); 128 | * getOpenModals (to get the modals that are already open); 129 | * etc; 130 | 131 | 132 | Disable Background Scrolling 133 | ----------- 134 | 135 | If you want to prevent the background page from scrolling (see [demo](http://jschr.github.com/bootstrap-modal/) for example) you must wrap the page contents in a `
`. For example: 136 | ```html 137 | 138 |
139 | 140 |
...
141 |
142 | 143 | ``` 144 | 145 | The reason for doing this instead of just simply setting `overflow: hidden` when a modal is open is to avoid having the page shift as a result of the scrollbar appearing/disappearing. This also allows the document to be scrollable when there is a tall modal but only to the height of the modal, not the entire page. 146 | 147 | Constrain Modal to Window Size 148 | ----------- 149 | 150 | You can bind the height of the modal body to the window with something like this: 151 | ```javascript 152 | $.fn.modal.defaults.maxHeight = function(){ 153 | // subtract the height of the modal header and footer 154 | return $(window).height() - 165; 155 | } 156 | ``` 157 | 158 | **Note:** This will be overwritten by the responsiveness and is only set when the modal is displayed, not when the window is resized. 159 | 160 | Tab Index for Modal Forms 161 | ----------- 162 | You can use `data-tabindex` instead of the default `tabindex` to specify the tabindex within a modal. 163 | ```html 164 | 165 | 166 | ``` 167 | See the stackable example on the [demo](http://jschr.github.com/bootstrap-modal/) page for an example. 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/jschr/bootstrap-modal/trend.png)](https://bitdeli.com/free "Bitdeli Badge") 177 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap-modal", 3 | "description": "Extends the default Bootstrap Modal class. Responsive, stackable, ajax and more.", 4 | "version": "2.2.5", 5 | "main": ["js/bootstrap-modal.js", "js/bootstrap-modalmanager.js", "css/bootstrap-modal.css"], 6 | "dependencies": { 7 | "bootstrap": ">=2.3.0" 8 | }, 9 | "url": "https://github.com/jschr/bootstrap-modal.git", 10 | "author": "Jordan Schroter", 11 | "license": { 12 | "type": "Apache License 2.0", 13 | "url": "https://github.com/jschr/bootstrap-modal/blob/master/LICENSE" 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /bs3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Bootstrap-modal by jschr 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 33 | 34 | 35 |
36 |
37 |
38 |

Bootstrap-Modal

39 |

Responsive, Stackable, AJAX and more.

40 |   48 | 50 | 52 |
53 |
54 |
55 |
56 | 57 |
58 |

Responsive

59 |
 60 |             
61 |
62 | 63 |
64 |
65 |
66 | 67 |
68 |

Stackable

69 |
         
 70 |             
71 |
72 | 73 |
74 |
75 |
76 | 77 | 86 | 87 |
88 |

AJAX (via jQuery.load)

89 |
 90 |             
91 |
92 | 93 |
94 |
95 |
96 | 97 |
98 |

Static Background with Animation

99 |

The shake animation is included in bootstrap-modal but any animation in animate.css is supported, just include the css file in your project.

100 |
101 |             
102 |
103 | 104 |
105 |
106 |
107 | 108 |
109 |

Full Width

110 |
111 |             
112 |
113 | 114 |
115 |
116 |
117 | 118 |
119 |

Long Modals

120 |
121 |             
122 |
123 | 124 |
125 |
126 |
127 | 128 |
129 |
130 |
131 | 132 | 133 | 167 | 168 | 182 | 183 | 201 | 202 | 219 | 220 | 235 | 236 | 245 | 246 | 259 | 260 | 275 | 276 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 331 | 332 | 333 | 355 | 356 | 384 | 387 | 388 | 389 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jschr/bootstrap-modal", 3 | "description": "Extends the default Bootstrap Modal class. Responsive, stackable, ajax and more.", 4 | "keywords": ["bootstrap", "modal", "javascript"], 5 | "homepage": "https://github.com/jschr/bootstrap-modal.git", 6 | "license": "Apache License 2.0", 7 | "authors": [ 8 | { 9 | "name": "Jordan Schroter", 10 | "homepage": "https://twitter.com/_jschr", 11 | "role": "Developer" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /css/bootstrap-modal-bs3patch.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Modal 3 | * 4 | * Copyright Jordan Schroter 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | * Boostrap 3 patch for for bootstrap-modal. Include BEFORE bootstrap-modal.css! 9 | */ 10 | 11 | body.modal-open, 12 | .modal-open .navbar-fixed-top, 13 | .modal-open .navbar-fixed-bottom { 14 | margin-right: 0; 15 | } 16 | 17 | .modal { 18 | left: 50%; 19 | bottom: auto; 20 | right: auto; 21 | z-index: 1050; 22 | padding: 0; 23 | width: 500px; 24 | margin-left: -250px; 25 | background-color: #ffffff; 26 | border: 1px solid #999999; 27 | border: 1px solid rgba(0, 0, 0, 0.2); 28 | border-radius: 6px; 29 | -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); 30 | box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); 31 | background-clip: padding-box; 32 | } 33 | 34 | .modal.container { 35 | max-width: none; 36 | } 37 | 38 | .modal-backdrop { 39 | position: fixed; 40 | top: 0; 41 | right: 0; 42 | bottom: 0; 43 | left: 0; 44 | z-index: 1040; 45 | } -------------------------------------------------------------------------------- /css/bootstrap-modal.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Modal 3 | * 4 | * Copyright Jordan Schroter 5 | * Licensed under the Apache License v2.0 6 | * http://www.apache.org/licenses/LICENSE-2.0 7 | * 8 | */ 9 | 10 | .modal-open { 11 | overflow: hidden; 12 | } 13 | 14 | 15 | /* add a scroll bar to stop page from jerking around */ 16 | .modal-open.page-overflow .page-container, 17 | .modal-open.page-overflow .page-container .navbar-fixed-top, 18 | .modal-open.page-overflow .page-container .navbar-fixed-bottom, 19 | .modal-open.page-overflow .modal-scrollable { 20 | overflow-y: scroll; 21 | } 22 | 23 | @media (max-width: 979px) { 24 | .modal-open.page-overflow .page-container .navbar-fixed-top, 25 | .modal-open.page-overflow .page-container .navbar-fixed-bottom { 26 | overflow-y: visible; 27 | } 28 | } 29 | 30 | 31 | .modal-scrollable { 32 | position: fixed; 33 | top: 0; 34 | bottom: 0; 35 | left: 0; 36 | right: 0; 37 | overflow: auto; 38 | } 39 | 40 | .modal { 41 | outline: none; 42 | position: absolute; 43 | margin-top: 0; 44 | top: 50%; 45 | overflow: visible; /* allow content to popup out (i.e tooltips) */ 46 | } 47 | 48 | .modal.fade { 49 | top: -100%; 50 | -webkit-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out; 51 | -moz-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out; 52 | -o-transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out; 53 | transition: opacity 0.3s linear, top 0.3s ease-out, bottom 0.3s ease-out, margin-top 0.3s ease-out; 54 | } 55 | 56 | .modal.fade.in { 57 | top: 50%; 58 | } 59 | 60 | .modal-body { 61 | max-height: none; 62 | overflow: visible; 63 | } 64 | 65 | .modal.modal-absolute { 66 | position: absolute; 67 | z-index: 950; 68 | } 69 | 70 | .modal .loading-mask { 71 | position: absolute; 72 | top: 0; 73 | bottom: 0; 74 | left: 0; 75 | right: 0; 76 | background: #fff; 77 | border-radius: 6px; 78 | } 79 | 80 | .modal-backdrop.modal-absolute{ 81 | position: absolute; 82 | z-index: 940; 83 | } 84 | 85 | .modal-backdrop, 86 | .modal-backdrop.fade.in{ 87 | opacity: 0.7; 88 | filter: alpha(opacity=70); 89 | background: #fff; 90 | } 91 | 92 | .modal.container { 93 | width: 940px; 94 | margin-left: -470px; 95 | } 96 | 97 | /* Modal Overflow */ 98 | 99 | .modal-overflow.modal { 100 | top: 1%; 101 | } 102 | 103 | .modal-overflow.modal.fade { 104 | top: -100%; 105 | } 106 | 107 | .modal-overflow.modal.fade.in { 108 | top: 1%; 109 | } 110 | 111 | .modal-overflow .modal-body { 112 | overflow: auto; 113 | -webkit-overflow-scrolling: touch; 114 | } 115 | 116 | /* Responsive */ 117 | 118 | @media (min-width: 1200px) { 119 | .modal.container { 120 | width: 1170px; 121 | margin-left: -585px; 122 | } 123 | } 124 | 125 | @media (max-width: 979px) { 126 | .modal, 127 | .modal.container, 128 | .modal.modal-overflow { 129 | top: 1%; 130 | right: 1%; 131 | left: 1%; 132 | bottom: auto; 133 | width: auto !important; 134 | height: auto !important; 135 | margin: 0 !important; 136 | padding: 0 !important; 137 | } 138 | 139 | .modal.fade.in, 140 | .modal.container.fade.in, 141 | .modal.modal-overflow.fade.in { 142 | top: 1%; 143 | bottom: auto; 144 | } 145 | 146 | .modal-body, 147 | .modal-overflow .modal-body { 148 | position: static; 149 | margin: 0; 150 | height: auto !important; 151 | max-height: none !important; 152 | overflow: visible !important; 153 | } 154 | 155 | .modal-footer, 156 | .modal-overflow .modal-footer { 157 | position: static; 158 | } 159 | } 160 | 161 | .loading-spinner { 162 | position: absolute; 163 | top: 50%; 164 | left: 50%; 165 | margin: -12px 0 0 -12px; 166 | } 167 | 168 | /* 169 | Animate.css - http://daneden.me/animate 170 | Licensed under the ☺ license (http://licence.visualidiot.com/) 171 | 172 | Copyright (c) 2012 Dan Eden*/ 173 | 174 | .animated { 175 | -webkit-animation-duration: 1s; 176 | -moz-animation-duration: 1s; 177 | -o-animation-duration: 1s; 178 | animation-duration: 1s; 179 | -webkit-animation-fill-mode: both; 180 | -moz-animation-fill-mode: both; 181 | -o-animation-fill-mode: both; 182 | animation-fill-mode: both; 183 | } 184 | 185 | @-webkit-keyframes shake { 186 | 0%, 100% {-webkit-transform: translateX(0);} 187 | 10%, 30%, 50%, 70%, 90% {-webkit-transform: translateX(-10px);} 188 | 20%, 40%, 60%, 80% {-webkit-transform: translateX(10px);} 189 | } 190 | 191 | @-moz-keyframes shake { 192 | 0%, 100% {-moz-transform: translateX(0);} 193 | 10%, 30%, 50%, 70%, 90% {-moz-transform: translateX(-10px);} 194 | 20%, 40%, 60%, 80% {-moz-transform: translateX(10px);} 195 | } 196 | 197 | @-o-keyframes shake { 198 | 0%, 100% {-o-transform: translateX(0);} 199 | 10%, 30%, 50%, 70%, 90% {-o-transform: translateX(-10px);} 200 | 20%, 40%, 60%, 80% {-o-transform: translateX(10px);} 201 | } 202 | 203 | @keyframes shake { 204 | 0%, 100% {transform: translateX(0);} 205 | 10%, 30%, 50%, 70%, 90% {transform: translateX(-10px);} 206 | 20%, 40%, 60%, 80% {transform: translateX(10px);} 207 | } 208 | 209 | .shake { 210 | -webkit-animation-name: shake; 211 | -moz-animation-name: shake; 212 | -o-animation-name: shake; 213 | animation-name: shake; 214 | } 215 | -------------------------------------------------------------------------------- /img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jschr/bootstrap-modal/7dbc60f45c6b3260fed3ef86990f672a777c21b2/img/ajax-loader.gif -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Bootstrap-modal by jschr 7 | 8 | 9 | 10 | 15 | 16 | 17 | 32 | 33 | 34 |
35 |
36 |
37 |

Bootstrap-Modal

38 |

Responsive, Stackable, AJAX and more.

39 |   47 | 49 | 51 |
52 |
53 |
54 |
55 |

56 | Using Bootstrap 3? Include the patch file before bootstrap-modal and check out the demo page. 57 |

58 |
59 |

Responsive

60 |
 61 |   				  
62 |
63 | 64 |
65 |
66 |
67 | 68 |
69 |

Stackable

70 |
         
 71 |   				  
72 |
73 | 74 |
75 |
76 |
77 | 78 | 87 | 88 |
89 |

AJAX (via jQuery.load)

90 |
 91 |   				  
92 |
93 | 94 |
95 |
96 |
97 | 98 |
99 |

Static Background with Animation

100 |

The shake animation is included in bootstrap-modal but any animation in animate.css is supported, just include the css file in your project.

101 |
102 |             
103 |
104 | 105 |
106 |
107 |
108 | 109 |
110 |

Full Width

111 |
112 |   				  
113 |
114 | 115 |
116 |
117 |
118 | 119 |
120 |

Long Modals

121 |
122 |             
123 |
124 | 125 |
126 |
127 |
128 | 129 |
130 |
131 |
132 | 133 | 134 | 168 | 169 | 183 | 184 | 202 | 203 | 220 | 221 | 236 | 237 | 246 | 247 | 260 | 261 | 276 | 277 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 324 | 325 | 326 | 348 | 349 | 377 | 380 | 381 | 382 | -------------------------------------------------------------------------------- /js/bootstrap-modal.js: -------------------------------------------------------------------------------- 1 | /* =========================================================== 2 | * bootstrap-modal.js v2.2.5 3 | * =========================================================== 4 | * Copyright 2012 Jordan Schroter 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | * ========================================================== */ 18 | 19 | 20 | !function ($) { 21 | 22 | "use strict"; // jshint ;_; 23 | 24 | /* MODAL CLASS DEFINITION 25 | * ====================== */ 26 | 27 | var Modal = function (element, options) { 28 | this.init(element, options); 29 | }; 30 | 31 | Modal.prototype = { 32 | 33 | constructor: Modal, 34 | 35 | init: function (element, options) { 36 | var that = this; 37 | 38 | this.options = options; 39 | 40 | this.$element = $(element) 41 | .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this)); 42 | 43 | this.options.remote && this.$element.find('.modal-body').load(this.options.remote, function () { 44 | var e = $.Event('loaded'); 45 | that.$element.trigger(e); 46 | }); 47 | 48 | var manager = typeof this.options.manager === 'function' ? 49 | this.options.manager.call(this) : this.options.manager; 50 | 51 | manager = manager.appendModal ? 52 | manager : $(manager).modalmanager().data('modalmanager'); 53 | 54 | manager.appendModal(this); 55 | }, 56 | 57 | toggle: function () { 58 | return this[!this.isShown ? 'show' : 'hide'](); 59 | }, 60 | 61 | show: function () { 62 | var e = $.Event('show'); 63 | 64 | if (this.isShown) return; 65 | 66 | this.$element.trigger(e); 67 | 68 | if (e.isDefaultPrevented()) return; 69 | 70 | this.escape(); 71 | 72 | this.tab(); 73 | 74 | this.options.loading && this.loading(); 75 | }, 76 | 77 | hide: function (e) { 78 | e && e.preventDefault(); 79 | 80 | e = $.Event('hide'); 81 | 82 | this.$element.trigger(e); 83 | 84 | if (!this.isShown || e.isDefaultPrevented()) return; 85 | 86 | this.isShown = false; 87 | 88 | this.escape(); 89 | 90 | this.tab(); 91 | 92 | this.isLoading && this.loading(); 93 | 94 | $(document).off('focusin.modal'); 95 | 96 | this.$element 97 | .removeClass('in') 98 | .removeClass('animated') 99 | .removeClass(this.options.attentionAnimation) 100 | .removeClass('modal-overflow') 101 | .attr('aria-hidden', true); 102 | 103 | $.support.transition && this.$element.hasClass('fade') ? 104 | this.hideWithTransition() : 105 | this.hideModal(); 106 | }, 107 | 108 | layout: function () { 109 | var prop = this.options.height ? 'height' : 'max-height', 110 | value = this.options.height || this.options.maxHeight; 111 | 112 | if (this.options.width){ 113 | this.$element.css('width', this.options.width); 114 | 115 | var that = this; 116 | this.$element.css('margin-left', function () { 117 | if (/%/ig.test(that.options.width)){ 118 | return -(parseInt(that.options.width) / 2) + '%'; 119 | } else { 120 | return -($(this).width() / 2) + 'px'; 121 | } 122 | }); 123 | } else { 124 | this.$element.css('width', ''); 125 | this.$element.css('margin-left', ''); 126 | } 127 | 128 | this.$element.find('.modal-body') 129 | .css('overflow', '') 130 | .css(prop, ''); 131 | 132 | if (value){ 133 | this.$element.find('.modal-body') 134 | .css('overflow', 'auto') 135 | .css(prop, value); 136 | } 137 | 138 | var modalOverflow = $(window).height() - 10 < this.$element.height(); 139 | 140 | if (modalOverflow || this.options.modalOverflow) { 141 | this.$element 142 | .css('margin-top', 0) 143 | .addClass('modal-overflow'); 144 | } else { 145 | this.$element 146 | .css('margin-top', 0 - this.$element.height() / 2) 147 | .removeClass('modal-overflow'); 148 | } 149 | }, 150 | 151 | tab: function () { 152 | var that = this; 153 | 154 | if (this.isShown && this.options.consumeTab) { 155 | this.$element.on('keydown.tabindex.modal', '[data-tabindex]', function (e) { 156 | if (e.keyCode && e.keyCode == 9){ 157 | var elements = [], 158 | tabindex = Number($(this).data('tabindex')); 159 | 160 | that.$element.find('[data-tabindex]:enabled:visible:not([readonly])').each(function (ev) { 161 | elements.push(Number($(this).data('tabindex'))); 162 | }); 163 | elements.sort(function(a,b){return a-b}); 164 | 165 | var arrayPos = $.inArray(tabindex, elements); 166 | if (!e.shiftKey){ 167 | arrayPos < elements.length-1 ? 168 | that.$element.find('[data-tabindex='+elements[arrayPos+1]+']').focus() : 169 | that.$element.find('[data-tabindex='+elements[0]+']').focus(); 170 | } else { 171 | arrayPos == 0 ? 172 | that.$element.find('[data-tabindex='+elements[elements.length-1]+']').focus() : 173 | that.$element.find('[data-tabindex='+elements[arrayPos-1]+']').focus(); 174 | } 175 | 176 | e.preventDefault(); 177 | } 178 | }); 179 | } else if (!this.isShown) { 180 | this.$element.off('keydown.tabindex.modal'); 181 | } 182 | }, 183 | 184 | escape: function () { 185 | var that = this; 186 | if (this.isShown && this.options.keyboard) { 187 | if (!this.$element.attr('tabindex')) this.$element.attr('tabindex', -1); 188 | 189 | this.$element.on('keyup.dismiss.modal', function (e) { 190 | e.which == 27 && that.hide(); 191 | }); 192 | } else if (!this.isShown) { 193 | this.$element.off('keyup.dismiss.modal') 194 | } 195 | }, 196 | 197 | hideWithTransition: function () { 198 | var that = this 199 | , timeout = setTimeout(function () { 200 | that.$element.off($.support.transition.end); 201 | that.hideModal(); 202 | }, 500); 203 | 204 | this.$element.one($.support.transition.end, function () { 205 | clearTimeout(timeout); 206 | that.hideModal(); 207 | }); 208 | }, 209 | 210 | hideModal: function () { 211 | var prop = this.options.height ? 'height' : 'max-height'; 212 | var value = this.options.height || this.options.maxHeight; 213 | 214 | if (value){ 215 | this.$element.find('.modal-body') 216 | .css('overflow', '') 217 | .css(prop, ''); 218 | } 219 | 220 | this.$element 221 | .hide() 222 | .trigger('hidden'); 223 | }, 224 | 225 | removeLoading: function () { 226 | this.$loading.remove(); 227 | this.$loading = null; 228 | this.isLoading = false; 229 | }, 230 | 231 | loading: function (callback) { 232 | callback = callback || function () {}; 233 | 234 | var animate = this.$element.hasClass('fade') ? 'fade' : ''; 235 | 236 | if (!this.isLoading) { 237 | var doAnimate = $.support.transition && animate; 238 | 239 | this.$loading = $('
') 240 | .append(this.options.spinner) 241 | .appendTo(this.$element); 242 | 243 | if (doAnimate) this.$loading[0].offsetWidth; // force reflow 244 | 245 | this.$loading.addClass('in'); 246 | 247 | this.isLoading = true; 248 | 249 | doAnimate ? 250 | this.$loading.one($.support.transition.end, callback) : 251 | callback(); 252 | 253 | } else if (this.isLoading && this.$loading) { 254 | this.$loading.removeClass('in'); 255 | 256 | var that = this; 257 | $.support.transition && this.$element.hasClass('fade')? 258 | this.$loading.one($.support.transition.end, function () { that.removeLoading() }) : 259 | that.removeLoading(); 260 | 261 | } else if (callback) { 262 | callback(this.isLoading); 263 | } 264 | }, 265 | 266 | focus: function () { 267 | var $focusElem = this.$element.find(this.options.focusOn); 268 | 269 | $focusElem = $focusElem.length ? $focusElem : this.$element; 270 | 271 | $focusElem.focus(); 272 | }, 273 | 274 | attention: function (){ 275 | // NOTE: transitionEnd with keyframes causes odd behaviour 276 | 277 | if (this.options.attentionAnimation){ 278 | this.$element 279 | .removeClass('animated') 280 | .removeClass(this.options.attentionAnimation); 281 | 282 | var that = this; 283 | 284 | setTimeout(function () { 285 | that.$element 286 | .addClass('animated') 287 | .addClass(that.options.attentionAnimation); 288 | }, 0); 289 | } 290 | 291 | 292 | this.focus(); 293 | }, 294 | 295 | 296 | destroy: function () { 297 | var e = $.Event('destroy'); 298 | 299 | this.$element.trigger(e); 300 | 301 | if (e.isDefaultPrevented()) return; 302 | 303 | this.$element 304 | .off('.modal') 305 | .removeData('modal') 306 | .removeClass('in') 307 | .attr('aria-hidden', true); 308 | 309 | if (this.$parent !== this.$element.parent()) { 310 | this.$element.appendTo(this.$parent); 311 | } else if (!this.$parent.length) { 312 | // modal is not part of the DOM so remove it. 313 | this.$element.remove(); 314 | this.$element = null; 315 | } 316 | 317 | this.$element.trigger('destroyed'); 318 | } 319 | }; 320 | 321 | 322 | /* MODAL PLUGIN DEFINITION 323 | * ======================= */ 324 | 325 | $.fn.modal = function (option, args) { 326 | return this.each(function () { 327 | var $this = $(this), 328 | data = $this.data('modal'), 329 | options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option); 330 | 331 | if (!data) $this.data('modal', (data = new Modal(this, options))); 332 | if (typeof option == 'string') data[option].apply(data, [].concat(args)); 333 | else if (options.show) data.show() 334 | }) 335 | }; 336 | 337 | $.fn.modal.defaults = { 338 | keyboard: true, 339 | backdrop: true, 340 | loading: false, 341 | show: true, 342 | width: null, 343 | height: null, 344 | maxHeight: null, 345 | modalOverflow: false, 346 | consumeTab: true, 347 | focusOn: null, 348 | replace: false, 349 | resize: false, 350 | attentionAnimation: 'shake', 351 | manager: 'body', 352 | spinner: '
', 353 | backdropTemplate: '