Skip to content
Browse files

Adding the jquery offline and json gems

  • Loading branch information...
1 parent 91f2cd9 commit e587a0627e5f230da9afd9335389a31cd05870c3 @Karunakar committed
View
62 app/assets/javascripts/application.js
@@ -7,24 +7,46 @@
//= require jquery
//= require jquery_ujs
//= require_tree .
-$(function () {
- $(windows.applicationCache.bind('error', function () {
- alert('There was an error when loading the cache manifest.');
- }))
- $(window.applicationCache).bind('error', function () {
- alert('There was an error when loading the cache manifest.');
- });
-
- $.getJSON("/items.json", function(data) {
- $("#items").html($("#item_template").tmpl(data));
- });
-
- $(window.applicationCache).bind('error', function () {
- alert('There was an error when loading the cache manifest.');
- });
-
- $.retrieveJSON("/items.json", function(data) {
- $("#items").html($("#item_template").tmpl(data));
- });
-});
+$(function() {
+ if ($.support.localStorage) {
+ $(window.applicationCache).bind("error", function() {
+ console.log("There was an error when loading the cache manifest.");
+ });
+ if (!localStorage["pendingItems"]) {
+ localStorage["pendingItems"] = JSON.stringify([]);
+ }
+ $.retrieveJSON("/items.json", function(data) {
+ var pendingItems = $.parseJSON(localStorage["pendingItems"]);
+ $("#items").html($("#item_template").tmpl(data.concat(pendingItems)));
+ });
+ $("#new_item").submit(function(e) {
+ var pendingItems = $.parseJSON(localStorage["pendingItems"]);
+ var item = {"data":$(this).serialize(), "item":{"name":$("#item_name").val()}};
+ $("#item_template").tmpl(item).appendTo("#items");
+ pendingItems.push(item);
+ localStorage["pendingItems"] = JSON.stringify(pendingItems)
+ $("#item_name").val("");
+ sendPending();
+ e.preventDefault();
+ });
+ function sendPending() {
+ if (window.navigator.onLine) {
+ var pendingItems = $.parseJSON(localStorage["pendingItems"]);
+ if (pendingItems.length > 0) {
+ var item = pendingItems[0];
+ $.post("/items", item.data, function(data) {
+ var pendingItems = $.parseJSON(localStorage["pendingItems"]);
+ pendingItems.shift();
+ localStorage["pendingItems"] = JSON.stringify(pendingItems)
+ setTimeout(sendPending, 100);
+ });
+ }
+ }
+ }
+ sendPending();
+ $(window).bind("online", sendPending);
+ } else {
+ alert("Try a different browser.");
+ }
+});
View
214 app/assets/javascripts/jquery.offline.js
@@ -1 +1,213 @@
-<html><body>You are being <a href="https://raw.github.com/wycats/jquery-offline/master/lib/jquery.offline.js">redirected</a>.</body></html>
+/*!
+ * jQuery Offline
+ * Version 1.0.0
+ *
+ * http://github.com/wycats/jquery-offline
+ *
+ * Copyright 2010, Yehuda Katz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * Date: Fri Jul 9 10:20:00 2010 -0800
+ */
+
+
+(function($) {
+
+ var prefix = "offline.jquery:",
+ mostRecent = null,
+ requesting = {};
+
+ // Allow the user to explicitly turn off localStorage
+ // before loading this plugin
+ if (typeof $.support.localStorage === "undefined") {
+ $.support.localStorage = !!window.localStorage;
+ }
+
+ // modified getJSON which uses ifModified: true
+ function getJSON(url, data, fn) {
+ if (jQuery.isFunction(data)) {
+ fn = data;
+ data = null;
+ }
+
+ var requestingKey = url + "?" + $.param(data || {});
+ if (requesting[requestingKey]) {
+ return false;
+ }
+
+ requesting[requestingKey] = true;
+
+ return jQuery.ajax({
+ type: "GET",
+ url: url,
+ data: data,
+ success: function(responseData, text) {
+ delete requesting[requestingKey];
+
+ // handle lack of response (error callback isn't called in this case)
+ if (undefined === responseData) {
+ if (!window.navigator.onLine) {
+ // requeue the request for the next time we come online
+ mostRecent = function() {
+ getJSON(url, data, fn);
+ };
+ }
+ return;
+ }
+
+ fn(responseData, text);
+ },
+ error: function() {
+ delete requesting[requestingKey];
+ },
+ dataType: "json",
+ ifModified: true
+ });
+ }
+
+ if ($.support.localStorage) {
+ // If localStorage is available, define jQuery.retrieveJSON
+ // and jQuery.clearJSON to operate in terms of the offline
+ // cache
+ // If the user comes online, run the most recent request
+ // that was queued due to the user being offline
+ $(window).bind("online", function() {
+ if (mostRecent) {
+ mostRecent();
+ }
+ });
+
+ // If the user goes offline, hide any loading bar
+ // the user may have created
+ $(window).bind("offline", function() {
+ jQuery.event.trigger("ajaxStop");
+ });
+
+ $.retrieveJSON = function(url, data, fn) {
+ // allow jQuery.retrieveJSON(url, fn)
+ if ($.isFunction(data)) {
+ fn = data;
+ data = {};
+ }
+
+ // remember when this request started so we can report
+ // the time when a follow-up Ajax request completes.
+ // this is especially important when the user comes
+ // back online, since retrieveDate may be minutes,
+ // hours or even days before the Ajax request finally
+ // completes
+ var retrieveDate = new Date;
+
+ // get a String value for the data passed in, and then
+ // use it to calculate a cache key
+ var param = $.param(data),
+ key = prefix + url + ":" + param,
+ text = localStorage[key],
+ dateString = localStorage[key + ":date"],
+ date = new Date(Date.parse(dateString));
+
+ function cleanupLocalStorage() {
+ // take all date keys and remove the oldest half
+ var dateKeys = [];
+ for (var i = 0; i < localStorage.length; ++i) {
+ var key = localStorage.key(i);
+ if (/:date$/.test(key)) {
+ dateKeys.push(key);
+ }
+ }
+ dateKeys.sort(function(a, b) {
+ var date_a = localStorage[a], date_b = localStorage[b];
+ return date_a < date_b ? -1 : (date_a > date_b ? +1 : 0);
+ });
+ for (var i = 0; i < dateKeys.length / 2; ++i) {
+ var key = dateKeys[i];
+ delete localStorage[key];
+ delete localStorage[key.substr(0, key.length - 5)]; // :date
+ }
+ }
+
+ // create a function that will make an Ajax request and
+ // store the result in the cache. This function will be
+ // deferred until later if the user is offline
+ function getData() {
+ getJSON(url, data, function(json, status) {
+ if ( status == 'notmodified' ) {
+ // Just return if the response has a 304 status code
+ return false;
+ }
+
+ while (true) {
+ try {
+ localStorage[key] = JSON.stringify(json);
+ localStorage[key + ":date"] = new Date;
+ break;
+ } catch (e) {
+ if (e.name == "QUOTA_EXCEEDED_ERR" || e.name ==
+ "NS_ERROR_DOM_QUOTA_REACHED") {
+ cleanupLocalStorage();
+ }
+ }
+ }
+
+ // If this is a follow-up request, create an object
+ // containing both the original time of the cached
+ // data and the time that the data was originally
+ // retrieved from the cache. With this information,
+ // users of jQuery Offline can provide the user
+ // with improved feedback if the lag is large
+ var data = text && { cachedAt: date, retrievedAt: retrieveDate };
+ fn(json, status, data);
+ });
+ }
+
+ // If there is anything in the cache, call the callback
+ // right away, with the "cached" status string
+ if( text ) {
+ var response = fn( $.parseJSON(text), "cached", { cachedAt: date } );
+ if( response === false ) return false;
+ }
+
+ // If the user is online, make the Ajax request right away;
+ // otherwise, make it the most recent callback so it will
+ // get triggered when the user comes online
+ if (window.navigator.onLine) {
+ getData();
+ } else {
+ mostRecent = getData;
+ }
+
+ return true;
+ };
+
+ // jQuery.clearJSON is simply a wrapper around deleting the
+ // localStorage for a URL/data pair
+ $.clearJSON = function(url, data) {
+ var param = $.param(data || {});
+ delete localStorage[prefix + url + ":" + param];
+ delete localStorage[prefix + url + ":" + param + ":date"];
+ };
+ } else {
+ // If localStorage is unavailable, just make all requests
+ // regular Ajax requests.
+ $.retrieveJSON = getJSON;
+ $.clearJSON = $.noop;
+ }
+
+})(jQuery);
View
8 app/assets/javascripts/json.js
@@ -1 +1,7 @@
-<html><body>You are being <a href="https://raw.github.com/wycats/jquery-offline/master/lib/json.js">redirected</a>.</body></html>
+if(!this.JSON)this.JSON={};
+(function(){function k(a){return a<10?"0"+a:a}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+k(this.getUTCMonth()+1)+"-"+k(this.getUTCDate())+"T"+k(this.getUTCHours())+":"+k(this.getUTCMinutes())+":"+k(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var n=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,o=
+/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,f,l,q={"\u0008":"\\b","\t":"\\t","\n":"\\n","\u000c":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},i;function p(a){o.lastIndex=0;return o.test(a)?'"'+a.replace(o,function(c){var d=q[c];return typeof d==="string"?d:"\\u"+("0000"+c.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+a+'"'}function m(a,c){var d,g,j=f,e,b=c[a];if(b&&typeof b==="object"&&typeof b.toJSON==="function")b=b.toJSON(a);
+if(typeof i==="function")b=i.call(c,a,b);switch(typeof b){case "string":return p(b);case "number":return isFinite(b)?String(b):"null";case "boolean":case "null":return String(b);case "object":if(!b)return"null";f+=l;e=[];if(Object.prototype.toString.apply(b)==="[object Array]"){g=b.length;for(a=0;a<g;a+=1)e[a]=m(a,b)||"null";c=e.length===0?"[]":f?"[\n"+f+e.join(",\n"+f)+"\n"+j+"]":"["+e.join(",")+"]";f=j;return c}if(i&&typeof i==="object"){g=i.length;for(a=0;a<g;a+=1){d=i[a];if(typeof d==="string")if(c=
+m(d,b))e.push(p(d)+(f?": ":":")+c)}}else for(d in b)if(Object.hasOwnProperty.call(b,d))if(c=m(d,b))e.push(p(d)+(f?": ":":")+c);c=e.length===0?"{}":f?"{\n"+f+e.join(",\n"+f)+"\n"+j+"}":"{"+e.join(",")+"}";f=j;return c}}if(typeof JSON.stringify!=="function")JSON.stringify=function(a,c,d){var g;l=f="";if(typeof d==="number")for(g=0;g<d;g+=1)l+=" ";else if(typeof d==="string")l=d;if((i=c)&&typeof c!=="function"&&(typeof c!=="object"||typeof c.length!=="number"))throw new Error("JSON.stringify");return m("",
+{"":a})};if(typeof JSON.parse!=="function")JSON.parse=function(a,c){function d(g,j){var e,b,h=g[j];if(h&&typeof h==="object")for(e in h)if(Object.hasOwnProperty.call(h,e)){b=d(h,e);if(b!==undefined)h[e]=b;else delete h[e]}return c.call(g,j,h)}a=String(a);n.lastIndex=0;if(n.test(a))a=a.replace(n,function(g){return"\\u"+("0000"+g.charCodeAt(0).toString(16)).slice(-4)});if(/^[\],:{}\s]*$/.test(a.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,
+"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){a=eval("("+a+")");return typeof c==="function"?d({"":a},""):a}throw new SyntaxError("JSON.parse");}})();
View
7 app/controllers/items_controller.rb
@@ -1,10 +1,13 @@
class ItemsController < ApplicationController
# GET /items
# GET /items.json
- respond_to :json
+ #respond_to :json
def index
@items = Item.all
- respond_with(@items)
+ respond_to do |format|
+ format.html # show.html.erb
+ format.json
+ end
end
# GET /items/1
View
7 app/views/items/index.html.erb
@@ -22,10 +22,3 @@
<%= link_to 'New Item', new_item_path %>
-
-<script type="text/html" id="item_template">
- <li>${item.name}</li>
-</script>
-
-<ol id="items"> pppppppppppppp
-</ol>
View
2 app/views/layouts/application.html.erb
@@ -4,7 +4,7 @@
<title>RailsOffline</title>
<%= stylesheet_link_tag "application" %>
<%= javascript_include_tag "application" %>
- <%= javascript_include_tag "jquery.tmpl", "jquery.tmpl", "json",
+ <%= javascript_include_tag "jquery.tmpl", "json","jquery.offline"
"jquery.offline"%>
<%= csrf_meta_tags %>

0 comments on commit e587a06

Please sign in to comment.
Something went wrong with that request. Please try again.