diff --git a/platypush/backend/http/static/js/application.js b/platypush/backend/http/static/js/application.js
index 83768316..8534fe3a 100644
--- a/platypush/backend/http/static/js/application.js
+++ b/platypush/backend/http/static/js/application.js
@@ -145,7 +145,7 @@ $(document).ready(function() {
     };
 
     var initModalOpenBindings = function() {
-        $('body').on('click touch', '[data-modal]', function(event) {
+        $('body').on('mouseup touchend', '[data-modal]', function(event) {
             var $source = $(event.target);
             var $modal = $($source.data('modal'));
             $modal.fadeIn();
@@ -153,11 +153,20 @@ $(document).ready(function() {
     };
 
     var initModalCloseBindings = function() {
-        $('body').on('click touch', '[data-dismiss-modal]', function(event) {
+        $('body').on('mouseup touchend', '[data-dismiss-modal]', function(event) {
             var $source = $(event.target);
             var $modal = $($source.data('dismiss-modal'));
             $modal.fadeOut();
         });
+
+        $('body').on('mouseup touchend', function(event) {
+            var $source = $(event.target);
+            if (!$source.parents('.modal').length
+                    && !$source.data('modal')
+                    && !$source.data('dismiss-modal')) {
+                $('.modal').filter(':visible').fadeOut();
+            }
+        });
     };
 
     var initModals = function() {
diff --git a/platypush/backend/http/static/js/dashboard.js b/platypush/backend/http/static/js/dashboard.js
index 2270a4c5..274cfa83 100644
--- a/platypush/backend/http/static/js/dashboard.js
+++ b/platypush/backend/http/static/js/dashboard.js
@@ -7,6 +7,21 @@ $(document).ready(function() {
             for (var key of Object.keys(event.args)) {
                 $widget.find('[data-bind=' + key + ']').text(event.args[key]);
             }
+        } else if (event.args.type == 'platypush.message.event.web.DashboardIframeUpdateEvent') {
+            var url = event.args.url;
+            var $modal = $('#iframe-modal');
+            var $iframe = $modal.find('iframe');
+            $iframe.attr('src', url);
+            $iframe.prop('width',  event.args.width  || '100%');
+            $iframe.prop('height', event.args.height || '600');
+
+            if ('timeout' in event.args) {
+                setTimeout(function() {
+                    $modal.fadeOut();
+                }, parseFloat(event.args.timeout) * 1000);
+            }
+
+            $modal.fadeIn();
         }
     };
 
diff --git a/platypush/backend/http/templates/dashboard.html b/platypush/backend/http/templates/dashboard.html
index ff77e030..5a5d7759 100644
--- a/platypush/backend/http/templates/dashboard.html
+++ b/platypush/backend/http/templates/dashboard.html
@@ -33,6 +33,14 @@
 
 <body>
     <main>
+        <!-- You can send events of type platypush.message.event.web.DashboardIframeUpdateEvent
+             to control what is shown in the optional iframe modal -->
+        <div id="iframe-modal" class="modal">
+            <div class="modal-container">
+                <iframe></iframe>
+            </div>
+        </div>
+
         <div id="widgets-container">
             {% set used_columns = [0] %}
             {% for widget_name, widget in config['widgets'].items() %}
diff --git a/platypush/message/event/web/__init__.py b/platypush/message/event/web/__init__.py
index e69de29b..14ed1eb8 100644
--- a/platypush/message/event/web/__init__.py
+++ b/platypush/message/event/web/__init__.py
@@ -0,0 +1,16 @@
+from platypush.message.event import Event
+
+
+class DashboardIframeUpdateEvent(Event):
+    """
+    Deliver a DashboardIframeUpdateEvent if you are using the web dashboard
+    and you want the connected web clients to show a certain URL in the iframe
+    modal window for (optionally) a certain time.
+    """
+
+    def __init__(self, url, width=None, height=None, timeout=None, *args, **kwargs):
+        super().__init__(url=url, width=width, height=height, timeout=timeout, *args, **kwargs)
+
+
+# vim:sw=4:ts=4:et:
+