├── .document ├── .gitignore ├── History.rdoc ├── LICENSE ├── README.rdoc ├── Rakefile ├── VERSION_COMPATIBILITY.rdoc ├── lib ├── generators │ └── remotipart │ │ └── install │ │ └── install_generator.rb ├── remotipart.rb └── remotipart │ ├── rails.rb │ ├── rails │ ├── engine.rb │ ├── railtie.rb │ └── version.rb │ ├── request_helper.rb │ └── view_helper.rb ├── remotipart.gemspec ├── test ├── helper.rb └── test_remotipart.rb └── vendor └── assets └── javascripts ├── jquery.form.js └── jquery.remotipart.js /.document: -------------------------------------------------------------------------------- 1 | README.rdoc 2 | lib/**/*.rb 3 | bin/* 4 | features/**/*.feature 5 | LICENSE 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## MAC OS 2 | .DS_Store 3 | 4 | ## TEXTMATE 5 | *.tmproj 6 | tmtags 7 | 8 | ## EMACS 9 | *~ 10 | \#* 11 | .\#* 12 | 13 | ## VIM 14 | *.swp 15 | 16 | ## PROJECT::GENERAL 17 | coverage 18 | rdoc 19 | pkg 20 | 21 | ## PROJECT::SPECIFIC 22 | -------------------------------------------------------------------------------- /History.rdoc: -------------------------------------------------------------------------------- 1 | = History 2 | 3 | === 0.4.2 / 2011-26-08 4 | 5 | * Minor Enhancements 6 | * Updated to jquery.form.js v2.84 7 | 8 | === 0.4.1 / 2011-07-12 9 | 10 | * Minor Enhancements 11 | * Updated README and docs 12 | 13 | === 0.4.0 / 2011-07-12 14 | 15 | * New Features 16 | * Added `remotipart_submitted?` helper method for controllers and views 17 | * Added railtie and engine support to add remotipart and dependencies to Rails 3.0 (in the js :defaults) and 3.1 (in the asset pipeline) apps automatically 18 | * Enhancements 19 | * Restructured gem to integrate better with Rails apps 20 | 21 | === 0.3.0 / 2011-02-24 22 | 23 | * New Features 24 | * Added support for all data-type ajax submissions, not just 'script'. 25 | * Made a little more flexible, so that separate js.erb response templates are no longer needed between remotipart (i.e. multipart) ajax form submissions and regular ajax form submissions, so multiple versions of the same form can now submit to the same action. 26 | 27 | === 0.2.1 / 2011-01-16 28 | 29 | * Minor Enhancements 30 | * Added support for passing text_area_tag options to remotipart_response. {GitHub Issue #7}[https://github.com/formasfunction/remotipart/issues#issue/7] - patch by {Todd Eichel}[https://github.com/tfe] 31 | 32 | === 0.2.0 / 2010-12-08 33 | 34 | * Bug Fixes 35 | * Added support for form action URLs that include GET params. {GitHub Issue #4}[https://github.com/formasfunction/remotipart/issues/closed#issue/4] - initial patch by ramontayag[https://github.com/ramontayag]. 36 | * Added proper HTML escaping for the remotipart_response textarea content. {GitHub Issue #5}[https://github.com/formasfunction/remotipart/issues/closed#issue/5] - patch by gucki[https://github.com/gucki]. 37 | 38 | === 0.1.1 / 2010-08-27 39 | 40 | * Bug Fixes 41 | * Removed a call to the JS console. {GitHub Issue #1}[https://github.com/formasfunction/remotipart/issues/closed#issue/5] - reported by {Trevor Burnham}[https://github.com/TrevorBurnham]. 42 | 43 | === 0.1.0 / 2010-04-09 44 | 45 | * Initial Release 46 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 Greg Leppert 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = THIS REPOSITORY IS NO LONGER BEING MAINTAINED 2 | 3 | Remotipart has a new home and is now being maintained at https://github.com/JangoSteve/remotipart. 4 | 5 | == Remotipart 6 | 7 | Remotipart is a Ruby on Rails gem enabling remote multipart forms (AJAX style file uploads) with jQuery. 8 | This gem augments the native Rails jQuery remote form function enabling asynchronous file uploads with little to no modification to your application. 9 | 10 | {View Homepage and Demos}[http://opensource.alfajango.com/remotipart/] 11 | 12 | == Copyright 13 | 14 | Copyright (c) 2011 Greg Leppert, Steve Schwartz. See LICENSE for details. 15 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | require File.expand_path('../lib/remotipart/rails/version', __FILE__) 4 | 5 | begin 6 | require 'jeweler' 7 | Jeweler::Tasks.new do |gem| 8 | gem.name = "remotipart" 9 | gem.summary = %Q{Remotipart is a Ruby on Rails gem enabling remote multipart forms (AJAX style file uploads) with jQuery.} 10 | gem.description = %Q{Remotipart is a Ruby on Rails gem enabling remote multipart forms (AJAX style file uploads) with jQuery. 11 | This gem augments the native Rails 3 jQuery-UJS remote form function enabling asynchronous file uploads with little to no modification to your application. 12 | } 13 | gem.email = %w{greg@formasfunction.com steve@alfajango.com} 14 | gem.homepage = "http://www.alfajango.com/blog/remotipart-rails-gem/" 15 | gem.authors = ["Greg Leppert", "Steve Schwartz"] 16 | gem.add_development_dependency "thoughtbot-shoulda", ">= 0" 17 | gem.version = Remotipart::Rails::VERSION 18 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings 19 | end 20 | Jeweler::GemcutterTasks.new 21 | rescue LoadError 22 | puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" 23 | end 24 | 25 | require 'rake/testtask' 26 | Rake::TestTask.new(:test) do |test| 27 | test.libs << 'lib' << 'test' 28 | test.pattern = 'test/**/test_*.rb' 29 | test.verbose = true 30 | end 31 | 32 | begin 33 | require 'rcov/rcovtask' 34 | Rcov::RcovTask.new do |test| 35 | test.libs << 'test' 36 | test.pattern = 'test/**/test_*.rb' 37 | test.verbose = true 38 | end 39 | rescue LoadError 40 | task :rcov do 41 | abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov" 42 | end 43 | end 44 | 45 | task :test => :check_dependencies 46 | 47 | task :default => :test 48 | 49 | require 'rake/rdoctask' 50 | require 'lib/remotipart/rails/version' 51 | Rake::RDocTask.new do |rdoc| 52 | version = Remotipart::Rails::VERSION 53 | 54 | rdoc.rdoc_dir = 'rdoc' 55 | rdoc.title = "remotipart #{version}" 56 | rdoc.rdoc_files.include('README*') 57 | rdoc.rdoc_files.include('lib/**/*.rb') 58 | end 59 | -------------------------------------------------------------------------------- /VERSION_COMPATIBILITY.rdoc: -------------------------------------------------------------------------------- 1 | = Version Compatibility 2 | 3 | +---------------------------------------------------------------------+ 4 | | Version of remotipart.js | is compatible with versions of rails.js* | 5 | +---------------------------------------------------------------------+ 6 | | <= 0.3.1 | <= 498b35e24cdb14f2 | 7 | | 0.3.2 | > 498b35e24cdb14f2, <= 7f2acc1811f62877 | 8 | | 0.3.3 | > 7f2acc1811f62877, <= d2abd6f9df4e4a42 | 9 | | >= 0.3.4 | > d2abd6f9df4e4a42 | (current version of rails.js) 10 | +---------------------------------------------------------------------+ 11 | 12 | *rails.js versions (For a full list of Rails.js]versions and diffs, see {Rails jQuery UJS Changelog}[https://github.com/rails/jquery-ujs/blob/master/CHANGELOG.md]): 13 | * {498b35e24cdb14f2}[https://github.com/rails/jquery-ujs/raw/498b35e24cdb14f2d94486e8a1f4a1f661091426/src/rails.js] 14 | * {7f2acc1811f62877}[https://github.com/rails/jquery-ujs/raw/7f2acc1811f62877611e16451530728b5e13dbe7/src/rails.js] 15 | * {d2abd6f9df4e4a42}[https://github.com/rails/jquery-ujs/raw/d2abd6f9df4e4a426c17c218b7d5e05004c768d0/src/rails.js] 16 | * {current}[https://github.com/rails/jquery-ujs/raw/master/src/rails.js] 17 | 18 | == Installation for Remotipart v0.3.x 19 | 20 | Prerequisite: Make sure you have a supported jquery-ujs (rails.js) version from the previous section. 21 | 22 | 1. Install the Remotipart gem 23 | 24 | * Add this line to your GEMFILE (add the correct version from previous section if needed) 25 | 26 | gem 'remotipart' 27 | 28 | * And run 29 | 30 | bundle install 31 | 32 | 2. Run the Remotipart generator to add jquery.remotipart.js to public/javascripts/ 33 | 34 | rails g remotipart 35 | 36 | 3. Add the Javascript files for jQuery, the Rails jQuery driver, jQuery Form plugin, and Remotipart to your template, making sure to include jquery.remotipart.js *after* jQuery and the Rails jQuery driver 37 | 38 | <%= javascript_include_tag 'jquery-1.4.4.min', 'rails', 'jquery.form', 'jquery.remotipart' %> 39 | -------------------------------------------------------------------------------- /lib/generators/remotipart/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | require 'rails' 2 | 3 | module Remotipart 4 | module Generators 5 | class InstallGenerator < ::Rails::Generators::Base 6 | 7 | desc "This generator installs Form.js #{Remotipart::Rails::FORMJS_VERSION} and Remotipart #{Remotipart::Rails::VERSION}" 8 | source_root File.expand_path('../../../../../vendor/assets/javascripts', __FILE__) 9 | 10 | def install_formjs 11 | say_status "copying", "Form.js #{Remotipart::Rails::FORMJS_VERSION}", :green 12 | copy_file "jquery.form.js", "public/javascripts/jquery.form.js" 13 | end 14 | 15 | def install_remotipart 16 | say_status "copying", "Remotipart.js #{Remotipart::Rails::VERSION}", :green 17 | copy_file 'jquery.remotipart.js', 'public/javascripts/jquery.remotipart.js' 18 | end 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /lib/remotipart.rb: -------------------------------------------------------------------------------- 1 | require 'remotipart/view_helper' 2 | require 'remotipart/request_helper' 3 | require 'remotipart/rails' if defined?(Rails) 4 | -------------------------------------------------------------------------------- /lib/remotipart/rails.rb: -------------------------------------------------------------------------------- 1 | module Remotipart 2 | module Rails 3 | if ::Rails.version < "3.1" 4 | require 'remotipart/rails/railtie' 5 | else 6 | require 'remotipart/rails/engine' 7 | end 8 | require 'remotipart/rails/version' 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/remotipart/rails/engine.rb: -------------------------------------------------------------------------------- 1 | # Configure Rails 3.1 2 | module Remotipart 3 | module Rails 4 | 5 | class Engine < ::Rails::Engine 6 | initializer "remotipart.view_helper" do 7 | ActionView::Base.send :include, RequestHelper 8 | ActionView::Base.send :include, ViewHelper 9 | end 10 | 11 | initializer "remotipart.controller_helper" do 12 | ActionController::Base.send :include, RequestHelper 13 | end 14 | end 15 | 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /lib/remotipart/rails/railtie.rb: -------------------------------------------------------------------------------- 1 | # Configure Rails 3.0 to use form.js and remotipart 2 | module Remotipart 3 | module Rails 4 | 5 | class Railtie < ::Rails::Railtie 6 | config.before_configuration do 7 | # Files to be added to :defaults 8 | FILES = ['jquery.form', 'jquery.remotipart'] 9 | 10 | # Figure out where rails.js (aka jquery_ujs.js if install by jquery-rails gem) is 11 | # in the :defaults array 12 | position = config.action_view.javascript_expansions[:defaults].index('rails') || 13 | config.action_view.javascript_expansions[:defaults].index('jquery_ujs') 14 | 15 | # Merge form.js and then remotipart into :defaults array right after rails.js 16 | if position && position > 0 17 | config.action_view.javascript_expansions[:defaults].insert(position + 1, *FILES) 18 | # If rails.js couldn't be found, it may have a custom filename, or not be in the :defaults. 19 | # In that case, just try adding to the end of the :defaults array. 20 | else 21 | config.action_view.javascript_expansions[:defaults].push(*FILES) 22 | end 23 | end 24 | 25 | initializer "remotipart.view_helper" do 26 | ActionView::Base.send :include, RequestHelper 27 | ActionView::Base.send :include, ViewHelper 28 | end 29 | 30 | initializer "remotipart.controller_helper" do 31 | ActionController::Base.send :include, RequestHelper 32 | end 33 | end 34 | 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/remotipart/rails/version.rb: -------------------------------------------------------------------------------- 1 | module Remotipart 2 | module Rails 3 | VERSION = "0.4.2" 4 | FORMJS_VERSION = "2.84" 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /lib/remotipart/request_helper.rb: -------------------------------------------------------------------------------- 1 | module Remotipart 2 | module RequestHelper 3 | def remotipart_submitted? 4 | params[:remotipart_submitted] ? true : false 5 | end 6 | alias :remotipart_requested? :remotipart_submitted? 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /lib/remotipart/view_helper.rb: -------------------------------------------------------------------------------- 1 | module Remotipart 2 | module ViewHelper 3 | def remotipart_response(options = {}, &block) 4 | content = with_output_buffer(&block) 5 | if remotipart_submitted? 6 | response.content_type = Mime::HTML 7 | text_area_tag('remotipart_response', String.new(content), options) 8 | else 9 | content 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /remotipart.gemspec: -------------------------------------------------------------------------------- 1 | # Generated by jeweler 2 | # DO NOT EDIT THIS FILE DIRECTLY 3 | # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command 4 | # -*- encoding: utf-8 -*- 5 | 6 | Gem::Specification.new do |s| 7 | s.name = %q{remotipart} 8 | s.version = "0.4.2" 9 | 10 | s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= 11 | s.authors = ["Greg Leppert", "Steve Schwartz"] 12 | s.date = %q{2011-08-26} 13 | s.description = %q{Remotipart is a Ruby on Rails gem enabling remote multipart forms (AJAX style file uploads) with jQuery. 14 | This gem augments the native Rails 3 jQuery-UJS remote form function enabling asynchronous file uploads with little to no modification to your application. 15 | } 16 | s.email = ["greg@formasfunction.com", "steve@alfajango.com"] 17 | s.extra_rdoc_files = [ 18 | "LICENSE", 19 | "README.rdoc" 20 | ] 21 | s.files = [ 22 | ".document", 23 | ".gitignore", 24 | "History.rdoc", 25 | "LICENSE", 26 | "README.rdoc", 27 | "Rakefile", 28 | "VERSION_COMPATIBILITY.rdoc", 29 | "lib/generators/remotipart/install/install_generator.rb", 30 | "lib/remotipart.rb", 31 | "lib/remotipart/rails.rb", 32 | "lib/remotipart/rails/engine.rb", 33 | "lib/remotipart/rails/railtie.rb", 34 | "lib/remotipart/rails/version.rb", 35 | "lib/remotipart/request_helper.rb", 36 | "lib/remotipart/view_helper.rb", 37 | "remotipart.gemspec", 38 | "test/helper.rb", 39 | "test/test_remotipart.rb", 40 | "vendor/assets/javascripts/jquery.form.js", 41 | "vendor/assets/javascripts/jquery.remotipart.js" 42 | ] 43 | s.homepage = %q{http://www.alfajango.com/blog/remotipart-rails-gem/} 44 | s.rdoc_options = ["--charset=UTF-8"] 45 | s.require_paths = ["lib"] 46 | s.rubygems_version = %q{1.3.7} 47 | s.summary = %q{Remotipart is a Ruby on Rails gem enabling remote multipart forms (AJAX style file uploads) with jQuery.} 48 | s.test_files = [ 49 | "test/helper.rb", 50 | "test/test_remotipart.rb" 51 | ] 52 | 53 | if s.respond_to? :specification_version then 54 | current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION 55 | s.specification_version = 3 56 | 57 | if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then 58 | s.add_development_dependency(%q, [">= 0"]) 59 | else 60 | s.add_dependency(%q, [">= 0"]) 61 | end 62 | else 63 | s.add_dependency(%q, [">= 0"]) 64 | end 65 | end 66 | 67 | -------------------------------------------------------------------------------- /test/helper.rb: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'test/unit' 3 | require 'shoulda' 4 | 5 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 6 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 7 | require 'remotipart' 8 | 9 | class Test::Unit::TestCase 10 | end 11 | -------------------------------------------------------------------------------- /test/test_remotipart.rb: -------------------------------------------------------------------------------- 1 | require 'helper' 2 | 3 | class TestRemotipart < Test::Unit::TestCase 4 | should "probably rename this file and start testing for real" do 5 | flunk "hey buddy, you should probably rename this file and start testing for real" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/jquery.form.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jQuery Form Plugin 3 | * version: 2.84 (12-AUG-2011) 4 | * @requires jQuery v1.3.2 or later 5 | * 6 | * Examples and documentation at: http://malsup.com/jquery/form/ 7 | * Dual licensed under the MIT and GPL licenses: 8 | * http://www.opensource.org/licenses/mit-license.php 9 | * http://www.gnu.org/licenses/gpl.html 10 | */ 11 | ;(function($) { 12 | 13 | /* 14 | Usage Note: 15 | ----------- 16 | Do not use both ajaxSubmit and ajaxForm on the same form. These 17 | functions are intended to be exclusive. Use ajaxSubmit if you want 18 | to bind your own submit handler to the form. For example, 19 | 20 | $(document).ready(function() { 21 | $('#myForm').bind('submit', function(e) { 22 | e.preventDefault(); // <-- important 23 | $(this).ajaxSubmit({ 24 | target: '#output' 25 | }); 26 | }); 27 | }); 28 | 29 | Use ajaxForm when you want the plugin to manage all the event binding 30 | for you. For example, 31 | 32 | $(document).ready(function() { 33 | $('#myForm').ajaxForm({ 34 | target: '#output' 35 | }); 36 | }); 37 | 38 | When using ajaxForm, the ajaxSubmit function will be invoked for you 39 | at the appropriate time. 40 | */ 41 | 42 | /** 43 | * ajaxSubmit() provides a mechanism for immediately submitting 44 | * an HTML form using AJAX. 45 | */ 46 | $.fn.ajaxSubmit = function(options) { 47 | // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) 48 | if (!this.length) { 49 | log('ajaxSubmit: skipping submit process - no element selected'); 50 | return this; 51 | } 52 | 53 | var method, action, url, $form = this; 54 | 55 | if (typeof options == 'function') { 56 | options = { success: options }; 57 | } 58 | 59 | method = this.attr('method'); 60 | action = this.attr('action'); 61 | url = (typeof action === 'string') ? $.trim(action) : ''; 62 | url = url || window.location.href || ''; 63 | if (url) { 64 | // clean url (don't include hash vaue) 65 | url = (url.match(/^([^#]+)/)||[])[1]; 66 | } 67 | 68 | options = $.extend(true, { 69 | url: url, 70 | success: $.ajaxSettings.success, 71 | type: method || 'GET', 72 | iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' 73 | }, options); 74 | 75 | // hook for manipulating the form data before it is extracted; 76 | // convenient for use with rich editors like tinyMCE or FCKEditor 77 | var veto = {}; 78 | this.trigger('form-pre-serialize', [this, options, veto]); 79 | if (veto.veto) { 80 | log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); 81 | return this; 82 | } 83 | 84 | // provide opportunity to alter form data before it is serialized 85 | if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { 86 | log('ajaxSubmit: submit aborted via beforeSerialize callback'); 87 | return this; 88 | } 89 | 90 | var n,v,a = this.formToArray(options.semantic); 91 | if (options.data) { 92 | options.extraData = options.data; 93 | for (n in options.data) { 94 | if( $.isArray(options.data[n]) ) { 95 | for (var k in options.data[n]) { 96 | a.push( { name: n, value: options.data[n][k] } ); 97 | } 98 | } 99 | else { 100 | v = options.data[n]; 101 | v = $.isFunction(v) ? v() : v; // if value is fn, invoke it 102 | a.push( { name: n, value: v } ); 103 | } 104 | } 105 | } 106 | 107 | // give pre-submit callback an opportunity to abort the submit 108 | if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { 109 | log('ajaxSubmit: submit aborted via beforeSubmit callback'); 110 | return this; 111 | } 112 | 113 | // fire vetoable 'validate' event 114 | this.trigger('form-submit-validate', [a, this, options, veto]); 115 | if (veto.veto) { 116 | log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); 117 | return this; 118 | } 119 | 120 | var q = $.param(a); 121 | 122 | if (options.type.toUpperCase() == 'GET') { 123 | options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; 124 | options.data = null; // data is null for 'get' 125 | } 126 | else { 127 | options.data = q; // data is the query string for 'post' 128 | } 129 | 130 | var callbacks = []; 131 | if (options.resetForm) { 132 | callbacks.push(function() { $form.resetForm(); }); 133 | } 134 | if (options.clearForm) { 135 | callbacks.push(function() { $form.clearForm(); }); 136 | } 137 | 138 | // perform a load on the target only if dataType is not provided 139 | if (!options.dataType && options.target) { 140 | var oldSuccess = options.success || function(){}; 141 | callbacks.push(function(data) { 142 | var fn = options.replaceTarget ? 'replaceWith' : 'html'; 143 | $(options.target)[fn](data).each(oldSuccess, arguments); 144 | }); 145 | } 146 | else if (options.success) { 147 | callbacks.push(options.success); 148 | } 149 | 150 | options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg 151 | var context = options.context || options; // jQuery 1.4+ supports scope context 152 | for (var i=0, max=callbacks.length; i < max; i++) { 153 | callbacks[i].apply(context, [data, status, xhr || $form, $form]); 154 | } 155 | }; 156 | 157 | // are there files to upload? 158 | var fileInputs = $('input:file', this).length > 0; 159 | var mp = 'multipart/form-data'; 160 | var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); 161 | 162 | // options.iframe allows user to force iframe mode 163 | // 06-NOV-09: now defaulting to iframe mode if file input is detected 164 | if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { 165 | // hack to fix Safari hang (thanks to Tim Molendijk for this) 166 | // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d 167 | if (options.closeKeepAlive) { 168 | $.get(options.closeKeepAlive, function() { fileUpload(a); }); 169 | } 170 | else { 171 | fileUpload(a); 172 | } 173 | } 174 | else { 175 | // IE7 massage (see issue 57) 176 | if ($.browser.msie && method == 'get') { 177 | var ieMeth = $form[0].getAttribute('method'); 178 | if (typeof ieMeth === 'string') 179 | options.type = ieMeth; 180 | } 181 | $.ajax(options); 182 | } 183 | 184 | // fire 'notify' event 185 | this.trigger('form-submit-notify', [this, options]); 186 | return this; 187 | 188 | 189 | // private function for handling file uploads (hat tip to YAHOO!) 190 | function fileUpload(a) { 191 | var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; 192 | var useProp = !!$.fn.prop; 193 | 194 | if (a) { 195 | // ensure that every serialized input is still enabled 196 | for (i=0; i < a.length; i++) { 197 | el = $(form[a[i].name]); 198 | el[ useProp ? 'prop' : 'attr' ]('disabled', false); 199 | } 200 | } 201 | 202 | if ($(':input[name=submit],:input[id=submit]', form).length) { 203 | // if there is an input with a name or id of 'submit' then we won't be 204 | // able to invoke the submit fn on the form (at least not x-browser) 205 | alert('Error: Form elements must not have name or id of "submit".'); 206 | return; 207 | } 208 | 209 | s = $.extend(true, {}, $.ajaxSettings, options); 210 | s.context = s.context || s; 211 | id = 'jqFormIO' + (new Date().getTime()); 212 | if (s.iframeTarget) { 213 | $io = $(s.iframeTarget); 214 | n = $io.attr('name'); 215 | if (n == null) 216 | $io.attr('name', id); 217 | else 218 | id = n; 219 | } 220 | else { 221 | $io = $('