moving to vm on desktop
This commit is contained in:
parent
c15cb0813f
commit
b5c15da9ff
|
@ -0,0 +1,2 @@
|
||||||
|
---
|
||||||
|
BUNDLE_WITHOUT: ""
|
|
@ -0,0 +1,207 @@
|
||||||
|
# DO NOT MODIFY THIS FILE
|
||||||
|
|
||||||
|
require 'digest/sha1'
|
||||||
|
require "rubygems"
|
||||||
|
|
||||||
|
module Gem
|
||||||
|
class Dependency
|
||||||
|
if !instance_methods.map { |m| m.to_s }.include?("requirement")
|
||||||
|
def requirement
|
||||||
|
version_requirements
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Bundler
|
||||||
|
module SharedHelpers
|
||||||
|
|
||||||
|
def default_gemfile
|
||||||
|
gemfile = find_gemfile
|
||||||
|
gemfile or raise GemfileNotFound, "The default Gemfile was not found"
|
||||||
|
Pathname.new(gemfile)
|
||||||
|
end
|
||||||
|
|
||||||
|
def in_bundle?
|
||||||
|
find_gemfile
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def find_gemfile
|
||||||
|
return ENV['BUNDLE_GEMFILE'] if ENV['BUNDLE_GEMFILE']
|
||||||
|
|
||||||
|
previous = nil
|
||||||
|
current = File.expand_path(Dir.pwd)
|
||||||
|
|
||||||
|
until !File.directory?(current) || current == previous
|
||||||
|
filename = File.join(current, 'Gemfile')
|
||||||
|
return filename if File.file?(filename)
|
||||||
|
current, previous = File.expand_path("..", current), current
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_load_path
|
||||||
|
# handle 1.9 where system gems are always on the load path
|
||||||
|
if defined?(::Gem)
|
||||||
|
me = File.expand_path("../../", __FILE__)
|
||||||
|
$LOAD_PATH.reject! do |p|
|
||||||
|
next if File.expand_path(p).include?(me)
|
||||||
|
p != File.dirname(__FILE__) &&
|
||||||
|
Gem.path.any? { |gp| p.include?(gp) }
|
||||||
|
end
|
||||||
|
$LOAD_PATH.uniq!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def reverse_rubygems_kernel_mixin
|
||||||
|
# Disable rubygems' gem activation system
|
||||||
|
::Kernel.class_eval do
|
||||||
|
if private_method_defined?(:gem_original_require)
|
||||||
|
alias rubygems_require require
|
||||||
|
alias require gem_original_require
|
||||||
|
end
|
||||||
|
|
||||||
|
undef gem
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cripple_rubygems(specs)
|
||||||
|
reverse_rubygems_kernel_mixin
|
||||||
|
|
||||||
|
executables = specs.map { |s| s.executables }.flatten
|
||||||
|
|
||||||
|
:: Kernel.class_eval do
|
||||||
|
private
|
||||||
|
def gem(*) ; end
|
||||||
|
end
|
||||||
|
Gem.source_index # ensure RubyGems is fully loaded
|
||||||
|
|
||||||
|
::Kernel.send(:define_method, :gem) do |dep, *reqs|
|
||||||
|
if executables.include? File.basename(caller.first.split(':').first)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
opts = reqs.last.is_a?(Hash) ? reqs.pop : {}
|
||||||
|
|
||||||
|
unless dep.respond_to?(:name) && dep.respond_to?(:requirement)
|
||||||
|
dep = Gem::Dependency.new(dep, reqs)
|
||||||
|
end
|
||||||
|
|
||||||
|
spec = specs.find { |s| s.name == dep.name }
|
||||||
|
|
||||||
|
if spec.nil?
|
||||||
|
e = Gem::LoadError.new "#{dep.name} is not part of the bundle. Add it to Gemfile."
|
||||||
|
e.name = dep.name
|
||||||
|
e.version_requirement = dep.requirement
|
||||||
|
raise e
|
||||||
|
elsif dep !~ spec
|
||||||
|
e = Gem::LoadError.new "can't activate #{dep}, already activated #{spec.full_name}. " \
|
||||||
|
"Make sure all dependencies are added to Gemfile."
|
||||||
|
e.name = dep.name
|
||||||
|
e.version_requirement = dep.requirement
|
||||||
|
raise e
|
||||||
|
end
|
||||||
|
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
# === Following hacks are to improve on the generated bin wrappers ===
|
||||||
|
|
||||||
|
# Yeah, talk about a hack
|
||||||
|
source_index_class = (class << Gem::SourceIndex ; self ; end)
|
||||||
|
source_index_class.send(:define_method, :from_gems_in) do |*args|
|
||||||
|
source_index = Gem::SourceIndex.new
|
||||||
|
source_index.spec_dirs = *args
|
||||||
|
source_index.add_specs(*specs)
|
||||||
|
source_index
|
||||||
|
end
|
||||||
|
|
||||||
|
# OMG more hacks
|
||||||
|
gem_class = (class << Gem ; self ; end)
|
||||||
|
gem_class.send(:define_method, :bin_path) do |name, *args|
|
||||||
|
exec_name, *reqs = args
|
||||||
|
|
||||||
|
spec = nil
|
||||||
|
|
||||||
|
if exec_name
|
||||||
|
spec = specs.find { |s| s.executables.include?(exec_name) }
|
||||||
|
spec or raise Gem::Exception, "can't find executable #{exec_name}"
|
||||||
|
else
|
||||||
|
spec = specs.find { |s| s.name == name }
|
||||||
|
exec_name = spec.default_executable or raise Gem::Exception, "no default executable for #{spec.full_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
File.join(spec.full_gem_path, spec.bindir, exec_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
extend self
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Bundler
|
||||||
|
LOCKED_BY = '0.9.11'
|
||||||
|
FINGERPRINT = "bc067d01abbb21b054cfc123f404a7874dfc8f94"
|
||||||
|
AUTOREQUIRES = {:test=>[["faker", false], ["shoulda", false], ["factory_girl", false]], :default=>[["mysql", false], ["formtastic", false], ["paperclip", false], ["will_paginate", false], ["clearance", false]], :development=>[["mongrel", false]], :developemtn=>[["faker", false]]}
|
||||||
|
SPECS = [
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/faker-0.3.1.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/faker-0.3.1/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/mongrel-1.1.5.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/mongrel-1.1.5/lib", "/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/mongrel-1.1.5/ext"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/fastthread-1.0.7.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/fastthread-1.0.7/lib", "/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/fastthread-1.0.7/ext"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/mysql-2.8.1.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/mysql-2.8.1/lib", "/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/mysql-2.8.1/ext"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/shoulda-2.10.3.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/shoulda-2.10.3/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/formtastic-0.9.7.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/formtastic-0.9.7/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/rack-1.0.1.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/rack-1.0.1/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/gem_plugin-0.2.3.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/gem_plugin-0.2.3/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/cgi_multipart_eof_fix-2.5.0.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/cgi_multipart_eof_fix-2.5.0/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/paperclip-2.3.1.1.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/paperclip-2.3.1.1/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/will_paginate-2.3.12.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/will_paginate-2.3.12/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/factory_girl-1.2.3.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/factory_girl-1.2.3/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/actionpack-2.3.5.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/actionpack-2.3.5/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/daemons-1.0.10.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/daemons-1.0.10/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/clearance-0.8.8.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/clearance-0.8.8/lib"]},
|
||||||
|
{:loaded_from=>"/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/specifications/activesupport-2.3.5.gemspec", :load_paths=>["/Users/sdavis/.rvm/gems/ruby-1.8.7-p249/gems/activesupport-2.3.5/lib"]},
|
||||||
|
].map do |hash|
|
||||||
|
spec = eval(File.read(hash[:loaded_from]), binding, hash[:loaded_from])
|
||||||
|
spec.loaded_from = hash[:loaded_from]
|
||||||
|
spec.require_paths = hash[:load_paths]
|
||||||
|
spec
|
||||||
|
end
|
||||||
|
|
||||||
|
extend SharedHelpers
|
||||||
|
|
||||||
|
def self.match_fingerprint
|
||||||
|
print = Digest::SHA1.hexdigest(File.read(File.expand_path('../../Gemfile', __FILE__)))
|
||||||
|
unless print == FINGERPRINT
|
||||||
|
abort 'Gemfile changed since you last locked. Please `bundle lock` to relock.'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.setup(*groups)
|
||||||
|
match_fingerprint
|
||||||
|
clean_load_path
|
||||||
|
cripple_rubygems(SPECS)
|
||||||
|
SPECS.each do |spec|
|
||||||
|
Gem.loaded_specs[spec.name] = spec
|
||||||
|
$LOAD_PATH.unshift(*spec.require_paths)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.require(*groups)
|
||||||
|
groups = [:default] if groups.empty?
|
||||||
|
groups.each do |group|
|
||||||
|
(AUTOREQUIRES[group.to_sym] || []).each do |file, explicit|
|
||||||
|
if explicit
|
||||||
|
Kernel.require file
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Kernel.require file
|
||||||
|
rescue LoadError
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Setup bundle when it's required.
|
||||||
|
setup
|
||||||
|
end
|
|
@ -0,0 +1,23 @@
|
||||||
|
# A sample Gemfile
|
||||||
|
source :gemcutter
|
||||||
|
#
|
||||||
|
#gem "rails", "2.3.5"
|
||||||
|
|
||||||
|
gem 'clearance'
|
||||||
|
gem 'will_paginate'
|
||||||
|
|
||||||
|
gem 'paperclip'
|
||||||
|
gem 'formtastic'
|
||||||
|
gem 'mysql'
|
||||||
|
#gem "matthuhiggins-foreigner", :require => "foreigner"
|
||||||
|
|
||||||
|
|
||||||
|
group :test do
|
||||||
|
gem 'shoulda'
|
||||||
|
gem 'factory_girl'
|
||||||
|
gem 'faker', :group => [:test, :developemtn]
|
||||||
|
end
|
||||||
|
|
||||||
|
group :development do
|
||||||
|
gem 'mongrel'
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
---
|
||||||
|
dependencies:
|
||||||
|
faker:
|
||||||
|
group:
|
||||||
|
- :test
|
||||||
|
- :developemtn
|
||||||
|
version: ">= 0"
|
||||||
|
mongrel:
|
||||||
|
group:
|
||||||
|
- :development
|
||||||
|
version: ">= 0"
|
||||||
|
mysql:
|
||||||
|
group:
|
||||||
|
- :default
|
||||||
|
version: ">= 0"
|
||||||
|
shoulda:
|
||||||
|
group:
|
||||||
|
- :test
|
||||||
|
version: ">= 0"
|
||||||
|
formtastic:
|
||||||
|
group:
|
||||||
|
- :default
|
||||||
|
version: ">= 0"
|
||||||
|
factory_girl:
|
||||||
|
group:
|
||||||
|
- :test
|
||||||
|
version: ">= 0"
|
||||||
|
paperclip:
|
||||||
|
group:
|
||||||
|
- :default
|
||||||
|
version: ">= 0"
|
||||||
|
will_paginate:
|
||||||
|
group:
|
||||||
|
- :default
|
||||||
|
version: ">= 0"
|
||||||
|
clearance:
|
||||||
|
group:
|
||||||
|
- :default
|
||||||
|
version: ">= 0"
|
||||||
|
specs:
|
||||||
|
- faker:
|
||||||
|
version: 0.3.1
|
||||||
|
- fastthread:
|
||||||
|
version: 1.0.7
|
||||||
|
- mongrel:
|
||||||
|
version: 1.1.5
|
||||||
|
- mysql:
|
||||||
|
version: 2.8.1
|
||||||
|
- shoulda:
|
||||||
|
version: 2.10.3
|
||||||
|
- rack:
|
||||||
|
version: 1.0.1
|
||||||
|
- gem_plugin:
|
||||||
|
version: 0.2.3
|
||||||
|
- cgi_multipart_eof_fix:
|
||||||
|
version: 2.5.0
|
||||||
|
- formtastic:
|
||||||
|
version: 0.9.7
|
||||||
|
- will_paginate:
|
||||||
|
version: 2.3.12
|
||||||
|
- paperclip:
|
||||||
|
version: 2.3.1.1
|
||||||
|
- factory_girl:
|
||||||
|
version: 1.2.3
|
||||||
|
- daemons:
|
||||||
|
version: 1.0.10
|
||||||
|
- clearance:
|
||||||
|
version: 0.8.8
|
||||||
|
- actionpack:
|
||||||
|
version: 2.3.5
|
||||||
|
- activesupport:
|
||||||
|
version: 2.3.5
|
||||||
|
hash: bc067d01abbb21b054cfc123f404a7874dfc8f94
|
||||||
|
sources:
|
||||||
|
- Rubygems:
|
||||||
|
uri: http://gemcutter.org
|
|
@ -11,4 +11,6 @@ class ApplicationController < ActionController::Base
|
||||||
def set_page
|
def set_page
|
||||||
@page_title = "Collab"
|
@page_title = "Collab"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,11 +11,34 @@ class ProjectsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def join
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
@project.users << current_user
|
||||||
|
if @project.save
|
||||||
|
flash[:success] = "You have joined #{@project.name}"
|
||||||
|
else
|
||||||
|
flash[:error] = "There was a problem joining this project"
|
||||||
|
end
|
||||||
|
redirect_to project_path(@project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def leave
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
@project.users.delete current_user
|
||||||
|
if @project.save
|
||||||
|
flash[:success] = "You have been removed from #{@project.name}"
|
||||||
|
else
|
||||||
|
flash[:error] = "There was an error removing you form this project"
|
||||||
|
end
|
||||||
|
redirect_to project_path(@project)
|
||||||
|
end
|
||||||
|
|
||||||
# GET /projects/1
|
# GET /projects/1
|
||||||
# GET /projects/1.xml
|
# GET /projects/1.xml
|
||||||
def show
|
def show
|
||||||
@project = Project.find(params[:id], :include => [:users])
|
@project = Project.find(params[:id], :include => [:users, :wall_posts])
|
||||||
@tasks = @project.tasks.parents.paginate(:per_page => 30, :page => params[:page], :include => :tasks)
|
@tasks = @project.tasks.parents.paginate(:per_page => 30, :page => params[:page], :include => :tasks)
|
||||||
|
@wall_posts = @project.wall_posts.paginate(:per_page => 15, :page => params[:post_page])
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html # show.html.erb
|
format.html # show.html.erb
|
||||||
format.xml { render :xml => @project }
|
format.xml { render :xml => @project }
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
class WallController < ApplicationController
|
||||||
|
before_filter :authenticate, :load_project
|
||||||
|
|
||||||
|
def create
|
||||||
|
@wall = Wall.new(params[:wall])
|
||||||
|
@wall.project = @project
|
||||||
|
@wall.author = current_user
|
||||||
|
@wall.save
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def load_project
|
||||||
|
@project = Project.find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,2 +1,13 @@
|
||||||
module ProjectsHelper
|
module ProjectsHelper
|
||||||
|
|
||||||
|
def parse_wall_string(string)
|
||||||
|
user_matches = string.scan(/@([a-zA-Z_0-9]+)/).flatten
|
||||||
|
return string if user_matches.empty?
|
||||||
|
User.find_all_by_short_name(user_matches).each do |user|
|
||||||
|
string.gsub!("@#{user.short_name}", link_to("@#{user.short_name}", user_path(user.short_name)))
|
||||||
|
end
|
||||||
|
string
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module WallHelper
|
||||||
|
include ProjectsHelper
|
||||||
|
end
|
|
@ -1,5 +1,6 @@
|
||||||
class Project < ActiveRecord::Base
|
class Project < ActiveRecord::Base
|
||||||
has_many :tasks
|
has_many :tasks
|
||||||
|
has_many :wall_posts, :class_name => "Wall", :foreign_key => "project_id", :order => "created_at DESC"
|
||||||
belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
|
belongs_to :owner, :class_name => "User", :foreign_key => "owner_id"
|
||||||
validates_presence_of :name
|
validates_presence_of :name
|
||||||
has_and_belongs_to_many :users
|
has_and_belongs_to_many :users
|
||||||
|
|
|
@ -7,7 +7,7 @@ class Task < ActiveRecord::Base
|
||||||
named_scope :parents, :conditions => {:parent => nil}
|
named_scope :parents, :conditions => {:parent => nil}
|
||||||
#validations
|
#validations
|
||||||
validates_presence_of :name, :description, :project_id
|
validates_presence_of :name, :description, :project_id
|
||||||
validates_associated :project
|
|
||||||
validate :assignee_validation, :owner_validation
|
validate :assignee_validation, :owner_validation
|
||||||
|
|
||||||
def assignee_validation
|
def assignee_validation
|
||||||
|
|
|
@ -5,13 +5,29 @@ class User < ActiveRecord::Base
|
||||||
has_many :owned_tasks, :class_name => "Task", :foreign_key => "owner_id"
|
has_many :owned_tasks, :class_name => "Task", :foreign_key => "owner_id"
|
||||||
has_many :assigned_tasks, :class_name => "Task", :foreign_key => "assigned_id"
|
has_many :assigned_tasks, :class_name => "Task", :foreign_key => "assigned_id"
|
||||||
validates_uniqueness_of :short_name
|
validates_uniqueness_of :short_name
|
||||||
validates_presence_of :short_name
|
validates_presence_of :email, :password, :short_name
|
||||||
validates_format_of :phone, :with => /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/, :if => Proc.new {|user| !user.phone.blank?}
|
validates_format_of :phone, :with => /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/, :if => Proc.new {|user| !user.phone.blank?}
|
||||||
validates_format_of :mobile, :with => /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/, :if => Proc.new {|user| !user.mobile.blank?}
|
validates_format_of :mobile, :with => /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/, :if => Proc.new {|user| !user.mobile.blank?}
|
||||||
|
|
||||||
|
before_validation :set_short_name
|
||||||
|
|
||||||
|
def set_short_name
|
||||||
|
if short_name.blank?
|
||||||
|
short_name = email.split('@')[0]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def gravatar(size = 48)
|
def gravatar(size = 48)
|
||||||
hash = Digest::MD5.hexdigest email
|
hash = Digest::MD5.hexdigest email
|
||||||
"http://www.gravatar.com/avatar/#{hash}.jpg?s=#{size}"
|
"http://www.gravatar.com/avatar/#{hash}.jpg?s=#{size}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def send_post_notification(post)
|
||||||
|
project_id = post.project_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_project_notification(project)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
class Wall < ActiveRecord::Base
|
||||||
|
|
||||||
|
belongs_to :author, :class_name => "User", :foreign_key => "user_id"
|
||||||
|
belongs_to :project
|
||||||
|
|
||||||
|
after_create :check_for_mentions, :check_for_hash_tags
|
||||||
|
|
||||||
|
def check_for_mentions
|
||||||
|
mentions = text.scan(/@([a-zA-Z_0-9])/).flatten
|
||||||
|
User.find_all_by_short_name(mentions).each{ |user| user.send_post_notification(self) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_for_hash_tags
|
||||||
|
tags = text.scan(/#([a-zA-Z0-9_]+)/).flatten
|
||||||
|
send_notice_to_members(project) if tags.include?('project')
|
||||||
|
end
|
||||||
|
|
||||||
|
def send_notice_to_members(project)
|
||||||
|
project.users.each {|user| user.send_project_notification(project)}
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -1,15 +1,40 @@
|
||||||
<p>
|
<h1><%=h @project.name.titleize %></h1>
|
||||||
<b>Name:</b>
|
<p><%= link_to 'Edit', edit_project_path(@project) %></p>
|
||||||
<%=h @project.name %>
|
<div id='project_right'>
|
||||||
</p>
|
<div id='project_users'>
|
||||||
<div id='project_users'>
|
<h2>Users</h2>
|
||||||
<% @project.users.each do |user| %>
|
<% @project.users.each do |user| %>
|
||||||
<%= image_tag user.gravatar %> <%= link_to "@#{user.short_name}", user_path(user.short_name) %>
|
<div class='project_user_info'>
|
||||||
<% end %>
|
<%= image_tag user.gravatar %> <%= link_to "@#{user.short_name}", user_path(user.short_name) %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% unless @project.users.include?(current_user) %>
|
||||||
|
<%= link_to "Join Project", join_project_path(@project), :method => :post %>
|
||||||
|
<% else %>
|
||||||
|
<%= link_to "Leave Project", leave_project_path(@project), :method => :delete %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<h2>Wall</h2>
|
||||||
|
<div id='project_wall'>
|
||||||
|
<div id='add_post'>
|
||||||
|
<% remote_form_for :wall, :url => project_wall_index_path(@project) do |f| %>
|
||||||
|
<%= f.text_area :text, :cols => 35, :rows => 10, :id=> :new_post %>
|
||||||
|
<%= f.submit :Submit %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div id='post_list'>
|
||||||
|
<% @wall_posts.each do |post| %>
|
||||||
|
<%= render :partial => 'wall/wall_posts', :locals => {:post => post} %>
|
||||||
|
<% end %>
|
||||||
|
<%= will_paginate @wall_posts, :param_name => :post_page %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id='project_tasks'>
|
<div id='project_tasks'>
|
||||||
|
<h2>Tasks</h2>
|
||||||
<%= render :partial => 'tasks/task_list' %>
|
<%= render :partial => 'tasks/task_list' %>
|
||||||
|
<%= will_paginate @tasks %>
|
||||||
</div>
|
</div>
|
||||||
<%= will_paginate @tasks %>
|
<br style='clear:both'/>
|
||||||
<%= link_to 'Edit', edit_project_path(@project) %> |
|
|
||||||
<%= link_to 'Back', projects_path %>
|
<%= link_to 'Back', projects_path %>
|
|
@ -1,21 +1,23 @@
|
||||||
<% unless @tasks.empty? %>
|
<% unless @tasks.empty? %>
|
||||||
<table class='task_list'>
|
<table class='task_list' cellspacing='0' cellpadding='0'>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Project</th>
|
<th>Project</th>
|
||||||
<th>Description</th>
|
<th>Description</th>
|
||||||
<th>Children</th>
|
<th>Children</th>
|
||||||
|
<th> </th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<% @tasks.each do |task| %>
|
<% @tasks.each do |task| %>
|
||||||
<tr class="<%= cycle(:even, :odd)%>">
|
<tr class="<%= cycle(:even, :odd)%>">
|
||||||
<td><%=h task.name %></td>
|
<td><%= link_to h(task.name), project_task_path(@project, task) %></td>
|
||||||
<td><%= link_to h(task.project.name), project_path(task.project) %></td>
|
<td><%= link_to h(task.project.name), project_path(task.project) %></td>
|
||||||
<td><%=h task.description %></td>
|
<td><%=h truncate(task.description, :length => 158) %></td>
|
||||||
<td><%=h task.tasks.size %></td>
|
<td><%= link_to h(task.tasks.size), project_task_path(@project, task) %></td>
|
||||||
<td><%= link_to 'Show', project_task_path(@project, task) %></td>
|
<td>
|
||||||
<td><%= link_to 'Edit', edit_project_task_path(@project, task) %></td>
|
<%= link_to 'Edit', edit_project_task_path(@project, task) %>
|
||||||
<td><%= link_to 'Destroy', project_task_path(@project, task), :confirm => 'Are you sure?', :method => :delete %></td>
|
<%= link_to 'Destroy', project_task_path(@project, task), :confirm => 'Are you sure?', :method => :delete %>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<% end %>
|
<% end %>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,14 +1,11 @@
|
||||||
<p>
|
<h1><%=h @task.name %></h1>
|
||||||
<b>Name:</b>
|
|
||||||
<%=h @task.name %>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
<b>Project:</b>
|
<b>Project:</b>
|
||||||
<%=h @task.project.name %>
|
<%=h @task.project.name %>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p>
|
<p id='task_description'>
|
||||||
<b>Description:</b>
|
<b>Description:</b>
|
||||||
<%=h @task.description %>
|
<%=h @task.description %>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<div class='post'>
|
||||||
|
<%= image_tag post.author.gravatar(16), :alt => post.author.short_name %>
|
||||||
|
<%= parse_wall_string(post.text) %>
|
||||||
|
</div>
|
|
@ -0,0 +1,7 @@
|
||||||
|
if @wall.save
|
||||||
|
page.insert_html :prepend, :post_list, :partial => 'wall_posts', :locals => {:post => @wall }
|
||||||
|
page[:post_list].visual_effect :highlight
|
||||||
|
page[:new_post].val('')
|
||||||
|
else
|
||||||
|
page.alert("Wall post is invalid")
|
||||||
|
end
|
|
@ -108,3 +108,21 @@ end
|
||||||
|
|
||||||
# All that for this:
|
# All that for this:
|
||||||
Rails.boot!
|
Rails.boot!
|
||||||
|
|
||||||
|
class Rails::Boot
|
||||||
|
def run
|
||||||
|
load_initializer
|
||||||
|
extend_environment
|
||||||
|
Rails::Initializer.run(:set_load_path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def extend_environment
|
||||||
|
Rails::Initializer.class_eval do
|
||||||
|
old_load = instance_method(:load_environment)
|
||||||
|
define_method(:load_environment) do
|
||||||
|
Bundler.require :default, Rails.env
|
||||||
|
old_load.bind(self).call
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -2,11 +2,14 @@ ActionController::Routing::Routes.draw do |map|
|
||||||
Clearance::Routes.draw(map)
|
Clearance::Routes.draw(map)
|
||||||
map.user '/users/:id', :controller => :users, :action => :show
|
map.user '/users/:id', :controller => :users, :action => :show
|
||||||
map.user_inline_edit '/users/:id/inline', :controller => :users, :action => :inline, :conditions => { :method => :post }
|
map.user_inline_edit '/users/:id/inline', :controller => :users, :action => :inline, :conditions => { :method => :post }
|
||||||
|
map.join_project '/projects/:project_id/join', :controller => :projects, :action => :join, :conditions => {:method => :post}
|
||||||
|
map.leave_project '/projects/:project_id/leave', :controller => :projects, :action => :leave, :conditions => {:method => :delete}
|
||||||
#map.dashboard '/dashboard', :controller => :users, :action => :dashboard
|
#map.dashboard '/dashboard', :controller => :users, :action => :dashboard
|
||||||
|
|
||||||
|
|
||||||
map.resources :projects do |projects|
|
map.resources :projects do |projects|
|
||||||
projects.resources :tasks
|
projects.resources :tasks
|
||||||
|
projects.resources :wall
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateWalls < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :walls do |t|
|
||||||
|
t.belongs_to :project
|
||||||
|
t.text :text
|
||||||
|
t.belongs_to :user
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :walls
|
||||||
|
end
|
||||||
|
end
|
10
db/schema.rb
10
db/schema.rb
|
@ -9,7 +9,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20100305060621) do
|
ActiveRecord::Schema.define(:version => 20100312004836) do
|
||||||
|
|
||||||
create_table "projects", :force => true do |t|
|
create_table "projects", :force => true do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
|
@ -59,6 +59,14 @@ ActiveRecord::Schema.define(:version => 20100305060621) do
|
||||||
add_index "users", ["id", "confirmation_token"], :name => "index_users_on_id_and_confirmation_token"
|
add_index "users", ["id", "confirmation_token"], :name => "index_users_on_id_and_confirmation_token"
|
||||||
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
|
add_index "users", ["remember_token"], :name => "index_users_on_remember_token"
|
||||||
|
|
||||||
|
create_table "walls", :force => true do |t|
|
||||||
|
t.integer "project_id"
|
||||||
|
t.text "text"
|
||||||
|
t.integer "user_id"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
end
|
||||||
|
|
||||||
add_foreign_key "projects", "users", :name => "projects_owner_id_fk", :column => "owner_id"
|
add_foreign_key "projects", "users", :name => "projects_owner_id_fk", :column => "owner_id"
|
||||||
|
|
||||||
add_foreign_key "tasks", "users", :name => "tasks_owner_id_fk", :column => "owner_id"
|
add_foreign_key "tasks", "users", :name => "tasks_owner_id_fk", :column => "owner_id"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
require 'factory_girl'
|
||||||
|
require 'faker'
|
||||||
|
|
||||||
|
Factory.define :user do |f|
|
||||||
|
f.sequence(:email) { |n| "email_#{n}@localhost.com" }
|
||||||
|
f.sequence(:password) { |n| "password#{n}" }
|
||||||
|
f.sequence(:short_name) { |n| "short_#{n}" }
|
||||||
|
end
|
||||||
|
|
||||||
|
Factory.define :project do |f|
|
||||||
|
f.sequence(:name) {|n| "project #{n}"}
|
||||||
|
end
|
||||||
|
|
||||||
|
Factory.define :task do |f|
|
||||||
|
f.sequence(:name) {|n| "task #{n}"}
|
||||||
|
f.description Faker::Lorem.words(50)
|
||||||
|
end
|
||||||
|
|
||||||
|
Factory.define :wall do |f|
|
||||||
|
f.text "@short_2 This is a wall post of fun and goodness"
|
||||||
|
end
|
|
@ -1,7 +1,5 @@
|
||||||
path = File.join(RAILS_ROOT, 'factories')
|
|
||||||
require 'factory_girl'
|
require 'factory_girl'
|
||||||
["user", "task", "project"].each {|factory| require File.join(path, "#{factory}_factory")}
|
require 'factories/factories'
|
||||||
|
|
||||||
class FactoryLoader
|
class FactoryLoader
|
||||||
|
|
||||||
def self.up
|
def self.up
|
||||||
|
@ -30,6 +28,7 @@ class FactoryLoader
|
||||||
10.times do |i|
|
10.times do |i|
|
||||||
p = Factory.create(:project, :owner => user, :users => [user])
|
p = Factory.create(:project, :owner => user, :users => [user])
|
||||||
self.create_tasks(p, user)
|
self.create_tasks(p, user)
|
||||||
|
self.create_wall_posts(p)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -46,5 +45,11 @@ class FactoryLoader
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.create_wall_posts(project)
|
||||||
|
User.all.each do |user|
|
||||||
|
Factory.create(:wall, :author => user, :project => project)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
|
@ -1,5 +0,0 @@
|
||||||
require 'factory_girl'
|
|
||||||
|
|
||||||
Factory.define :project do |f|
|
|
||||||
f.sequence(:name) {|n| "project #{n}"}
|
|
||||||
end
|
|
|
@ -1,6 +0,0 @@
|
||||||
require 'factory_girl'
|
|
||||||
require 'faker'
|
|
||||||
Factory.define :task do |f|
|
|
||||||
f.sequence(:name) {|n| "task #{n}"}
|
|
||||||
f.description Faker::Lorem.paragraphs(1)
|
|
||||||
end
|
|
|
@ -1,8 +0,0 @@
|
||||||
require 'factory_girl'
|
|
||||||
|
|
||||||
|
|
||||||
Factory.define :user do |f|
|
|
||||||
f.sequence(:email) { |n| "email_#{n}@localhost.com" }
|
|
||||||
f.sequence(:password) { |n| "password#{n}" }
|
|
||||||
f.sequence(:short_name) { |n| "short_#{n}" }
|
|
||||||
end
|
|
|
@ -1,2 +1,3 @@
|
||||||
|
|
||||||
// Place your application-specific JavaScript functions and classes here
|
// Place your application-specific JavaScript functions and classes here
|
||||||
// This file is automatically included by javascript_include_tag :defaults
|
// This file is automatically included by javascript_include_tag :defaults
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1 +1 @@
|
||||||
(function($){$().ajaxSend(function(a,xhr,s){xhr.setRequestHeader("Accept","text/javascript, text/html, application/xml, text/xml, */*")})})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&field.type=="text"||field.type=="textarea"){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||self.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o){e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"()")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery);
|
(function($){$.ajaxSettings.accepts._default="text/javascript, text/html, application/xml, text/xml, */*"})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&(field.type=="text"||field.type=="textarea"||field.type=="password")){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){var observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||el.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o,options){if(options){speed=options.duration*1000}else{speed=null}e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"("+speed+")")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery);
|
|
@ -4,7 +4,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin-top:10px
|
margin:10px
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin:5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.flash {
|
div.flash {
|
||||||
|
@ -21,6 +25,11 @@ div#flash_error {
|
||||||
border:red 5px solid;
|
border:red 5px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#flash_failure{
|
||||||
|
color:red;
|
||||||
|
border:red 5px solid;
|
||||||
|
}
|
||||||
|
|
||||||
div#flash_notice {
|
div#flash_notice {
|
||||||
color:blue;
|
color:blue;
|
||||||
border:blue 5px solid;
|
border:blue 5px solid;
|
||||||
|
@ -31,6 +40,9 @@ div#flash_success {
|
||||||
border:green 5px solid;
|
border:green 5px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div#content {
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
|
||||||
table.task_list tr.odd{
|
table.task_list tr.odd{
|
||||||
background-color:#ddd;
|
background-color:#ddd;
|
||||||
|
@ -59,3 +71,47 @@ div#wrapper {
|
||||||
margin-top:30px;
|
margin-top:30px;
|
||||||
background-color:white;
|
background-color:white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Projects **/
|
||||||
|
|
||||||
|
div#project_right {
|
||||||
|
width:30%;
|
||||||
|
float:right;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#project_tasks {
|
||||||
|
float:left;
|
||||||
|
width:60%;
|
||||||
|
text-align:center;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.project_user_info a{
|
||||||
|
font-size:20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#post_list {
|
||||||
|
border:1px solid #ccc;
|
||||||
|
margin-top:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.post {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.task_list tr {
|
||||||
|
text-align:left;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.task_list tr td {
|
||||||
|
padding:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.task_list tr th {
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Tasks **/
|
||||||
|
|
||||||
|
div#task_description {
|
||||||
|
|
||||||
|
}
|
|
@ -1,13 +1 @@
|
||||||
Factory.sequence :email do |n|
|
|
||||||
"user#{n}@example.com"
|
|
||||||
end
|
|
||||||
|
|
||||||
Factory.define :user do |user|
|
|
||||||
user.email { Factory.next :email }
|
|
||||||
user.password { "password" }
|
|
||||||
user.password_confirmation { "password" }
|
|
||||||
end
|
|
||||||
|
|
||||||
Factory.define :email_confirmed_user, :parent => :user do |user|
|
|
||||||
user.email_confirmed { true }
|
|
||||||
end
|
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
||||||
|
|
||||||
|
one:
|
||||||
|
belongs_to:
|
||||||
|
text: MyText
|
||||||
|
|
||||||
|
two:
|
||||||
|
belongs_to:
|
||||||
|
text: MyText
|
|
@ -1,6 +1,12 @@
|
||||||
require 'test_helper'
|
require 'test_helper'
|
||||||
|
|
||||||
class ProjectsControllerTest < ActionController::TestCase
|
class ProjectsControllerTest < ActionController::TestCase
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@user = Factory(:user)
|
||||||
|
sign_in_as(@user)
|
||||||
|
end
|
||||||
|
|
||||||
test "should get index" do
|
test "should get index" do
|
||||||
get :index
|
get :index
|
||||||
assert_response :success
|
assert_response :success
|
||||||
|
@ -13,31 +19,32 @@ class ProjectsControllerTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should create project" do
|
test "should create project" do
|
||||||
assert_difference('Project.count') do
|
|
||||||
post :create, :project => { }
|
|
||||||
end
|
|
||||||
|
|
||||||
|
assert_difference('Project.count') do
|
||||||
|
post :create, :project => Factory.attributes_for(:project)
|
||||||
|
end
|
||||||
assert_redirected_to project_path(assigns(:project))
|
assert_redirected_to project_path(assigns(:project))
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should show project" do
|
test "should show project" do
|
||||||
get :show, :id => projects(:one).to_param
|
get :show, :id => Factory(:project).id
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should get edit" do
|
test "should get edit" do
|
||||||
get :edit, :id => projects(:one).to_param
|
get :edit, :id => Factory(:project).id
|
||||||
assert_response :success
|
assert_response :success
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should update project" do
|
test "should update project" do
|
||||||
put :update, :id => projects(:one).to_param, :project => { }
|
put :update, :id => Factory(:project).id, :project => Factory.attributes_for(:project)
|
||||||
assert_redirected_to project_path(assigns(:project))
|
assert_redirected_to project_path(assigns(:project))
|
||||||
end
|
end
|
||||||
|
|
||||||
test "should destroy project" do
|
test "should destroy project" do
|
||||||
|
project = Factory(:project)
|
||||||
assert_difference('Project.count', -1) do
|
assert_difference('Project.count', -1) do
|
||||||
delete :destroy, :id => projects(:one).to_param
|
delete :destroy, :id => project.id
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_redirected_to projects_path
|
assert_redirected_to projects_path
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class WallControllerTest < ActionController::TestCase
|
||||||
|
# Replace this with your real tests.
|
||||||
|
test "the truth" do
|
||||||
|
assert true
|
||||||
|
end
|
||||||
|
end
|
|
@ -37,4 +37,17 @@ class ActiveSupport::TestCase
|
||||||
#fixtures :all
|
#fixtures :all
|
||||||
|
|
||||||
# Add more helper methods to be used by all tests here...
|
# Add more helper methods to be used by all tests here...
|
||||||
|
|
||||||
|
def sign_in_as(user)
|
||||||
|
@controller.current_user = user
|
||||||
|
return user
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign_in
|
||||||
|
sign_in_as Factory(:email_confirmed_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sign_out
|
||||||
|
@controller.current_user = nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class WallHelperTest < ActionView::TestCase
|
||||||
|
end
|
|
@ -0,0 +1,8 @@
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class WallTest < ActiveSupport::TestCase
|
||||||
|
# Replace this with your real tests.
|
||||||
|
test "the truth" do
|
||||||
|
assert true
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,11 +1,19 @@
|
||||||
SVN
|
0.5.0 (31 July 2009)
|
||||||
|
* Gemification
|
||||||
|
* Support for Ruby 1.9.X
|
||||||
|
* Updated to jQuery 1.3.2
|
||||||
|
* Updated to jQuery UI 1.7.2
|
||||||
|
* Created a jrails binary (runs rake tasks) because rails does not (yet?) pickup
|
||||||
|
tasks from gem plugins
|
||||||
|
* Changed default to use jQuery compatibility name (not $)
|
||||||
|
* Created a scrub task that will remove the prototype / script.aculo.us
|
||||||
|
javascript files
|
||||||
* better approximate scriptaculous effect names
|
* better approximate scriptaculous effect names
|
||||||
* add support for page[:element_id].visual_effect(:effect) as well as page.visual_effect(:effect, :element_id)
|
* add support for page[:element_id].visual_effect(:effect) as well as page.visual_effect(:effect, :element_id)
|
||||||
* added a reset form function to jrails.js (stolen from jquery form)
|
* added a reset form function to jrails.js (stolen from jquery form)
|
||||||
* can now use jquery selectors in all functions
|
* can now use jquery selectors in all functions
|
||||||
* added javascript_function helper to render inline rjs helpers
|
* added javascript_function helper to render inline rjs helpers
|
||||||
* better support for sortable_element
|
* better support for sortable_element
|
||||||
* updated to jquery-ui 1.5.1
|
|
||||||
|
|
||||||
0.4.0 (16 June 2008)
|
0.4.0 (16 June 2008)
|
||||||
* updated to jquery-ui 1.5 & merged js into single file
|
* updated to jquery-ui 1.5 & merged js into single file
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
Copyright (c) 2008 Aaron Eisenberger
|
||||||
|
|
||||||
|
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.
|
|
@ -0,0 +1,21 @@
|
||||||
|
= jRails
|
||||||
|
|
||||||
|
jRails is a drop-in jQuery replacement for the Rails Prototype/script.aculo.us helpers.
|
||||||
|
|
||||||
|
== Resources
|
||||||
|
|
||||||
|
Install
|
||||||
|
|
||||||
|
* .script/plugin install git://github.com/aaronchi/jrails.git
|
||||||
|
|
||||||
|
Project Site
|
||||||
|
|
||||||
|
* http://code.google.com/p/ennerchi
|
||||||
|
|
||||||
|
Web Site
|
||||||
|
|
||||||
|
* http://www.ennerchi.com/projects/jrails
|
||||||
|
|
||||||
|
Group Site
|
||||||
|
|
||||||
|
* http://groups.google.com/group/jrails
|
|
@ -0,0 +1,19 @@
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
begin
|
||||||
|
require 'jeweler'
|
||||||
|
Jeweler::Tasks.new do |gem|
|
||||||
|
gem.name = "jrails"
|
||||||
|
gem.summary = "jRails is a drop-in jQuery replacement for the Rails Prototype/script.aculo.us helpers."
|
||||||
|
gem.description = "Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library."
|
||||||
|
gem.email = "aaronchi@gmail.com"
|
||||||
|
gem.homepage = "http://ennerchi.com/projects/jrails"
|
||||||
|
gem.authors = ["Aaron Eisenberger", "Patrick Hurley"]
|
||||||
|
gem.rubyforge_project = "jrails"
|
||||||
|
gem.files = FileList["[A-Z]*.rb","{bin,javascripts,lib,rails,tasks}/**/*"]
|
||||||
|
end
|
||||||
|
Jeweler::GemcutterTasks.new
|
||||||
|
rescue LoadError
|
||||||
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
:build:
|
||||||
|
:patch: 0
|
||||||
|
:major: 0
|
||||||
|
:minor: 6
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'rubygems'
|
||||||
|
require 'rake'
|
||||||
|
|
||||||
|
RAILS_ROOT = Dir.pwd
|
||||||
|
rakeapp = Rake.application
|
||||||
|
fname =File.join(File.dirname(__FILE__), '..', 'tasks', 'jrails.rake')
|
||||||
|
load fname
|
||||||
|
|
||||||
|
task :help do
|
||||||
|
puts "jrails [command]\n\n"
|
||||||
|
rakeapp.options.show_task_pattern = Regexp.new('^[hius]')
|
||||||
|
rakeapp.display_tasks_and_comments
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Installs the jQuery and jRails javascripts to public/javascripts'
|
||||||
|
task :install do
|
||||||
|
Rake::Task['jrails:js:install'].invoke
|
||||||
|
end
|
||||||
|
|
||||||
|
desc 'Remove the prototype / script.aculo.us javascript files'
|
||||||
|
task :scrub do
|
||||||
|
Rake::Task['jrails:js:scrub'].invoke
|
||||||
|
end
|
||||||
|
|
||||||
|
rakeapp.init("jrails")
|
||||||
|
task :default => [:help]
|
||||||
|
|
||||||
|
rakeapp.top_level
|
|
@ -1,6 +1 @@
|
||||||
# uncomment to use jQuery.noConflict()
|
require 'rails/init.rb'
|
||||||
#ActionView::Helpers::PrototypeHelper::JQUERY_VAR = 'jQuery'
|
|
||||||
|
|
||||||
ActionView::Helpers::AssetTagHelper::JAVASCRIPT_DEFAULT_SOURCES = ['jrails']
|
|
||||||
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
|
|
||||||
require 'jrails'
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,128 +1 @@
|
||||||
(function($){$().ajaxSend(function(a,xhr,s){xhr.setRequestHeader("Accept","text/javascript, text/html, application/xml, text/xml, */*")})})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&field.type=="text"||field.type=="textarea"){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.obj.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||self.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o){e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"()")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery);
|
(function($){$.ajaxSettings.accepts._default="text/javascript, text/html, application/xml, text/xml, */*"})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&(field.type=="text"||field.type=="textarea"||field.type=="password")){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){var observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||el.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o,options){if(options){speed=options.duration*1000}else{speed=null}e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"("+speed+")")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery);
|
||||||
|
|
||||||
jQuery(function ($) {
|
|
||||||
var csrf_token = $('meta[name=csrf-token]').attr('content'),
|
|
||||||
csrf_param = $('meta[name=csrf-param]').attr('content');
|
|
||||||
|
|
||||||
$.fn.extend({
|
|
||||||
/**
|
|
||||||
* Triggers a custom event on an element and returns the event result
|
|
||||||
* this is used to get around not being able to ensure callbacks are placed
|
|
||||||
* at the end of the chain.
|
|
||||||
*
|
|
||||||
* TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our
|
|
||||||
* own events and placing ourselves at the end of the chain.
|
|
||||||
*/
|
|
||||||
triggerAndReturn: function (name, data) {
|
|
||||||
var event = new $.Event(name);
|
|
||||||
this.trigger(event, data);
|
|
||||||
|
|
||||||
return event.result !== false;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles execution of remote calls firing overridable events along the way
|
|
||||||
*/
|
|
||||||
callRemote: function () {
|
|
||||||
var el = this,
|
|
||||||
data = el.is('form') ? el.serializeArray() : [],
|
|
||||||
method = el.attr('method') || el.attr('data-method') || 'GET',
|
|
||||||
url = el.attr('action') || el.attr('href');
|
|
||||||
|
|
||||||
if (url === undefined) {
|
|
||||||
throw "No URL specified for remote call (action or href must be present).";
|
|
||||||
} else {
|
|
||||||
if (el.triggerAndReturn('ajax:before')) {
|
|
||||||
$.ajax({
|
|
||||||
url: url,
|
|
||||||
data: data,
|
|
||||||
dataType: 'script',
|
|
||||||
type: method.toUpperCase(),
|
|
||||||
beforeSend: function (xhr) {
|
|
||||||
el.trigger('ajax:loading', xhr);
|
|
||||||
},
|
|
||||||
success: function (data, status, xhr) {
|
|
||||||
el.trigger('ajax:success', [data, status, xhr]);
|
|
||||||
},
|
|
||||||
complete: function (xhr) {
|
|
||||||
el.trigger('ajax:complete', xhr);
|
|
||||||
},
|
|
||||||
error: function (xhr, status, error) {
|
|
||||||
el.trigger('ajax:failure', [xhr, status, error]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
el.trigger('ajax:after');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* confirmation handler
|
|
||||||
*/
|
|
||||||
$('a[data-confirm],input[data-confirm]').live('click', function () {
|
|
||||||
var el = $(this);
|
|
||||||
if (el.triggerAndReturn('confirm')) {
|
|
||||||
if (!confirm(el.attr('data-confirm'))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* remote handlers
|
|
||||||
*/
|
|
||||||
$('form[data-remote]').live('submit', function (e) {
|
|
||||||
$(this).callRemote();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('a[data-remote],input[data-remote]').live('click', function (e) {
|
|
||||||
$(this).callRemote();
|
|
||||||
e.preventDefault();
|
|
||||||
});
|
|
||||||
|
|
||||||
$('a[data-method]:not([data-remote])').live('click', function (e){
|
|
||||||
var link = $(this),
|
|
||||||
href = link.attr('href'),
|
|
||||||
method = link.attr('data-method'),
|
|
||||||
form = $('<form method="post" action="'+href+'">'),
|
|
||||||
metadata_input = '<input name="_method" value="'+method+'" type="hidden" />';
|
|
||||||
|
|
||||||
if (csrf_param != null && csrf_token != null) {
|
|
||||||
metadata_input += '<input name="'+csrf_param+'" value="'+csrf_token+'" type="hidden" />';
|
|
||||||
}
|
|
||||||
|
|
||||||
form.hide()
|
|
||||||
.append(metadata_input)
|
|
||||||
.appendTo('body');
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
form.submit();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* disable-with handlers
|
|
||||||
*/
|
|
||||||
var disable_with_input_selector = 'input[data-disable-with]';
|
|
||||||
var disable_with_form_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')';
|
|
||||||
|
|
||||||
$(disable_with_form_selector).live('ajax:before', function () {
|
|
||||||
$(this).find(disable_with_input_selector).each(function () {
|
|
||||||
var input = $(this);
|
|
||||||
input.data('enable-with', input.val())
|
|
||||||
.attr('value', input.attr('data-disable-with'))
|
|
||||||
.attr('disabled', 'disabled');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$(disable_with_form_selector).live('ajax:after', function () {
|
|
||||||
$(this).find(disable_with_input_selector).each(function () {
|
|
||||||
var input = $(this);
|
|
||||||
input.removeAttr('disabled')
|
|
||||||
.val(input.data('enable-with'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -7,9 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$().ajaxSend(function(a, xhr, s){ //Set request headers globally
|
$.ajaxSettings.accepts._default = "text/javascript, text/html, application/xml, text/xml, */*";
|
||||||
xhr.setRequestHeader("Accept", "text/javascript, text/html, application/xml, text/xml, */*");
|
|
||||||
});
|
|
||||||
})(jQuery);
|
})(jQuery);
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +57,7 @@
|
||||||
fieldEvent: function(el, obs) {
|
fieldEvent: function(el, obs) {
|
||||||
var field = el[0] || el, e = 'change';
|
var field = el[0] || el, e = 'change';
|
||||||
if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
|
if (field.type == 'radio' || field.type == 'checkbox') e = 'click';
|
||||||
else if (obs && field.type == 'text' || field.type == 'textarea') e = 'keyup';
|
else if (obs && (field.type == 'text' || field.type == 'textarea' || field.type == 'password')) e = 'keyup';
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -119,9 +117,14 @@
|
||||||
|
|
||||||
(function($) {
|
(function($) {
|
||||||
$.fn.extend({
|
$.fn.extend({
|
||||||
visualEffect : function(o) {
|
visualEffect : function(o, options) {
|
||||||
|
if (options) {
|
||||||
|
speed = options.duration * 1000;
|
||||||
|
} else {
|
||||||
|
speed = null;
|
||||||
|
}
|
||||||
e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
|
e = o.replace(/\_(.)/g, function(m, l){return l.toUpperCase()});
|
||||||
return eval('$(this).'+e+'()');
|
return eval('$(this).'+e+'('+ speed + ')');
|
||||||
},
|
},
|
||||||
appear : function(speed, callback) {
|
appear : function(speed, callback) {
|
||||||
return this.fadeIn(speed, callback);
|
return this.fadeIn(speed, callback);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
# Generated by jeweler
|
||||||
|
# DO NOT EDIT THIS FILE DIRECTLY
|
||||||
|
# Instead, edit Jeweler::Tasks in rakefile, and run the gemspec command
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
|
Gem::Specification.new do |s|
|
||||||
|
s.name = %q{jrails}
|
||||||
|
s.version = "0.6.0"
|
||||||
|
|
||||||
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||||
|
s.authors = ["Aaron Eisenberger", "Patrick Hurley"]
|
||||||
|
s.date = %q{2009-10-20}
|
||||||
|
s.default_executable = %q{jrails}
|
||||||
|
s.description = %q{Using jRails, you can get all of the same default Rails helpers for javascript functionality using the lighter jQuery library.}
|
||||||
|
s.email = %q{aaronchi@gmail.com}
|
||||||
|
s.executables = ["jrails"]
|
||||||
|
s.extra_rdoc_files = [
|
||||||
|
"CHANGELOG",
|
||||||
|
"LICENSE",
|
||||||
|
"README.rdoc"
|
||||||
|
]
|
||||||
|
s.files = [
|
||||||
|
"bin/jrails",
|
||||||
|
"init.rb",
|
||||||
|
"install.rb",
|
||||||
|
"javascripts/jquery-ui.js",
|
||||||
|
"javascripts/jquery.js",
|
||||||
|
"javascripts/jrails.js",
|
||||||
|
"javascripts/sources/jrails.js",
|
||||||
|
"lib/jquery_selector_assertions.rb",
|
||||||
|
"lib/jrails.rb",
|
||||||
|
"rails/init.rb",
|
||||||
|
"tasks/jrails.rake"
|
||||||
|
]
|
||||||
|
s.homepage = %q{http://ennerchi.com/projects/jrails}
|
||||||
|
s.rdoc_options = ["--charset=UTF-8"]
|
||||||
|
s.require_paths = ["lib"]
|
||||||
|
s.rubyforge_project = %q{jrails}
|
||||||
|
s.rubygems_version = %q{1.3.5}
|
||||||
|
s.summary = %q{jRails is a drop-in jQuery replacement for the Rails Prototype/script.aculo.us helpers.}
|
||||||
|
|
||||||
|
if s.respond_to? :specification_version then
|
||||||
|
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
||||||
|
s.specification_version = 3
|
||||||
|
|
||||||
|
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
||||||
|
else
|
||||||
|
end
|
||||||
|
else
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
#
|
||||||
|
# jQuery Selector Assertions (modifications to the prototype/scriptaculous assertions)
|
||||||
|
#
|
||||||
|
# From http://pastie.org/303776
|
||||||
|
#
|
||||||
|
# 1. Make sure to use '#' prefix when referring to element IDs in assert_select_rjs(),
|
||||||
|
# like this:
|
||||||
|
# assert_select_rjs :replace_html, '#someid'
|
||||||
|
# instead of prototype convention:
|
||||||
|
# assert_select_rjs :replace_html, 'someid'
|
||||||
|
#
|
||||||
|
# We monkey-patch some RJS-matching constants for assert_select_rjs to work
|
||||||
|
# with jQuery-based code as opposed to Prototype's:
|
||||||
|
#
|
||||||
|
module ActionController
|
||||||
|
module Assertions
|
||||||
|
module SelectorAssertions
|
||||||
|
silence_warnings do
|
||||||
|
RJS_PATTERN_HTML = "\"((\\\\\"|[^\"])*)\""
|
||||||
|
# RJS_ANY_ID = "\"([^\"])*\""
|
||||||
|
# better match with single or double quoted ids
|
||||||
|
RJS_ANY_ID = "[\"']([^\"])*[\"']"
|
||||||
|
|
||||||
|
RJS_STATEMENTS = {
|
||||||
|
:chained_replace => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.replaceWith\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:chained_replace_html => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.updateWith\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:replace_html => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.html\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:replace => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.replaceWith\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:insert_top => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.prepend\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:insert_bottom => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.append\\(#{RJS_PATTERN_HTML}\\)",
|
||||||
|
:effect => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.effect\\(",
|
||||||
|
:highlight => "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.effect\\('highlight'"
|
||||||
|
|
||||||
|
=begin TODO:
|
||||||
|
|
||||||
|
I've never used the chained_* so I don't know if they work.
|
||||||
|
|
||||||
|
I couldn't seem to get assert_select_rjs to actually match the single quoted ids
|
||||||
|
which are created by some of the effects like ...
|
||||||
|
... jQuery('#item_1559').effect('highlight',{},1000);
|
||||||
|
so I modified jrails/lib/jrails.rb line 337
|
||||||
|
... javascript = "#{JQUERY_VAR}('#{jquery_id(element_id)}').#{mode || 'effect'}('#{name}'"
|
||||||
|
to
|
||||||
|
... javascript = "#{JQUERY_VAR}(\"#{jquery_id(element_id)}\").#{mode || 'effect'}('#{name}'"
|
||||||
|
so it writes double quotes like most of the others. This change should probably be
|
||||||
|
done to the others, but as I don't use them so haven't tested them.
|
||||||
|
|
||||||
|
My other option seemed to require modifying rails' selector_assertions.rb line 427
|
||||||
|
... id ? statement.gsub(RJS_ANY_ID, "\"#{id}\"") : statement
|
||||||
|
which forces the expectation that the id is double quoted. If I changed it to
|
||||||
|
... statement.gsub(RJS_ANY_ID, "[\"']{1}#{id}[\"']{1}")
|
||||||
|
I believe that it would work as the logic seemed to work in some testing.
|
||||||
|
I have not actually tried to modify rails, as this file doesn't seem to
|
||||||
|
actually be in the git repository.
|
||||||
|
|
||||||
|
|
||||||
|
jrails now uses a nonconflict option so $ is jQuery. I put both in the pattern in case it gets changed.
|
||||||
|
|
||||||
|
:insert_after => "",
|
||||||
|
:insert_before => "",
|
||||||
|
=end
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[:remove, :show, :hide, :toggle, :reset ].each do |action|
|
||||||
|
RJS_STATEMENTS[action] = "\(jQuery|$\)\\(#{RJS_ANY_ID}\\)\\.#{action}\\(\\)"
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO:
|
||||||
|
#RJS_STATEMENTS[:insert_html] = "Element.insert\\(#{RJS_ANY_ID}, \\{ (#{RJS_INSERTIONS.join('|')}):
|
||||||
|
#{RJS_PATTERN_HTML} \\}\\)"
|
||||||
|
|
||||||
|
RJS_STATEMENTS[:any] = Regexp.new("(#{RJS_STATEMENTS.values.join('|')})")
|
||||||
|
RJS_PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,406 +1,427 @@
|
||||||
module ActionView
|
module ActionView
|
||||||
module Helpers
|
module Helpers
|
||||||
|
|
||||||
module JavaScriptHelper
|
module JavaScriptHelper
|
||||||
|
|
||||||
# This function can be used to render rjs inline
|
# This function can be used to render rjs inline
|
||||||
#
|
#
|
||||||
# <%= javascript_function do |page|
|
# <%= javascript_function do |page|
|
||||||
# page.replace_html :list, :partial => 'list', :object => @list
|
# page.replace_html :list, :partial => 'list', :object => @list
|
||||||
# end %>
|
# end %>
|
||||||
#
|
#
|
||||||
def javascript_function(*args, &block)
|
def javascript_function(*args, &block)
|
||||||
html_options = args.extract_options!
|
html_options = args.extract_options!
|
||||||
function = args[0] || ''
|
function = args[0] || ''
|
||||||
|
|
||||||
html_options.symbolize_keys!
|
html_options.symbolize_keys!
|
||||||
function = update_page(&block) if block_given?
|
function = update_page(&block) if block_given?
|
||||||
javascript_tag(function)
|
javascript_tag(function)
|
||||||
end
|
end
|
||||||
|
|
||||||
def jquery_id(id)
|
def jquery_id(id)
|
||||||
id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
||||||
end
|
end
|
||||||
|
|
||||||
def jquery_ids(ids)
|
def jquery_ids(ids)
|
||||||
Array(ids).map{|id| jquery_id(id)}.join(',')
|
Array(ids).map{|id| jquery_id(id)}.join(',')
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
module PrototypeHelper
|
module PrototypeHelper
|
||||||
|
|
||||||
unless const_defined? :JQUERY_VAR
|
USE_PROTECTION = const_defined?(:DISABLE_JQUERY_FORGERY_PROTECTION) ? !DISABLE_JQUERY_FORGERY_PROTECTION : true
|
||||||
JQUERY_VAR = '$'
|
|
||||||
end
|
unless const_defined? :JQUERY_VAR
|
||||||
|
JQUERY_VAR = 'jQuery'
|
||||||
unless const_defined? :JQCALLBACKS
|
end
|
||||||
JQCALLBACKS = Set.new([ :beforeSend, :complete, :error, :success ] + (100..599).to_a)
|
|
||||||
AJAX_OPTIONS = Set.new([ :before, :after, :condition, :url,
|
unless const_defined? :JQCALLBACKS
|
||||||
:asynchronous, :method, :insertion, :position,
|
JQCALLBACKS = Set.new([ :beforeSend, :complete, :error, :success ] + (100..599).to_a)
|
||||||
:form, :with, :update, :script ]).merge(JQCALLBACKS)
|
#instance_eval { remove_const :AJAX_OPTIONS }
|
||||||
end
|
remove_const(:AJAX_OPTIONS) if const_defined?(:AJAX_OPTIONS)
|
||||||
|
AJAX_OPTIONS = Set.new([ :before, :after, :condition, :url,
|
||||||
def periodically_call_remote(options = {})
|
:asynchronous, :method, :insertion, :position,
|
||||||
frequency = options[:frequency] || 10 # every ten seconds by default
|
:form, :with, :update, :script ]).merge(JQCALLBACKS)
|
||||||
code = "setInterval(function() {#{remote_function(options)}}, #{frequency} * 1000)"
|
end
|
||||||
javascript_tag(code)
|
|
||||||
end
|
def periodically_call_remote(options = {})
|
||||||
|
frequency = options[:frequency] || 10 # every ten seconds by default
|
||||||
def remote_function(options)
|
code = "setInterval(function() {#{remote_function(options)}}, #{frequency} * 1000)"
|
||||||
javascript_options = options_for_ajax(options)
|
javascript_tag(code)
|
||||||
|
end
|
||||||
update = ''
|
|
||||||
if options[:update] && options[:update].is_a?(Hash)
|
def remote_function(options)
|
||||||
update = []
|
javascript_options = options_for_ajax(options)
|
||||||
update << "success:'#{options[:update][:success]}'" if options[:update][:success]
|
|
||||||
update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure]
|
update = ''
|
||||||
update = '{' + update.join(',') + '}'
|
if options[:update] && options[:update].is_a?(Hash)
|
||||||
elsif options[:update]
|
update = []
|
||||||
update << "'#{options[:update]}'"
|
update << "success:'#{options[:update][:success]}'" if options[:update][:success]
|
||||||
end
|
update << "failure:'#{options[:update][:failure]}'" if options[:update][:failure]
|
||||||
|
update = '{' + update.join(',') + '}'
|
||||||
function = "#{JQUERY_VAR}.ajax(#{javascript_options})"
|
elsif options[:update]
|
||||||
|
update << "'#{options[:update]}'"
|
||||||
function = "#{options[:before]}; #{function}" if options[:before]
|
end
|
||||||
function = "#{function}; #{options[:after]}" if options[:after]
|
|
||||||
function = "if (#{options[:condition]}) { #{function}; }" if options[:condition]
|
function = "#{JQUERY_VAR}.ajax(#{javascript_options})"
|
||||||
function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm]
|
|
||||||
return function
|
function = "#{options[:before]}; #{function}" if options[:before]
|
||||||
end
|
function = "#{function}; #{options[:after]}" if options[:after]
|
||||||
|
function = "if (#{options[:condition]}) { #{function}; }" if options[:condition]
|
||||||
class JavaScriptGenerator
|
function = "if (confirm('#{escape_javascript(options[:confirm])}')) { #{function}; }" if options[:confirm]
|
||||||
module GeneratorMethods
|
return function
|
||||||
|
end
|
||||||
def insert_html(position, id, *options_for_render)
|
|
||||||
insertion = position.to_s.downcase
|
class JavaScriptGenerator
|
||||||
insertion = 'append' if insertion == 'bottom'
|
module GeneratorMethods
|
||||||
insertion = 'prepend' if insertion == 'top'
|
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").#{insertion}", render(*options_for_render)
|
def insert_html(position, id, *options_for_render)
|
||||||
end
|
insertion = position.to_s.downcase
|
||||||
|
insertion = 'append' if insertion == 'bottom'
|
||||||
def replace_html(id, *options_for_render)
|
insertion = 'prepend' if insertion == 'top'
|
||||||
insert_html(:html, id, *options_for_render)
|
call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").#{insertion}", render(*options_for_render)
|
||||||
end
|
end
|
||||||
|
|
||||||
def replace(id, *options_for_render)
|
def replace_html(id, *options_for_render)
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").replaceWith", render(*options_for_render)
|
insert_html(:html, id, *options_for_render)
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove(*ids)
|
def replace(id, *options_for_render)
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").remove"
|
call "#{JQUERY_VAR}(\"#{jquery_id(id)}\").replaceWith", render(*options_for_render)
|
||||||
end
|
end
|
||||||
|
|
||||||
def show(*ids)
|
def remove(*ids)
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").show"
|
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").remove"
|
||||||
end
|
end
|
||||||
|
|
||||||
def hide(*ids)
|
def show(*ids)
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").hide"
|
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").show"
|
||||||
end
|
end
|
||||||
|
|
||||||
def toggle(*ids)
|
def hide(*ids)
|
||||||
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").toggle"
|
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").hide"
|
||||||
end
|
end
|
||||||
|
|
||||||
def jquery_id(id)
|
def toggle(*ids)
|
||||||
id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
call "#{JQUERY_VAR}(\"#{jquery_ids(ids)}\").toggle"
|
||||||
end
|
end
|
||||||
|
|
||||||
def jquery_ids(ids)
|
def jquery_id(id)
|
||||||
Array(ids).map{|id| jquery_id(id)}.join(',')
|
id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
def jquery_ids(ids)
|
||||||
end
|
Array(ids).map{|id| jquery_id(id)}.join(',')
|
||||||
|
end
|
||||||
protected
|
|
||||||
def options_for_ajax(options)
|
def prepend(id, *option_for_render)
|
||||||
js_options = build_callbacks(options)
|
insert_html(:prepend, id, *options_for_render)
|
||||||
|
end
|
||||||
url_options = options[:url]
|
|
||||||
url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
|
end
|
||||||
js_options['url'] = "'#{url_for(url_options)}'"
|
end
|
||||||
js_options['async'] = false if options[:type] == :synchronous
|
|
||||||
js_options['type'] = options[:method] ? method_option_to_s(options[:method]) : ( options[:form] ? "'post'" : nil )
|
protected
|
||||||
js_options['dataType'] = options[:datatype] ? "'#{options[:datatype]}'" : (options[:update] ? nil : "'script'")
|
def options_for_ajax(options)
|
||||||
|
js_options = build_callbacks(options)
|
||||||
if options[:form]
|
|
||||||
js_options['data'] = "#{JQUERY_VAR}.param(#{JQUERY_VAR}(this).serializeArray())"
|
url_options = options[:url]
|
||||||
elsif options[:submit]
|
url_options = url_options.merge(:escape => false) if url_options.is_a?(Hash)
|
||||||
js_options['data'] = "#{JQUERY_VAR}(\"##{options[:submit]} :input\").serialize()"
|
js_options['url'] = "'#{url_for(url_options)}'"
|
||||||
elsif options[:with]
|
js_options['async'] = false if options[:type] == :synchronous
|
||||||
js_options['data'] = options[:with].gsub("Form.serialize(this.form)","#{JQUERY_VAR}.param(#{JQUERY_VAR}(this.form).serializeArray())")
|
js_options['type'] = options[:method] ? method_option_to_s(options[:method]) : ( options[:form] ? "'post'" : nil )
|
||||||
end
|
js_options['dataType'] = options[:datatype] ? "'#{options[:datatype]}'" : (options[:update] ? nil : "'script'")
|
||||||
|
|
||||||
js_options['type'] ||= "'post'"
|
if options[:form]
|
||||||
if options[:method]
|
js_options['data'] = "#{JQUERY_VAR}.param(#{JQUERY_VAR}(this).serializeArray())"
|
||||||
if method_option_to_s(options[:method]) == "'put'" || method_option_to_s(options[:method]) == "'delete'"
|
elsif options[:submit]
|
||||||
js_options['type'] = "'post'"
|
js_options['data'] = "#{JQUERY_VAR}(\"##{options[:submit]} :input\").serialize()"
|
||||||
if js_options['data']
|
elsif options[:with]
|
||||||
js_options['data'] << " + '&"
|
js_options['data'] = options[:with].gsub("Form.serialize(this.form)","#{JQUERY_VAR}.param(#{JQUERY_VAR}(this.form).serializeArray())")
|
||||||
else
|
end
|
||||||
js_options['data'] = "'"
|
|
||||||
end
|
js_options['type'] ||= "'post'"
|
||||||
js_options['data'] << "_method=#{options[:method]}'"
|
if options[:method]
|
||||||
end
|
if method_option_to_s(options[:method]) == "'put'" || method_option_to_s(options[:method]) == "'delete'"
|
||||||
end
|
js_options['type'] = "'post'"
|
||||||
|
if js_options['data']
|
||||||
if respond_to?('protect_against_forgery?') && protect_against_forgery?
|
js_options['data'] << " + '&"
|
||||||
if js_options['data']
|
else
|
||||||
js_options['data'] << " + '&"
|
js_options['data'] = "'"
|
||||||
else
|
end
|
||||||
js_options['data'] = "'"
|
js_options['data'] << "_method=#{options[:method]}'"
|
||||||
end
|
end
|
||||||
js_options['data'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
|
end
|
||||||
end
|
|
||||||
js_options['data'] = "''" if js_options['type'] == "'post'" && js_options['data'].nil?
|
if USE_PROTECTION && respond_to?('protect_against_forgery?') && protect_against_forgery?
|
||||||
options_for_javascript(js_options.reject {|key, value| value.nil?})
|
if js_options['data']
|
||||||
end
|
js_options['data'] << " + '&"
|
||||||
|
else
|
||||||
def build_update_for_success(html_id, insertion=nil)
|
js_options['data'] = "'"
|
||||||
insertion = build_insertion(insertion)
|
end
|
||||||
"#{JQUERY_VAR}('#{jquery_id(html_id)}').#{insertion}(request);"
|
js_options['data'] << "#{request_forgery_protection_token}=' + encodeURIComponent('#{escape_javascript form_authenticity_token}')"
|
||||||
end
|
end
|
||||||
|
js_options['data'] = "''" if js_options['type'] == "'post'" && js_options['data'].nil?
|
||||||
def build_update_for_error(html_id, insertion=nil)
|
options_for_javascript(js_options.reject {|key, value| value.nil?})
|
||||||
insertion = build_insertion(insertion)
|
end
|
||||||
"#{JQUERY_VAR}('#{jquery_id(html_id)}').#{insertion}(request.responseText);"
|
|
||||||
end
|
def build_update_for_success(html_id, insertion=nil)
|
||||||
|
insertion = build_insertion(insertion)
|
||||||
def build_insertion(insertion)
|
"#{JQUERY_VAR}('#{jquery_id(html_id)}').#{insertion}(request);"
|
||||||
insertion = insertion ? insertion.to_s.downcase : 'html'
|
end
|
||||||
insertion = 'append' if insertion == 'bottom'
|
|
||||||
insertion = 'prepend' if insertion == 'top'
|
def build_update_for_error(html_id, insertion=nil)
|
||||||
insertion
|
insertion = build_insertion(insertion)
|
||||||
end
|
"#{JQUERY_VAR}('#{jquery_id(html_id)}').#{insertion}(request.responseText);"
|
||||||
|
end
|
||||||
def build_observer(klass, name, options = {})
|
|
||||||
if options[:with] && (options[:with] !~ /[\{=(.]/)
|
def build_insertion(insertion)
|
||||||
options[:with] = "'#{options[:with]}=' + value"
|
insertion = insertion ? insertion.to_s.downcase : 'html'
|
||||||
else
|
insertion = 'append' if insertion == 'bottom'
|
||||||
options[:with] ||= 'value' unless options[:function]
|
insertion = 'prepend' if insertion == 'top'
|
||||||
end
|
insertion
|
||||||
|
end
|
||||||
callback = options[:function] || remote_function(options)
|
|
||||||
javascript = "#{JQUERY_VAR}('#{jquery_id(name)}').delayedObserver("
|
def build_observer(klass, name, options = {})
|
||||||
javascript << "#{options[:frequency] || 0}, "
|
if options[:with] && (options[:with] !~ /[\{=(.]/)
|
||||||
javascript << "function(element, value) {"
|
options[:with] = "'#{options[:with]}=' + value"
|
||||||
javascript << "#{callback}}"
|
else
|
||||||
#javascript << ", '#{options[:on]}'" if options[:on]
|
options[:with] ||= 'value' unless options[:function]
|
||||||
javascript << ")"
|
end
|
||||||
javascript_tag(javascript)
|
|
||||||
end
|
callback = options[:function] || remote_function(options)
|
||||||
|
javascript = "#{JQUERY_VAR}('#{jquery_id(name)}').delayedObserver("
|
||||||
def build_callbacks(options)
|
javascript << "#{options[:frequency] || 0}, "
|
||||||
callbacks = {}
|
javascript << "function(element, value) {"
|
||||||
options[:beforeSend] = '';
|
javascript << "#{callback}}"
|
||||||
[:uninitialized,:loading,:loaded].each do |key|
|
#javascript << ", '#{options[:on]}'" if options[:on]
|
||||||
options[:beforeSend] << (options[key].last == ';' ? options.delete(key) : options.delete(key) << ';') if options[key]
|
javascript << ")"
|
||||||
end
|
javascript_tag(javascript)
|
||||||
options.delete(:beforeSend) if options[:beforeSend].blank?
|
end
|
||||||
options[:error] = options.delete(:failure) if options[:failure]
|
|
||||||
if options[:update]
|
def build_callbacks(options)
|
||||||
if options[:update].is_a?(Hash)
|
callbacks = {}
|
||||||
options[:update][:error] = options[:update].delete(:failure) if options[:update][:failure]
|
options[:beforeSend] = '';
|
||||||
if options[:update][:success]
|
[:uninitialized,:loading].each do |key|
|
||||||
options[:success] = build_update_for_success(options[:update][:success], options[:position]) << (options[:success] ? options[:success] : '')
|
options[:beforeSend] << (options[key].last == ';' ? options.delete(key) : options.delete(key) << ';') if options[key]
|
||||||
end
|
end
|
||||||
if options[:update][:error]
|
options.delete(:beforeSend) if options[:beforeSend].blank?
|
||||||
options[:error] = build_update_for_error(options[:update][:error], options[:position]) << (options[:error] ? options[:error] : '')
|
options[:complete] = options.delete(:loaded) if options[:loaded]
|
||||||
end
|
options[:error] = options.delete(:failure) if options[:failure]
|
||||||
else
|
if options[:update]
|
||||||
options[:success] = build_update_for_success(options[:update], options[:position]) << (options[:success] ? options[:success] : '')
|
if options[:update].is_a?(Hash)
|
||||||
end
|
options[:update][:error] = options[:update].delete(:failure) if options[:update][:failure]
|
||||||
end
|
if options[:update][:success]
|
||||||
options.each do |callback, code|
|
options[:success] = build_update_for_success(options[:update][:success], options[:position]) << (options[:success] ? options[:success] : '')
|
||||||
if JQCALLBACKS.include?(callback)
|
end
|
||||||
callbacks[callback] = "function(request){#{code}}"
|
if options[:update][:error]
|
||||||
end
|
options[:error] = build_update_for_error(options[:update][:error], options[:position]) << (options[:error] ? options[:error] : '')
|
||||||
end
|
end
|
||||||
callbacks
|
else
|
||||||
end
|
options[:success] = build_update_for_success(options[:update], options[:position]) << (options[:success] ? options[:success] : '')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
options.each do |callback, code|
|
||||||
class JavaScriptElementProxy < JavaScriptProxy #:nodoc:
|
if JQCALLBACKS.include?(callback)
|
||||||
|
callbacks[callback] = "function(request){#{code}}"
|
||||||
unless const_defined? :JQUERY_VAR
|
end
|
||||||
JQUERY_VAR = ActionView::Helpers::PrototypeHelper::JQUERY_VAR
|
end
|
||||||
end
|
callbacks
|
||||||
|
end
|
||||||
def initialize(generator, id)
|
|
||||||
id = id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
end
|
||||||
@id = id
|
|
||||||
super(generator, "#{JQUERY_VAR}(\"#{id}\")")
|
class JavaScriptElementProxy < JavaScriptProxy #:nodoc:
|
||||||
end
|
|
||||||
|
unless const_defined? :JQUERY_VAR
|
||||||
def replace_html(*options_for_render)
|
JQUERY_VAR = PrototypeHelper::JQUERY_VAR
|
||||||
call 'html', @generator.send(:render, *options_for_render)
|
end
|
||||||
end
|
|
||||||
|
def initialize(generator, id)
|
||||||
def replace(*options_for_render)
|
id = id.to_s.count('#.*,>+~:[/ ') == 0 ? "##{id}" : id
|
||||||
call 'replaceWith', @generator.send(:render, *options_for_render)
|
@id = id
|
||||||
end
|
super(generator, "#{JQUERY_VAR}(\"#{id}\")")
|
||||||
|
end
|
||||||
def value()
|
|
||||||
call 'val()'
|
def replace_html(*options_for_render)
|
||||||
end
|
call 'html', @generator.send(:render, *options_for_render)
|
||||||
|
end
|
||||||
def value=(value)
|
|
||||||
call 'val', value
|
def replace(*options_for_render)
|
||||||
end
|
call 'replaceWith', @generator.send(:render, *options_for_render)
|
||||||
|
end
|
||||||
end
|
|
||||||
|
def reload(options_for_replace={})
|
||||||
class JavaScriptElementCollectionProxy < JavaScriptCollectionProxy #:nodoc:\
|
replace(options_for_replace.merge({ :partial => @id.to_s.sub(/^#/,'') }))
|
||||||
|
end
|
||||||
unless const_defined? :JQUERY_VAR
|
|
||||||
JQUERY_VAR = ActionView::Helpers::PrototypeHelper::JQUERY_VAR
|
def value()
|
||||||
end
|
call 'val()'
|
||||||
|
end
|
||||||
def initialize(generator, pattern)
|
|
||||||
super(generator, "#{JQUERY_VAR}(#{pattern.to_json})")
|
def value=(value)
|
||||||
end
|
call 'val', value
|
||||||
end
|
end
|
||||||
|
|
||||||
module ScriptaculousHelper
|
end
|
||||||
|
|
||||||
unless const_defined? :JQUERY_VAR
|
class JavaScriptElementCollectionProxy < JavaScriptCollectionProxy #:nodoc:\
|
||||||
JQUERY_VAR = ActionView::Helpers::PrototypeHelper::JQUERY_VAR
|
|
||||||
end
|
unless const_defined? :JQUERY_VAR
|
||||||
|
JQUERY_VAR = PrototypeHelper::JQUERY_VAR
|
||||||
unless const_defined? :SCRIPTACULOUS_EFFECTS
|
end
|
||||||
SCRIPTACULOUS_EFFECTS = {
|
|
||||||
:appear => {:method => 'fadeIn'},
|
def initialize(generator, pattern)
|
||||||
:blind_down => {:method => 'blind', :mode => 'show', :options => {:direction => 'vertical'}},
|
super(generator, "#{JQUERY_VAR}(#{pattern.to_json})")
|
||||||
:blind_up => {:method => 'blind', :mode => 'hide', :options => {:direction => 'vertical'}},
|
end
|
||||||
:blind_right => {:method => 'blind', :mode => 'show', :options => {:direction => 'horizontal'}},
|
end
|
||||||
:blind_left => {:method => 'blind', :mode => 'hide', :options => {:direction => 'horizontal'}},
|
|
||||||
:bounce_in => {:method => 'bounce', :mode => 'show', :options => {:direction => 'up'}},
|
module ScriptaculousHelper
|
||||||
:bounce_out => {:method => 'bounce', :mode => 'hide', :options => {:direction => 'up'}},
|
|
||||||
:drop_in => {:method => 'drop', :mode => 'show', :options => {:direction => 'up'}},
|
unless const_defined? :JQUERY_VAR
|
||||||
:drop_out => {:method => 'drop', :mode => 'hide', :options => {:direction => 'down'}},
|
JQUERY_VAR = PrototypeHelper::JQUERY_VAR
|
||||||
:fade => {:method => 'fadeOut'},
|
end
|
||||||
:fold_in => {:method => 'fold', :mode => 'hide'},
|
|
||||||
:fold_out => {:method => 'fold', :mode => 'show'},
|
unless const_defined? :SCRIPTACULOUS_EFFECTS
|
||||||
:grow => {:method => 'scale', :mode => 'show'},
|
SCRIPTACULOUS_EFFECTS = {
|
||||||
:shrink => {:method => 'scale', :mode => 'hide'},
|
:appear => {:method => 'fadeIn'},
|
||||||
:slide_down => {:method => 'slide', :mode => 'show', :options => {:direction => 'up'}},
|
:blind_down => {:method => 'blind', :mode => 'show', :options => {:direction => 'vertical'}},
|
||||||
:slide_up => {:method => 'slide', :mode => 'hide', :options => {:direction => 'up'}},
|
:blind_up => {:method => 'blind', :mode => 'hide', :options => {:direction => 'vertical'}},
|
||||||
:slide_right => {:method => 'slide', :mode => 'show', :options => {:direction => 'left'}},
|
:blind_right => {:method => 'blind', :mode => 'show', :options => {:direction => 'horizontal'}},
|
||||||
:slide_left => {:method => 'slide', :mode => 'hide', :options => {:direction => 'left'}},
|
:blind_left => {:method => 'blind', :mode => 'hide', :options => {:direction => 'horizontal'}},
|
||||||
:squish => {:method => 'scale', :mode => 'hide', :options => {:origin => "['top','left']"}},
|
:bounce_in => {:method => 'bounce', :mode => 'show', :options => {:direction => 'up'}},
|
||||||
:switch_on => {:method => 'clip', :mode => 'show', :options => {:direction => 'vertical'}},
|
:bounce_out => {:method => 'bounce', :mode => 'hide', :options => {:direction => 'up'}},
|
||||||
:switch_off => {:method => 'clip', :mode => 'hide', :options => {:direction => 'vertical'}},
|
:drop_in => {:method => 'drop', :mode => 'show', :options => {:direction => 'up'}},
|
||||||
:toggle_appear => {:method => 'fadeToggle'},
|
:drop_out => {:method => 'drop', :mode => 'hide', :options => {:direction => 'down'}},
|
||||||
:toggle_slide => {:method => 'slide', :mode => 'toggle', :options => {:direction => 'up'}},
|
:fade => {:method => 'fadeOut'},
|
||||||
:toggle_blind => {:method => 'blind', :mode => 'toggle', :options => {:direction => 'vertical'}},
|
:fold_in => {:method => 'fold', :mode => 'hide'},
|
||||||
}
|
:fold_out => {:method => 'fold', :mode => 'show'},
|
||||||
end
|
:grow => {:method => 'scale', :mode => 'show'},
|
||||||
|
:shrink => {:method => 'scale', :mode => 'hide'},
|
||||||
def visual_effect(name, element_id = false, js_options = {})
|
:slide_down => {:method => 'slide', :mode => 'show', :options => {:direction => 'up'}},
|
||||||
element = element_id ? element_id : "this"
|
:slide_up => {:method => 'slide', :mode => 'hide', :options => {:direction => 'up'}},
|
||||||
|
:slide_right => {:method => 'slide', :mode => 'show', :options => {:direction => 'left'}},
|
||||||
if SCRIPTACULOUS_EFFECTS.has_key? name.to_sym
|
:slide_left => {:method => 'slide', :mode => 'hide', :options => {:direction => 'left'}},
|
||||||
effect = SCRIPTACULOUS_EFFECTS[name.to_sym]
|
:squish => {:method => 'scale', :mode => 'hide', :options => {:origin => "['top','left']"}},
|
||||||
name = effect[:method]
|
:switch_on => {:method => 'clip', :mode => 'show', :options => {:direction => 'vertical'}},
|
||||||
mode = effect[:mode]
|
:switch_off => {:method => 'clip', :mode => 'hide', :options => {:direction => 'vertical'}},
|
||||||
js_options = js_options.merge(effect[:options]) if effect[:options]
|
:toggle_appear => {:method => 'fadeToggle'},
|
||||||
end
|
:toggle_slide => {:method => 'slide', :mode => 'toggle', :options => {:direction => 'up'}},
|
||||||
|
:toggle_blind => {:method => 'blind', :mode => 'toggle', :options => {:direction => 'vertical'}},
|
||||||
[:color, :direction].each do |option|
|
}
|
||||||
js_options[option] = "'#{js_options[option]}'" if js_options[option]
|
end
|
||||||
end
|
|
||||||
|
def visual_effect(name, element_id = false, js_options = {})
|
||||||
if js_options.has_key? :duration
|
element = element_id ? element_id : "this"
|
||||||
speed = js_options.delete :duration
|
|
||||||
speed = (speed * 1000).to_i unless speed.nil?
|
if SCRIPTACULOUS_EFFECTS.has_key? name.to_sym
|
||||||
else
|
effect = SCRIPTACULOUS_EFFECTS[name.to_sym]
|
||||||
speed = js_options.delete :speed
|
name = effect[:method]
|
||||||
end
|
mode = effect[:mode]
|
||||||
|
js_options = js_options.merge(effect[:options]) if effect[:options]
|
||||||
if ['fadeIn','fadeOut','fadeToggle'].include?(name)
|
end
|
||||||
javascript = "#{JQUERY_VAR}('#{jquery_id(element_id)}').#{name}("
|
|
||||||
javascript << "#{speed}" unless speed.nil?
|
[:color, :direction, :startcolor, :endcolor].each do |option|
|
||||||
javascript << ");"
|
js_options[option] = "'#{js_options[option]}'" if js_options[option]
|
||||||
else
|
end
|
||||||
javascript = "#{JQUERY_VAR}('#{jquery_id(element_id)}').#{mode || 'effect'}('#{name}'"
|
|
||||||
javascript << ",#{options_for_javascript(js_options)}" unless speed.nil? && js_options.empty?
|
if js_options.has_key? :duration
|
||||||
javascript << ",#{speed}" unless speed.nil?
|
speed = js_options.delete :duration
|
||||||
javascript << ");"
|
speed = (speed * 1000).to_i unless speed.nil?
|
||||||
end
|
else
|
||||||
|
speed = js_options.delete :speed
|
||||||
end
|
end
|
||||||
|
|
||||||
def sortable_element_js(element_id, options = {}) #:nodoc:
|
if ['fadeIn','fadeOut','fadeToggle'].include?(name)
|
||||||
#convert similar attributes
|
# 090905 - Jake - changed ' to \" so it passes assert_select_rjs with an id
|
||||||
options[:handle] = ".#{options[:handle]}" if options[:handle]
|
javascript = "#{JQUERY_VAR}(\"#{jquery_id(element_id)}\").#{name}("
|
||||||
if options[:tag] || options[:only]
|
javascript << "#{speed}" unless speed.nil?
|
||||||
options[:items] = "> "
|
javascript << ");"
|
||||||
options[:items] << options.delete(:tag) if options[:tag]
|
else
|
||||||
options[:items] << ".#{options.delete(:only)}" if options[:only]
|
# 090905 - Jake - changed ' to \" so it passes "assert_select_rjs :effect, ID"
|
||||||
end
|
javascript = "#{JQUERY_VAR}(\"#{jquery_id(element_id)}\").#{mode || 'effect'}('#{name}'"
|
||||||
options[:connectWith] = options.delete(:containment).map {|x| "##{x}"} if options[:containment]
|
javascript << ",#{options_for_javascript(js_options)}" unless speed.nil? && js_options.empty?
|
||||||
options[:containment] = options.delete(:container) if options[:container]
|
javascript << ",#{speed}" unless speed.nil?
|
||||||
options[:dropOnEmpty] = false unless options[:dropOnEmpty]
|
javascript << ");"
|
||||||
options[:helper] = "'clone'" if options[:ghosting] == true
|
end
|
||||||
options[:axis] = case options.delete(:constraint)
|
|
||||||
when "vertical"
|
end
|
||||||
"y"
|
|
||||||
when "horizontal"
|
def sortable_element_js(element_id, options = {}) #:nodoc:
|
||||||
"x"
|
#convert similar attributes
|
||||||
when false
|
options[:handle] = ".#{options[:handle]}" if options[:handle]
|
||||||
nil
|
if options[:tag] || options[:only]
|
||||||
when nil
|
options[:items] = "> "
|
||||||
"y"
|
options[:items] << options.delete(:tag) if options[:tag]
|
||||||
end
|
options[:items] << ".#{options.delete(:only)}" if options[:only]
|
||||||
options.delete(:axis) if options[:axis].nil?
|
end
|
||||||
options.delete(:overlap)
|
options[:connectWith] = options.delete(:containment).map {|x| "##{x}"} if options[:containment]
|
||||||
options.delete(:ghosting)
|
options[:containment] = options.delete(:container) if options[:container]
|
||||||
|
options[:dropOnEmpty] = false unless options[:dropOnEmpty]
|
||||||
if options[:onUpdate] || options[:url]
|
options[:helper] = "'clone'" if options[:ghosting] == true
|
||||||
options[:with] ||= "#{JQUERY_VAR}(this).sortable('serialize',{key:'#{element_id}'})"
|
options[:axis] = case options.delete(:constraint)
|
||||||
options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
|
when "vertical", :vertical
|
||||||
end
|
"y"
|
||||||
|
when "horizontal", :horizontal
|
||||||
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
|
"x"
|
||||||
options[:update] = options.delete(:onUpdate) if options[:onUpdate]
|
when false
|
||||||
|
nil
|
||||||
[:axis, :cancel, :containment, :cursor, :handle, :tolerance, :items, :placeholder].each do |option|
|
when nil
|
||||||
options[option] = "'#{options[option]}'" if options[option]
|
"y"
|
||||||
end
|
end
|
||||||
|
options.delete(:axis) if options[:axis].nil?
|
||||||
options[:connectWith] = array_or_string_for_javascript(options[:connectWith]) if options[:connectWith]
|
options.delete(:overlap)
|
||||||
|
options.delete(:ghosting)
|
||||||
%(#{JQUERY_VAR}('#{jquery_id(element_id)}').sortable(#{options_for_javascript(options)});)
|
|
||||||
end
|
if options[:onUpdate] || options[:url]
|
||||||
|
if options[:format]
|
||||||
def draggable_element_js(element_id, options = {})
|
options[:with] ||= "#{JQUERY_VAR}(this).sortable('serialize',{key:'#{element_id}[]', expression:#{options[:format]}})"
|
||||||
%(#{JQUERY_VAR}("#{jquery_id(element_id)}").draggable(#{options_for_javascript(options)});)
|
options.delete(:format)
|
||||||
end
|
else
|
||||||
|
options[:with] ||= "#{JQUERY_VAR}(this).sortable('serialize',{key:'#{element_id}[]'})"
|
||||||
def drop_receiving_element_js(element_id, options = {})
|
end
|
||||||
#convert similar options
|
|
||||||
options[:hoverClass] = options.delete(:hoverclass) if options[:hoverclass]
|
options[:onUpdate] ||= "function(){" + remote_function(options) + "}"
|
||||||
options[:drop] = options.delete(:onDrop) if options[:onDrop]
|
end
|
||||||
|
|
||||||
if options[:drop] || options[:url]
|
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
|
||||||
options[:with] ||= "'id=' + encodeURIComponent(#{JQUERY_VAR}(ui.draggable).attr('id'))"
|
options[:update] = options.delete(:onUpdate) if options[:onUpdate]
|
||||||
options[:drop] ||= "function(ev, ui){" + remote_function(options) + "}"
|
|
||||||
end
|
[:axis, :cancel, :containment, :cursor, :handle, :tolerance, :items, :placeholder].each do |option|
|
||||||
|
options[option] = "'#{options[option]}'" if options[option]
|
||||||
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
|
end
|
||||||
|
|
||||||
options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept]
|
options[:connectWith] = array_or_string_for_javascript(options[:connectWith]) if options[:connectWith]
|
||||||
[:activeClass, :hoverClass, :tolerance].each do |option|
|
|
||||||
options[option] = "'#{options[option]}'" if options[option]
|
%(#{JQUERY_VAR}('#{jquery_id(element_id)}').sortable(#{options_for_javascript(options)});)
|
||||||
end
|
end
|
||||||
|
|
||||||
%(#{JQUERY_VAR}('#{jquery_id(element_id)}').droppable(#{options_for_javascript(options)});)
|
def draggable_element_js(element_id, options = {})
|
||||||
end
|
%(#{JQUERY_VAR}("#{jquery_id(element_id)}").draggable(#{options_for_javascript(options)});)
|
||||||
|
end
|
||||||
end
|
|
||||||
|
def drop_receiving_element_js(element_id, options = {})
|
||||||
end
|
#convert similar options
|
||||||
|
options[:hoverClass] = options.delete(:hoverclass) if options[:hoverclass]
|
||||||
|
options[:drop] = options.delete(:onDrop) if options[:onDrop]
|
||||||
|
|
||||||
|
if options[:drop] || options[:url]
|
||||||
|
options[:with] ||= "'id=' + encodeURIComponent(#{JQUERY_VAR}(ui.draggable).attr('id'))"
|
||||||
|
options[:drop] ||= "function(ev, ui){" + remote_function(options) + "}"
|
||||||
|
end
|
||||||
|
|
||||||
|
options.delete_if { |key, value| PrototypeHelper::AJAX_OPTIONS.include?(key) }
|
||||||
|
|
||||||
|
options[:accept] = array_or_string_for_javascript(options[:accept]) if options[:accept]
|
||||||
|
[:activeClass, :hoverClass, :tolerance].each do |option|
|
||||||
|
options[option] = "'#{options[option]}'" if options[option]
|
||||||
|
end
|
||||||
|
|
||||||
|
%(#{JQUERY_VAR}('#{jquery_id(element_id)}').droppable(#{options_for_javascript(options)});)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# The following options can be changed by creating an initializer in config/initializers/jrails.rb
|
||||||
|
|
||||||
|
# jRails uses jQuery.noConflict() by default
|
||||||
|
# to use the default jQuery varibale, use:
|
||||||
|
# ActionView::Helpers::PrototypeHelper::JQUERY_VAR = '$'
|
||||||
|
|
||||||
|
# ActionView::Helpers::PrototypeHelper:: DISABLE_JQUERY_FORGERY_PROTECTION
|
||||||
|
# Set this to disable forgery protection in ajax calls
|
||||||
|
# This is handy if you want to use caching with ajax by injecting the forgery token via another means
|
||||||
|
# for an example, see http://henrik.nyh.se/2008/05/rails-authenticity-token-with-jquery
|
||||||
|
# ActionView::Helpers::PrototypeHelper::DISABLE_JQUERY_FORGERY_PROTECTION = true
|
||||||
|
|
||||||
|
ActionView::Helpers::AssetTagHelper::JAVASCRIPT_DEFAULT_SOURCES = ['jquery','jquery-ui','jrails']
|
||||||
|
ActionView::Helpers::AssetTagHelper::reset_javascript_include_default
|
||||||
|
require 'jrails'
|
||||||
|
require 'jquery_selector_assertions' if RAILS_ENV == 'test'
|
|
@ -1,19 +1,25 @@
|
||||||
namespace :jrails do
|
namespace :jrails do
|
||||||
namespace :update do
|
|
||||||
|
namespace :js do
|
||||||
desc "Copies the jQuery and jRails javascripts to public/javascripts"
|
desc "Copies the jQuery and jRails javascripts to public/javascripts"
|
||||||
task :javascripts do
|
task :install do
|
||||||
puts "Copying files..."
|
puts "Copying files..."
|
||||||
project_dir = RAILS_ROOT + '/public/javascripts/'
|
project_dir = RAILS_ROOT + '/public/javascripts/'
|
||||||
scripts = Dir[File.join(File.dirname(__FILE__), '..') + '/javascripts/*.js']
|
scripts = Dir[File.join(File.dirname(__FILE__), '..', '/javascripts/', '*.js')]
|
||||||
FileUtils.cp(scripts, project_dir)
|
FileUtils.cp(scripts, project_dir)
|
||||||
puts "files copied successfully."
|
puts "files copied successfully."
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
namespace :install do
|
desc 'Remove the prototype / script.aculo.us javascript files'
|
||||||
desc "Installs the jQuery and jRails javascripts to public/javascripts"
|
task :scrub do
|
||||||
task :javascripts do
|
puts "Removing files..."
|
||||||
Rake::Task['jrails:update:javascripts'].invoke
|
files = %W[controls.js dragdrop.js effects.js prototype.js]
|
||||||
end
|
project_dir = File.join(RAILS_ROOT, 'public', 'javascripts')
|
||||||
end
|
files.each do |fname|
|
||||||
|
FileUtils.rm(File.join(project_dir, fname)) if File.exists?(File.join(project_dir, fname))
|
||||||
|
end
|
||||||
|
puts "files removed successfully."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue