').append($('
').val(item.text)));
+ });
+
+ $('#todo-items').empty().append(listItems).toggle(listItems.length > 0);
+ $('#summary').html('
' + todoItems.length + ' item(s)');
+ });
+ }
+
+ function getTodoItemId(formElement) {
+ return Number($(formElement).closest('li').attr('data-todoitem-id'));
+ }
+
+ // Handle insert
+ $('#add-item').submit(function(evt) {
+ var textbox = $('#new-item-text'),
+ itemText = textbox.val();
+ if (itemText !== '') {
+ todoItemTable.insert({ text: itemText, complete: false }).then(refreshTodoItems);
+ }
+ textbox.val('').focus();
+ evt.preventDefault();
+ });
+
+ // Handle update
+ $(document.body).on('change', '.item-text', function() {
+ var newText = $(this).val();
+ todoItemTable.update({ id: getTodoItemId(this), text: newText });
+ });
+
+ $(document.body).on('change', '.item-complete', function() {
+ var isComplete = $(this).prop('checked');
+ todoItemTable.update({ id: getTodoItemId(this), complete: isComplete }).then(refreshTodoItems);
+ });
+
+ // Handle delete
+ $(document.body).on('click', '.item-delete', function () {
+ todoItemTable.del({ id: getTodoItemId(this) }).then(refreshTodoItems);
+ });
+
+ // On initial load, start by fetching the current data
+ refreshTodoItems();
+});
\ No newline at end of file
diff --git a/quickstart/web/index.html b/quickstart/web/index.html
new file mode 100644
index 000000000..0ce73a32c
--- /dev/null
+++ b/quickstart/web/index.html
@@ -0,0 +1,36 @@
+
+
+
+
Todo list: ZUMOAPPNAME
+
+
+
+
+
+
+
+ Windows Azure
+ Mobile Services
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/quickstart/web/server/launch-linux.sh b/quickstart/web/server/launch-linux.sh
new file mode 100644
index 000000000..0f134022e
--- /dev/null
+++ b/quickstart/web/server/launch-linux.sh
@@ -0,0 +1,18 @@
+#!/bin/bash
+
+# Check that Python is available
+command -v python >/dev/null 2>&1 || {
+ echo >&2 "Cannot find python. Either:
+ - Install python
+ - Or, serve the quickstart files from an alternative web server such as Apache."
+ exit 1
+}
+
+# Go to the directory containing the www files (one level above where this script is)
+# and then start the simple web server
+pushd `dirname $0` > /dev/null
+cd ..
+python -m SimpleHTTPServer 8000
+
+# Finally, return to the original directory
+popd > /dev/null
diff --git a/quickstart/web/server/launch-mac.command b/quickstart/web/server/launch-mac.command
new file mode 100644
index 000000000..ece67179c
--- /dev/null
+++ b/quickstart/web/server/launch-mac.command
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+# This .command file is just a wrapper around launch-linux.sh that allows it to be
+# launched by double-clicking inside Finder on OS X
+`dirname $0`/launch-linux.sh
diff --git a/quickstart/web/server/launch-windows.lnk b/quickstart/web/server/launch-windows.lnk
new file mode 100644
index 000000000..11340ff1c
Binary files /dev/null and b/quickstart/web/server/launch-windows.lnk differ
diff --git a/quickstart/web/server/start-iisexpress.ps1 b/quickstart/web/server/start-iisexpress.ps1
new file mode 100644
index 000000000..c812a1b95
--- /dev/null
+++ b/quickstart/web/server/start-iisexpress.ps1
@@ -0,0 +1,17 @@
+# Ensure IIS Express is installed
+$programFiles = if ("${env:ProgramFiles(x86)}") { "${env:ProgramFiles(x86)}" } else { "${env:ProgramFiles}" }
+$iisExpress = Join-Path $programFiles "IIS Express\iisexpress.exe"
+if (-not (Test-Path $iisExpress)) {
+ Write-Warning "Cannot find IIS Express - please install it."
+ Write-Host "Looked for $iisExpress, but it does not exist."
+ cmd /c pause
+ Start-Process -FilePath "http://www.microsoft.com/web/gallery/install.aspx?appid=IISExpress"
+ return
+}
+
+# Launch IIS Express, serving files from the directory above where this script is
+$scriptDir = (Split-Path -Parent $MyInvocation.MyCommand.Definition)
+$wwwRoot = (Resolve-Path $scriptDir\..).Path
+Push-Location -Path (Split-Path -Parent $iisExpress)
+cmd /c iisexpress.exe /port:8000 /path:$wwwRoot
+Pop-Location
diff --git a/quickstart/web/styles.css b/quickstart/web/styles.css
new file mode 100644
index 000000000..290eba38b
--- /dev/null
+++ b/quickstart/web/styles.css
@@ -0,0 +1,34 @@
+/* Reset and define common styles */
+* { box-sizing: border-box; -moz-box-sizing: border-box; margin: 0; padding: 0; }
+body { font-family: Arial, Helvetica; background-color: #e0e0e0; }
+button { border: 1px solid #999; color: #555; background-color: #F4F4FA; padding: 0 10px; }
+button:hover { background-color: white; }
+input[type=text], input:not([type]) { padding: 0 10px; text-overflow: ellipsis; }
+
+/* Main page structure and masthead style */
+#wrapper { max-width: 800px; margin: auto; padding: 20px; }
+article { background-color: white; box-shadow: 0 0 12px rgba(0, 0, 0, 0.75); border-radius: 10px; }
+header { background-color: #71BCFA; padding: 20px; border-top-left-radius: 10px; border-top-right-radius: 10px; }
+header h1 { text-transform: uppercase; font-weight: normal; color: #545353; font-size: 28px; }
+header h2 { text-transform: uppercase; font-weight: normal; color: white; font-size: 20px; }
+#summary { text-align: center; padding: 8px 0; }
+
+/* "Add new" form */
+#add-item { height: 40px; margin: 17px 0 5px 0; font-size: 1.1em }
+#add-item div { overflow: hidden; }
+#add-item button { float: right; margin-left: 10px; padding: 0 10px; height: 100%; border-radius: 4px; }
+#new-item-text { width: 100%; height: 40px; border: 1px solid #999; font-size: 1em; border-radius: 4px; }
+
+/* List of items */
+#todo-items li { list-style-type: none; height: 36px; padding: 0px 5px; border-bottom: 1px solid #dadada; }
+.item-complete { float: left; margin: 0 8px 0 15px; height: 100%; }
+.item-delete { float: right; margin: 5px; margin-right: 15px; height: 26px; }
+
+/* Textboxes in list of items */
+#todo-items li div { overflow: hidden; padding: 5px 2px; }
+.item-text { width: 100%; height: 26px; line-height: 24px; border: 1px solid transparent; background-color: transparent; }
+.item-text:focus, .item-text:hover { border-color: #aaa; background-color: #FFC; }
+
+/* Footer */
+footer { text-align: center; font-size: 0.8em; margin-top: 20px; }
+footer a { color: #666; }