Permalink
Browse files

Merge remote branch 'remotes/rsaccon/master' into integration

  • Loading branch information...
2 parents 3501500 + fce3a57 commit bb30e95b4f10b41e8c872f5859f7f6294d892cc8 @zefhemel zefhemel committed Nov 3, 2010
View
@@ -38,6 +38,10 @@ There are a few `persistence.js` plug-ins available that add functionality:
the database schema), see `docs/migrations.md` for more information.
* `persistence.sync.js`, supports database synchronization with a
remote server, see `docs/sync.md` for more information.
+* `jquery.persistence.js`, adds jQuery integration, including
+ jQuery-mobile ajax request interception and re-routing to persistencejs,
+ see `docs/jquery.md` for more information and `demo/jquerymobile` for a
+ simple demo.
A Brief Intro to Async Programming
----------------------------------
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Form submission</title>
+</head>
+<body>
+
+<div data-role="page">
+
+ <div data-role="header">
+ <h1>Sample form response</h1>
+ </div><!-- /header -->
+
+ <div data-role="content">
+ <h1>Fake response:</h1>
+ <h2>You choose:</h2>
+ <h3>=> see url</h3>
+ </div><!-- /content -->
+
+</div><!-- /page -->
+
+</body>
+</html>
@@ -3,9 +3,8 @@
<head>
<title>jQuery mobile / persistencejs integration</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.css" />
- <script src="http://code.jquery.com/jquery-1.4.3.min.js"></script>
- <script src="http://code.jquery.com/mobile/1.0a1/jquery.mobile-1.0a1.min.js"></script>
+ <link rel="stylesheet" href="http://jquerymobile.com/test/themes/default" />
+ <script src="http://jquerymobile.com/test/js/all"></script>
<script src="http://code.google.com/apis/gears/gears_init.js"></script>
<script src="../../lib/persistence.js"></script>
<script src="../../lib/persistence.store.sql.js"></script>
@@ -18,13 +17,15 @@
} else {
persistence.store.memory.config(persistence);
}
- var Doc = persistence.define('Docs', {
+ persistence.define('Docs', {
path: "TEXT",
- data: "TEXT",
- mime: "TEXT"
+ data: "TEXT"
+ });
+ persistence.define('Orderform', {
+ shipping: "TEXT"
});
- persistence.pathPrefix = "demo-pages";
persistence.schemaSync();
+ persistence.jqmUrlPathPrefix = "demo-pages";
</script>
</head>
<body>
@@ -36,7 +37,21 @@
<li data-role="list-divider">Pages</li>
<li><a href="demo-pages/docs/foo.html">Foo</a></li>
<li><a href="demo-pages/docs/bar.html">Bar</a></li>
- </ul>
+ </ul>
+ <form action="demo-pages/orderform/form-get-response.html" method="get">
+ <fieldset>
+ <div data-role="fieldcontain">
+ <label for="shipping" class="select">Formsubmission (GET):</label>
+ <select name="shipping" id="shipping">
+ <option value="Standard shipping">Standard: 7 day</option>
+ <option value="Rush shipping">Rush: 3 days</option>
+ <option value="Express shipping">Express: next day</option>
+ <option value="Overnight shipping">Overnight</option>
+ </select>
+ </div>
+ <button type="submit" data-theme="a">Submit</button>
+ </fieldset>
+ </form>
<a href="#" onclick="persistence.reset();persistence.schemaSync();" data-role="button">Reset DB</a>
</div>
</div>
View
@@ -5,7 +5,7 @@ allows the usage of jquery notation for crossbrowser-access of
persistencejs entities.
Example
---------
+-------
Simple example:
@@ -23,3 +23,48 @@ Simple example:
console.log($(user).data('firstname')); // => Mike
You can find more examples in `test/test.persistence-jquery.js`.
+
+
+## jQuery mobile integration
+jQuery mobile (jqm) ajax request re-routing to persitencejs for:
+
+* html page loading (caches the page in local DB)
+* form submission
+
+re-routed URL paths have the following format:
+
+ optional/path/prefix / entity-name / path/to/response-template-key
+
+URL needs to match the following criteria for re-routing:
+
+* path prefix must be equal `persistence.jqmUrlPathPrefix`
+* entity with given entity-name must exist
+
+Global settings (and it's default values):
+
+ persistence.jqmUrlPathPrefix = "";
+ persistence.jqmTemplateKeyField = "path"; // (Page entity template-key field name)
+ persistence.jqmDataField`= "data"; // (Page entity template data field name)
+
+**Images need to be embedded into HTML response via data URL's**
+
+Ajax page loading example:
+
+ URL: "docs_controller/path/docs/about/intro.html"
+ persistence.jqmUrlPathPrefix = "docs_controller/path"
+ => entity name: "Docs"
+ => templateKey: "about/intro.html"
+
+Ajax form submission examples:
+
+ URL (GET): "form_controller/path/orderform/response.html?shipment=express"
+ persistence.jqmUrlPathPrefix = "form_controller/path"
+ => entity name: "Orderform"
+ => entity fields: retrieved from URL
+ => templateKey: "response.html"
+
+ URL (POST): "form_controller/path/orderform/response.html"
+ persistence.jqmUrlPathPrefix = "form_controller/path"
+ => entity name: "Orderform"
+ => entity fields: retrieved from POST data
+ => templateKey: "response.html"
View
@@ -24,12 +24,12 @@
*/
-if(!window.jQuery) {
- throw "jQuery should be loaded before persistence.jquery.js"
+if (!window.jQuery) {
+ throw "jQuery should be loaded before persistence.jquery.js";
}
-if(!window.persistence) {
- throw "persistence.js should be loaded before persistence.jquery.js"
+if (!window.persistence) {
+ throw "persistence.js should be loaded before persistence.jquery.js";
}
/**
@@ -63,33 +63,7 @@ persistence.get = function(arg1, arg2) {
return (typeof val === "function") ? val() : val;
};
-/**
- * default implementation for converting an URL into an object which
- * describes the entity for re-routing ajax calls to persitencejs
- * Example URL: "rel/path/to/docs/about/intro.html"
- * persistence.pathPrefix = "rel/path/to"
- * => name: "Docs"
- * => path: "about/intro.html"
- * (Images need to be embedded into HTML via data URL's)
- */
-persistence.pathPrefix = "";
-persistence.entityDescription = function(url) {
- if ((persistence.pathPrefix.length > 0) && (persistence.pathPrefix.length < url.length)) {
- var parts = url.substring(persistence.pathPrefix.length).split("/");
- return (parts.length == 0) ? null : {
- name: parts[1].charAt(0).toUpperCase() + parts[1].substring(1),
- pathName: "path",
- pathValue: parts.slice(2).join('/'),
- dataName: "data"
- };
- } else {
- return null
- }
-};
-/**
- * jquery stuff
- */
(function($){
var originalDataMethod = $.fn.data;
@@ -107,35 +81,109 @@ persistence.entityDescription = function(url) {
};
if ($.mobile && window.openDatabase) {
+ persistence.jqmUrlPathPrefix = "";
+ persistence.jqmTemplateKeyField = "path";
+ persistence.jqmDataField = "data";
+
var originalAjaxMethod = $.ajax;
+ function anylizeRequest(settings) {
+ var arr = settings.url.split('?');
+ var parts, name, url = arr[0];
+ if (persistence.jqmUrlPathPrefix.length == 0) {
+ parts = url.split("/");
+ } else if ((persistence.jqmUrlPathPrefix.length > 0)
+ && (persistence.jqmUrlPathPrefix.length < url.length)
+ && (url.match("^" + persistence.jqmUrlPathPrefix) == persistence.jqmUrlPathPrefix)) {
+ parts = url.substring(persistence.jqmUrlPathPrefix.length).split("/");
+ } else {
+ return null ;
+ }
+ if ((parts[0] == "") && (parts.length > 0)) {
+ parts = parts.slice(1);
+ }
+ name = parts[0].charAt(0).toUpperCase() + parts[0].substring(1);
+ if (persistence.isDefined(name)) {
+ if ((settings.type == "post") || ((settings.type == "get") && (arr.length > 1))) {
+ // ajax form submission
+ var data = {}, qs = (settings.type == "post") ? settings.data : arr[1] ;
+ qs.replace(/(?:^|&)([^&=]*)=?([^&]*)/g, function ( $0, $1, $2 ) {
+ if ($1) {
+ data[$1] = $2;
+ }
+ });
+ return {
+ isFormSubmission: true,
+ name: name,
+ templateKey: parts.slice(1).join('/'),
+ data: data
+ };
+ } else {
+ // ajax page
+ return {
+ name: name,
+ templateKey: parts.slice(1).join('/')
+ };
+ }
+ } else {
+ return null;
+ }
+ }
+
$.ajax = function(settings) {
- var descr = persistence.entityDescription(settings.url);
- if (descr === null) {
+ var info = anylizeRequest(settings);
+ if (info === null) {
originalAjaxMethod(settings);
} else {
- var Entity = persistence.define(descr.name);
- Entity.findBy(descr.pathName, descr.pathValue, function(hit){
- if (hit) {
- if (settings.success)
- settings.success(hit[descr.dataName]());
+ var Entity = persistence.define(info.name);
+ if (info.isFormSubmission) {
+ var persist = function(data) {
+ var obj = {};
+ for (var i in data) {
+ if (data.hasOwnProperty(i)) {
+ obj[i] = data[i];
+ }
+ }
+ var entity = new Entity(obj);
+ persistence.add(entity);
+ persistence.flush();
+ };
+
+ if (!navigator.hasOwnProperty("onLine") || navigator.onLine) {
+ originalAjaxMethod({
+ url: settings.url,
+ success: function(data) {
+ settings.success(data);
+ persist(info.data);
+ },
+ error: settings.error
+ });
} else {
- originalAjaxMethod({
- url: descr.pathValue,
- success: function(data) {
- settings.success(data);
- var obj = {};
- obj[descr.pathName] = descr.pathValue;
- obj[descr.dataName] = data;
- var entity = new Entity(obj);
- persistence.add(entity);
- persistence.flush();
- },
- error: settings.error
- });
+ persist(info.data);
}
- });
- }
+ } else { // ajax html page
+ Entity.findBy(persistence.jqmTemplateKeyField, info.templateKey, function(hit){
+ if (hit) {
+ if (settings.success)
+ settings.success(hit[persistence.jqmDataField]());
+ } else {
+ originalAjaxMethod({
+ url: settings.url,
+ success: function(data) {
+ settings.success(data);
+ var obj = {};
+ obj[persistence.jqmTemplateKeyField] = info.templateKey;
+ obj[persistence.jqmDataField] = data;
+ var entity = new Entity(obj);
+ persistence.add(entity);
+ persistence.flush();
+ },
+ error: settings.error
+ });
+ }
+ });
+ }
+ }
};
}
View
@@ -197,6 +197,17 @@ persistence.get = function(arg1, arg2) {
};
/**
+ * Checks whether an entity exists
+ *
+ * @param entityName
+ * the name of the entity (also the table name in the database)
+ * @return `true` if the entity exists, otherwise `false`
+ */
+ persistence.isDefined = function (entityName) {
+ return !!entityMeta[entityName];
+ }
+
+ /**
* Define a mixin
*
* @param mixinName

0 comments on commit bb30e95

Please sign in to comment.