This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
Wen-Tien Chang (author)
Fri Apr 04 00:18:29 -0700 2008
commit bcc0c3bcdbca4e7c0e18f76e305dde731ffb4b86
tree 825503befbf61ab21e583ad5a85cdf33ebe2e43c
parent 2aec2f444093983d2db49e312ad4526f0f7fee01
tree 825503befbf61ab21e583ad5a85cdf33ebe2e43c
parent 2aec2f444093983d2db49e312ad4526f0f7fee01
spakit /
README
Author:: Wen-Tien Chang(mailto:ihower@gmail.com), hlb(mailto:hlb@handlino.com) Copyright:: Copyright (c) 2007 Handlino Inc. License:: Distributed under the New BSD License == Description == Spakit is a plugin that makes it very easy to turn your Rails App Into a "single page application" (SPA). To enable SPA, simply install the plug-in, create a spakit layout and use Spakit helper. Don't need modify any model/controller code... ;) Spakit will send xhr request(i.e. prototype's Ajax.Updater ) with ?layout=spakit, and controller return HTML with spakit layout. Note that spakit_form_for not support file upload submit. By the way, Message plugin is another SPA plugin,using different approach. == Usage == For now, Spakit provide three helper: * spakit_link_to, just like remote_link_to * spakit_form_for, just like form_for, but you must specify :url * spakit_form_tag, just like form_tag by default spakit will replace HTML element called #content. == Layout code example == You should write flash message here because we often place that in application layout. # /view/layouts/spakit.rhtml <p><%= flash[:notice] %></p> <%= yield %> == History Bookmarks == We recommend Really Simple History(RSH) library to handle browser forward/back. Example code: # environment.rb module SpakitHelper @@spa_options = { :update => 'content-region', :loading => 'SPA.loading', :complete => 'SPA.complete' } end # application.js # We use jquery syntax, you can use prototype to define your function. var $j = jQuery.noConflict(); (function($) { SPA = { currentHash: null, currentLocation: null, init: function() { if ( $('#waiting-message').length == 0 ) { $('<div id="waiting-message"><img src="/images/ajax-loader.gif"></div>').appendTo('#bd'); $('#waiting-message').hide(); } }, loading: function() { this.init(); $('#waiting-message').show(); }, hide: function() { $('#waiting-message').hide(); }, historyChange: function(newLocation, historyData, isFresh) { if (isFresh == null) { if (historyStorage.hasKey(newLocation)) { if (newLocation == "start") { newLocation = location.pathname; } $.ajax({ type: "GET", url: newLocation, data: { layout: "spakit" }, beforeSend: function(){ SPA.loading(); }, complete: function(res, status){ if ( status == "success" || status == "notmodified" ) { $('#content-region').html(res.responseText); } SPA.hide(); } }); } } else { /* new data */ dhtmlHistory.add(newLocation, historyData); } }, complete: function(newLocation) { this.historyChange(newLocation, "", true); this.hide(); } }; SPA.currentHash = window.location.hash; if (SPA.currentHash.length) { if (SPA.currentHash.charAt(0) == '#' && SPA.currentHash.charAt(1) == '/') { SPA.currentLocation = SPA.currentHash.slice(1); } } $(document).ready(function(){ dhtmlHistory.initialize(); if (SPA.currentLocation) { if (SPA.currentLocation != '#start') { window.location.href = SPA.currentLocation; } } else { dhtmlHistory.addListener(SPA.historyChange); if (dhtmlHistory.isFirstLoad()) { dhtmlHistory.add("start", ""); } } }); })(jQuery); window.dhtmlHistory.create({ toJSON: function(o) { return JSON.stringify(o); }, fromJSON: function(s) { return JSON.parse(s); } });








