ihower / spakit

SPAkit is a plugin that makes it very easy to turn your Rails App Into a "single page application" (SPA).

This URL has Read+Write access

spakit / README.txt
dea74c04 » Wen-Tien Chang 2008-04-08 Add hoe config for rubyforge 1 Author:: Wen-Tien Chang(mailto:ihower@handlino.com), hlb(mailto:hlb@handlino.com)
bcc0c3bc » Wen-Tien Chang 2008-04-04 initial import 2 Copyright:: Copyright (c) 2007 Handlino Inc.
3 License:: Distributed under the New BSD License
4
5 == Description ==
6 Spakit is a plugin that makes it very easy to turn your Rails App
7 Into a "single page application" (SPA).
8
9 To enable SPA, simply install the plug-in, create a spakit layout and use Spakit helper.
10 Don't need modify any model/controller code... ;)
11
12 Spakit will send xhr request(i.e. prototype's Ajax.Updater ) with ?layout=spakit,
13 and controller return HTML with spakit layout. Note that spakit_form_for not support file upload submit.
14
15 By the way, Message plugin is another SPA plugin,using different approach.
16
dea74c04 » Wen-Tien Chang 2008-04-08 Add hoe config for rubyforge 17 == Requirements
18 * Rails 2.0.2
19
20 == Install ==
21 * gem install spakit
22 * cd /your_app/vendor/plugin/
23 * gem unpack spakit
24
bcc0c3bc » Wen-Tien Chang 2008-04-04 initial import 25 == Usage ==
26
27 For now, Spakit provide three helper:
28
29 * spakit_link_to, just like remote_link_to
30 * spakit_form_for, just like form_for, but you must specify :url
31 * spakit_form_tag, just like form_tag
32
33 by default spakit will replace HTML element called #content.
34
35 == Layout code example ==
36 You should write flash message here because we often place that in application layout.
37
38 # /view/layouts/spakit.rhtml
39
40 <p><%= flash[:notice] %></p>
41 <%= yield %>
42
43 == History Bookmarks ==
44
45 We recommend Really Simple History(RSH) library to handle browser forward/back.
46
47 Example code:
48
49 # environment.rb
50
51 module SpakitHelper
52 @@spa_options = {
53 :update => 'content-region',
54 :loading => 'SPA.loading',
55 :complete => 'SPA.complete'
56 }
57 end
58
59 # application.js
60 # We use jquery syntax, you can use prototype to define your function.
61
62 var $j = jQuery.noConflict();
63
64 (function($) {
65 SPA = {
66 currentHash: null,
67 currentLocation: null,
68 init: function() {
69 if ( $('#waiting-message').length == 0 ) {
70 $('<div id="waiting-message"><img src="/images/ajax-loader.gif"></div>').appendTo('#bd');
71 $('#waiting-message').hide();
72 }
73 },
74 loading: function() {
75 this.init();
76 $('#waiting-message').show();
77 },
78 hide: function() {
79 $('#waiting-message').hide();
80 },
81 historyChange: function(newLocation, historyData, isFresh) {
82 if (isFresh == null) {
83 if (historyStorage.hasKey(newLocation)) {
84 if (newLocation == "start") {
85 newLocation = location.pathname;
86 }
87
88 $.ajax({
89 type: "GET",
90 url: newLocation,
91 data: { layout: "spakit" },
92 beforeSend: function(){ SPA.loading(); },
93 complete: function(res, status){
94 if ( status == "success" || status == "notmodified" ) {
95 $('#content-region').html(res.responseText);
96 }
97 SPA.hide();
98 }
99 });
100 }
101 } else {
102 /* new data */
103 dhtmlHistory.add(newLocation, historyData);
104 }
105 },
106 complete: function(newLocation) {
107 this.historyChange(newLocation, "", true);
108 this.hide();
109 }
110 };
111
112 SPA.currentHash = window.location.hash;
113 if (SPA.currentHash.length) {
114 if (SPA.currentHash.charAt(0) == '#' && SPA.currentHash.charAt(1) == '/') {
115 SPA.currentLocation = SPA.currentHash.slice(1);
116 }
117 }
118
119 $(document).ready(function(){
120 dhtmlHistory.initialize();
121 if (SPA.currentLocation) {
122 if (SPA.currentLocation != '#start') {
123 window.location.href = SPA.currentLocation;
124 }
125 } else {
126 dhtmlHistory.addListener(SPA.historyChange);
127 if (dhtmlHistory.isFirstLoad()) {
128 dhtmlHistory.add("start", "");
129 }
130 }
131 });
132
133 })(jQuery);
134
135 window.dhtmlHistory.create({
136 toJSON: function(o) {
137 return JSON.stringify(o);
138 },
139 fromJSON: function(s) {
140 return JSON.parse(s);
141 }
142 });