diff --git a/examples/widgets/Dialogs.ipynb b/examples/widgets/Dialogs.ipynb
new file mode 100644
index 0000000..6e71286
--- /dev/null
+++ b/examples/widgets/Dialogs.ipynb
@@ -0,0 +1,200 @@
+{
+ "metadata": {
+ "name": ""
+ },
+ "nbformat": 3,
+ "nbformat_minor": 0,
+ "worksheets": [
+ {
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Simple example notebook that shows how one can use widgets to build custom dialogs."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "from IPython.html import widgets\n",
+ "from IPython.display import display"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 1
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "By using Bootstrap's modal class and ContainerWidgets, we can build a simple dialog window."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def scrub_text_html(text):\n",
+ " text = text.replace('&', '&')\n",
+ " text = text.replace(' ', ' ')\n",
+ " text = text.replace('<', '<')\n",
+ " text = text.replace('>', '>')\n",
+ " text = text.replace('\\n', '
\\n')\n",
+ " return text\n",
+ "\n",
+ "def create_dialog(title=None, on_hidden=None):\n",
+ " dialog = widgets.ContainerWidget(visible=False)\n",
+ " dialog_header = widgets.ContainerWidget(parent=dialog)\n",
+ " dialog_header_close = widgets.ButtonWidget(parent=dialog_header, description = '×')\n",
+ " dialog_header_label = widgets.StringWidget(parent=dialog_header, default_view_name='LabelView')\n",
+ " dialog_body = widgets.ContainerWidget(parent=dialog)\n",
+ " dialog_footer = widgets.ContainerWidget(parent=dialog)\n",
+ " \n",
+ " if title is None or title == '':\n",
+ " title = ' '\n",
+ " dialog_header_label.value = '
%s
' % scrub_text_html(title)\n",
+ " \n",
+ " def handle_close():\n",
+ " dialog.visible = False\n",
+ " if on_hidden is not None:\n",
+ " on_hidden(dialog)\n",
+ " dialog_header_close.on_click(handle_close)\n",
+ " \n",
+ " display(dialog)\n",
+ " \n",
+ " dialog_header.add_class('modal-header')\n",
+ " dialog_body.add_class('modal-body')\n",
+ " dialog_footer.add_class('modal-footer')\n",
+ " dialog.add_class('modal')\n",
+ " \n",
+ " dialog_header_close.remove_class('btn')\n",
+ " dialog_header_close.add_class('close')\n",
+ " \n",
+ " return dialog_body, dialog_footer, dialog\n"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 2
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Using this `show_dialog` method, custom dialogs can be made using widgets. Below is an example of a Yes/No dialog."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "# Since Python has a global thread lock, everything runs on a single thread.\n",
+ "# Because of this, we use an asynronous model (callbacks).\n",
+ "def show_yes_no(prompt, yes_callback=None, no_callback=None, title=None):\n",
+ " \n",
+ " def handle_hidden(dialog_window):\n",
+ " if no_callback is not None:\n",
+ " no_callback()\n",
+ " dialog_window.close()\n",
+ " \n",
+ " (dialog_body, dialog_footer, dialog_window) = create_dialog(title=title, on_hidden=handle_hidden)\n",
+ " \n",
+ " def handle_yes():\n",
+ " dialog_window.visible = False\n",
+ " if yes_callback is not None:\n",
+ " yes_callback()\n",
+ " dialog_window.close()\n",
+ " \n",
+ " def handle_no():\n",
+ " dialog_window.visible = False\n",
+ " handle_hidden(dialog_window)\n",
+ " \n",
+ " yes_button = widgets.ButtonWidget(parent=dialog_footer, description='Yes')\n",
+ " yes_button.on_click(handle_yes)\n",
+ " no_button = widgets.ButtonWidget(parent=dialog_footer, description='No')\n",
+ " no_button.on_click(handle_no)\n",
+ " prompt_label = widgets.StringWidget(parent=dialog_body, value=scrub_text_html(prompt), default_view_name='LabelView')\n",
+ " \n",
+ " display(yes_button)\n",
+ " display(no_button)\n",
+ " display(prompt_label)\n",
+ " \n",
+ " yes_button.add_class('btn-success')\n",
+ " no_button.add_class('btn-danger')\n",
+ " \n",
+ " dialog_window.visible=True\n",
+ " \n",
+ " "
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 3
+ },
+ {
+ "cell_type": "heading",
+ "level": 1,
+ "metadata": {},
+ "source": [
+ "Test"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "def yes():\n",
+ " show_yes_no(\"Do you want to show the dialog again?\", yes, title=\"Self displaying dialog\")\n",
+ "yes()"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 4
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Dialog result handlers can contain nested dialogs. The following example shows how syncronous logic can be simulated using closures."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "collapsed": false,
+ "input": [
+ "title = \"Interactive Story\"\n",
+ "def open_door():\n",
+ " show_yes_no(\"The house is empty. You are tired and decide to sleep. You live to see another day.\")\n",
+ "\n",
+ "def stay_outside():\n",
+ " def fight():\n",
+ " show_yes_no(\"You try to fight the wolves but die in the process.\", title=title)\n",
+ " \n",
+ " def panic():\n",
+ " def flight():\n",
+ " show_yes_no(\"You run as fast as you can. You manage to escape the\\n\" + \\\n",
+ " \"wolves but the cold is beginning to get to you. You\\n\" + \\\n",
+ " \"sit in the snow to take a nap. You freeze and die.\", title=title)\n",
+ " \n",
+ " show_yes_no(\"You panic. Do you enter the cabin now?\", open_door, flight, title=title)\n",
+ " \n",
+ " show_yes_no(\"A pack of wolves approach. Do you want to fight them?\", fight, panic, title=title)\n",
+ "\n",
+ "show_yes_no(\"You are standing outside in a blizzard on a cold winter night.\\n\" + \\\n",
+ " \"A warm cabin with the lights on is in front of you.\\n\\n\" + \\\n",
+ " \"Do you want to enter the cabin?\", open_door, stay_outside, title=title)\n"
+ ],
+ "language": "python",
+ "metadata": {},
+ "outputs": [],
+ "prompt_number": 5
+ }
+ ],
+ "metadata": {}
+ }
+ ]
+}
\ No newline at end of file