ソースを参照

Improve accessibility (per Bootstrap recommendations) + update examples

breity 11 年 前
コミット
58b05daff4

+ 17 - 5
dist/js/bootstrap-dialog.js

@@ -103,7 +103,8 @@
         spinicon: BootstrapDialog.ICON_SPINNER,
         autodestroy: true,
         draggable: false,
-        animate: true
+        animate: true,
+        description: ''
     };
 
     /**
@@ -187,8 +188,8 @@
             return this;
         },
         createModal: function() {
-            var $modal = $('<div class="modal" tabindex="-1"></div>');
-            $modal.prop('id', this.getId());
+            var $modal = $('<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"></div>');
+            $modal.prop('id', this.getId()).attr('aria-labelledby', this.getId() + '_title');
 
             return $modal;
         },
@@ -342,7 +343,7 @@
         updateTitle: function() {
             if (this.isRealized()) {
                 var title = this.getTitle() !== null ? this.createDynamicContent(this.getTitle()) : this.getDefaultText();
-                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title);
+                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title).prop('id', this.getId() + '_title');
             }
 
             return this;
@@ -473,6 +474,14 @@
         setAutodestroy: function(autodestroy) {
             this.options.autodestroy = autodestroy;
         },
+        getDescription: function() {
+            return this.options.description;
+        },
+        setDescription: function(description) {
+            this.options.description = description;
+
+            return this;
+        },
         getDefaultText: function() {
             return BootstrapDialog.DEFAULT_TEXTS[this.getType()];
         },
@@ -838,6 +847,9 @@
             this.getModal().addClass(BootstrapDialog.NAMESPACE)
             .addClass(this.getSize())
             .addClass(this.getCssClass());
+            if(this.getDescription()){
+            	this.getModal().attr('aria-describedby', this.getDescription());
+            }
             this.getModalFooter().append(this.createFooterContent());
             this.getModalHeader().append(this.createHeaderContent());
             this.getModalBody().append(this.createBodyContent());
@@ -1030,4 +1042,4 @@
 
     return BootstrapDialog;
 
-}));
+}));

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/js/bootstrap-dialog.min.js


+ 17 - 5
examples/assets/bootstrap-dialog/js/bootstrap-dialog.js

@@ -103,7 +103,8 @@
         spinicon: BootstrapDialog.ICON_SPINNER,
         autodestroy: true,
         draggable: false,
-        animate: true
+        animate: true,
+        description: ''
     };
 
     /**
@@ -187,8 +188,8 @@
             return this;
         },
         createModal: function() {
-            var $modal = $('<div class="modal" tabindex="-1"></div>');
-            $modal.prop('id', this.getId());
+            var $modal = $('<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"></div>');
+            $modal.prop('id', this.getId()).attr('aria-labelledby', this.getId() + '_title');
 
             return $modal;
         },
@@ -342,7 +343,7 @@
         updateTitle: function() {
             if (this.isRealized()) {
                 var title = this.getTitle() !== null ? this.createDynamicContent(this.getTitle()) : this.getDefaultText();
-                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title);
+                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title).prop('id', this.getId() + '_title');
             }
 
             return this;
@@ -473,6 +474,14 @@
         setAutodestroy: function(autodestroy) {
             this.options.autodestroy = autodestroy;
         },
+        getDescription: function() {
+            return this.options.description;
+        },
+        setDescription: function(description) {
+            this.options.description = description;
+
+            return this;
+        },
         getDefaultText: function() {
             return BootstrapDialog.DEFAULT_TEXTS[this.getType()];
         },
@@ -838,6 +847,9 @@
             this.getModal().addClass(BootstrapDialog.NAMESPACE)
             .addClass(this.getSize())
             .addClass(this.getCssClass());
+            if(this.getDescription()){
+            	this.getModal().attr('aria-describedby', this.getDescription());
+            }
             this.getModalFooter().append(this.createFooterContent());
             this.getModalHeader().append(this.createHeaderContent());
             this.getModalBody().append(this.createBodyContent());
@@ -1030,4 +1042,4 @@
 
     return BootstrapDialog;
 
-}));
+}));

ファイルの差分が大きいため隠しています
+ 1 - 1
examples/assets/bootstrap-dialog/js/bootstrap-dialog.min.js


+ 22 - 1
examples/index.html

@@ -643,6 +643,18 @@
         -->
     </div>
     
+    <h3>Adding a description to your dialog (for accessibility)</h3>
+    <p>This adds an 'aria-describedby' attribute to your dialog, which provides a description of the dialog for screen readers.</p>
+    <div class="source-code runnable">
+        <!--
+        BootstrapDialog.show({
+            title: 'Add Description',
+            message: 'The description is shown to screen readers.',
+            description: 'This is a Bootstrap Dialog'
+        });
+        -->
+    </div>
+    
     <h3>Data binding</h3>
     <div class="source-code runnable">
         <!--
@@ -941,7 +953,7 @@ BootstrapDialog.show({
 </div>
                     <strong>id</strong>: optional, if id is set, you can use dialogInstance.getButton(id) to get the button later. <br />
                     <strong>icon</strong>: optional, if set, the specified icon will be added to the button. <br />
-                    <strong>cssClass</strong>: optinal, additional css class to be added to the button. <br />
+                    <strong>cssClass</strong>: optional, additional css class to be added to the button. <br />
                     <strong>autospin</strong>: optinal, if it's true, after clicked the button a spinning icon appears. <br />
                     <strong>action</strong>: optional, if provided, the callback will be invoked after the button is clicked, and the dialog instance will be passed to the callback function.
                 </td>
@@ -1024,6 +1036,15 @@ BootstrapDialog.show({
                     When it's true, all modal stuff will be removed from the DOM tree after the dialog is popped down, set it to false if you need your dialog (same instance) pups up and down again and again.
                 </td>
             </tr>
+            <tr>
+                <td>description</td>
+                <td>
+                    String
+                </td>
+                <td>
+                    If provided, 'aria-describedby' attribute will be added to the dialog with the description string as its value.  This can improve accessibility, as the description can be read by screen readers.
+                </td>
+            </tr>
         </tbody>
             
     </table>

+ 17 - 5
src/js/bootstrap-dialog.js

@@ -103,7 +103,8 @@
         spinicon: BootstrapDialog.ICON_SPINNER,
         autodestroy: true,
         draggable: false,
-        animate: true
+        animate: true,
+        description: ''
     };
 
     /**
@@ -187,8 +188,8 @@
             return this;
         },
         createModal: function() {
-            var $modal = $('<div class="modal" tabindex="-1"></div>');
-            $modal.prop('id', this.getId());
+            var $modal = $('<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"></div>');
+            $modal.prop('id', this.getId()).attr('aria-labelledby', this.getId() + '_title');
 
             return $modal;
         },
@@ -342,7 +343,7 @@
         updateTitle: function() {
             if (this.isRealized()) {
                 var title = this.getTitle() !== null ? this.createDynamicContent(this.getTitle()) : this.getDefaultText();
-                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title);
+                this.getModalHeader().find('.' + this.getNamespace('title')).html('').append(title).prop('id', this.getId() + '_title');
             }
 
             return this;
@@ -473,6 +474,14 @@
         setAutodestroy: function(autodestroy) {
             this.options.autodestroy = autodestroy;
         },
+        getDescription: function() {
+            return this.options.description;
+        },
+        setDescription: function(description) {
+            this.options.description = description;
+
+            return this;
+        },
         getDefaultText: function() {
             return BootstrapDialog.DEFAULT_TEXTS[this.getType()];
         },
@@ -838,6 +847,9 @@
             this.getModal().addClass(BootstrapDialog.NAMESPACE)
             .addClass(this.getSize())
             .addClass(this.getCssClass());
+            if(this.getDescription()){
+            	this.getModal().attr('aria-describedby', this.getDescription());
+            }
             this.getModalFooter().append(this.createFooterContent());
             this.getModalHeader().append(this.createHeaderContent());
             this.getModalBody().append(this.createBodyContent());
@@ -1030,4 +1042,4 @@
 
     return BootstrapDialog;
 
-}));
+}));