From 4bb0a6aa3ab39bb48a4a9502bcdecbdd407b48ce Mon Sep 17 00:00:00 2001 From: Richard Kimber Date: Sun, 11 May 2014 12:14:09 +0100 Subject: [PATCH 1/4] Send submitting elements value along with post --- jquery.pjax.js | 50 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/jquery.pjax.js b/jquery.pjax.js index 7c1d3535..77570004 100644 --- a/jquery.pjax.js +++ b/jquery.pjax.js @@ -117,7 +117,8 @@ function handleClick(event, container, options) { function handleSubmit(event, container, options) { options = optionsFor(container, options) - var form = event.currentTarget + var form = event.currentTarget, + $form = $(form) if (form.tagName.toUpperCase() !== 'FORM') throw "$.pjax.submit requires a form element" @@ -125,8 +126,8 @@ function handleSubmit(event, container, options) { var defaults = { type: form.method.toUpperCase(), url: form.action, - data: $(form).serializeArray(), - container: $(form).attr('data-pjax'), + data: $form.serializeArray(), + container: $form.attr('data-pjax'), target: form } @@ -135,6 +136,44 @@ function handleSubmit(event, container, options) { event.preventDefault() } +var submitClickSelectors = 'form[data-pjax] input[type=submit],\ + form[data-pjax] button[type=submit],\ + form[data-pjax] button:not([type])'; + +// Private: sends value of submitting element along form post +// +// event - "click" jQuery.Event +// +// Returns nothing. +function handleSubmitClick(event) { + var $submit = $(this), + $form = $submit.closest('form'), + hiddenClass = 'pjax-submit-button-value' + $input = $form.find('.' + hiddenClass) + + if (name = $submit.attr('name')) { + var defaultValue = $submit.is('input[type=submit]') ? 'Submit' : '', + value = $submit.val() || defaultValue + + if (!$input.length) { + var input = document.createElement('input') + input.setAttribute('type', 'hidden') + input.setAttribute('name', name) + input.setAttribute('value', value) + input.setAttribute('class', hiddenClass) + + $form.prepend(input) + } + else { + $input.attr('name', name) + $input.val(value) + } + } + else { + $input.remove() + } +} + // Loads a URL with ajax, puts the response body inside a container, // then pushState()'s the loaded URL. // @@ -798,7 +837,10 @@ function enable() { maxCacheLength: 20, version: findVersion } + $(window).on('popstate.pjax', onPjaxPopstate) + + $(document).on('click', submitClickSelectors, handleSubmitClick) } // Disable pushState behavior. @@ -822,6 +864,8 @@ function disable() { $.pjax.reload = function() { window.location.reload() } $(window).off('popstate.pjax', onPjaxPopstate) + + $(document).off('click', submitClickSelectors, handleSubmitClick) } From ba0292e42e5ad4a6a99ad4cc1f77aa89349f2c56 Mon Sep 17 00:00:00 2001 From: Richard Kimber Date: Sun, 11 May 2014 13:59:10 +0100 Subject: [PATCH 2/4] Added missing comma to `handleSubmitClick` --- jquery.pjax.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.pjax.js b/jquery.pjax.js index 77570004..71d87fa2 100644 --- a/jquery.pjax.js +++ b/jquery.pjax.js @@ -148,7 +148,7 @@ var submitClickSelectors = 'form[data-pjax] input[type=submit],\ function handleSubmitClick(event) { var $submit = $(this), $form = $submit.closest('form'), - hiddenClass = 'pjax-submit-button-value' + hiddenClass = 'pjax-submit-button-value', $input = $form.find('.' + hiddenClass) if (name = $submit.attr('name')) { From dff21decac654a79d205072020cf4cd811131956 Mon Sep 17 00:00:00 2001 From: Richard Kimber Date: Mon, 12 May 2014 00:44:44 +0100 Subject: [PATCH 3/4] Used data attribute instead of hidden field, added unit test --- jquery.pjax.js | 33 +++++++++++---------------------- test/app.rb | 6 +++++- test/unit/form.js | 29 +++++++++++++++++++++++++++++ test/views/form.erb | 20 ++++++++++++++++++++ test/views/form_post.erb | 1 + test/views/qunit.erb | 1 + 6 files changed, 67 insertions(+), 23 deletions(-) create mode 100644 test/unit/form.js create mode 100644 test/views/form.erb create mode 100644 test/views/form_post.erb diff --git a/jquery.pjax.js b/jquery.pjax.js index 71d87fa2..ba28b744 100644 --- a/jquery.pjax.js +++ b/jquery.pjax.js @@ -123,10 +123,15 @@ function handleSubmit(event, container, options) { if (form.tagName.toUpperCase() !== 'FORM') throw "$.pjax.submit requires a form element" + var data = $form.serializeArray() + + if (submitButton = $form.data(submitButtonAttr)) + data.push(submitButton) + var defaults = { type: form.method.toUpperCase(), url: form.action, - data: $form.serializeArray(), + data: data, container: $form.attr('data-pjax'), target: form } @@ -138,7 +143,8 @@ function handleSubmit(event, container, options) { var submitClickSelectors = 'form[data-pjax] input[type=submit],\ form[data-pjax] button[type=submit],\ - form[data-pjax] button:not([type])'; + form[data-pjax] button:not([type])', + submitButtonAttr = 'pjax-submit-button-value' // Private: sends value of submitting element along form post // @@ -147,30 +153,13 @@ var submitClickSelectors = 'form[data-pjax] input[type=submit],\ // Returns nothing. function handleSubmitClick(event) { var $submit = $(this), - $form = $submit.closest('form'), - hiddenClass = 'pjax-submit-button-value', - $input = $form.find('.' + hiddenClass) + $form = $submit.closest('form') if (name = $submit.attr('name')) { - var defaultValue = $submit.is('input[type=submit]') ? 'Submit' : '', - value = $submit.val() || defaultValue - - if (!$input.length) { - var input = document.createElement('input') - input.setAttribute('type', 'hidden') - input.setAttribute('name', name) - input.setAttribute('value', value) - input.setAttribute('class', hiddenClass) - - $form.prepend(input) - } - else { - $input.attr('name', name) - $input.val(value) - } + $form.data(submitButtonAttr, { name: name, value: $submit.val() }) } else { - $input.remove() + $form.data(submitButtonAttr, null) } } diff --git a/test/app.rb b/test/app.rb index 9be09f53..668d95eb 100644 --- a/test/app.rb +++ b/test/app.rb @@ -28,7 +28,7 @@ def title(str) get '/' do - erb :qunit + erb :qunit, :layout => false end get '/jquery.pjax.js' do @@ -86,3 +86,7 @@ def title(str) get '/:page.html' do erb :"#{params[:page]}", :layout => !pjax? end + +post '/form_post.html' do + erb :form_post, :layout => !pjax? +end diff --git a/test/unit/form.js b/test/unit/form.js new file mode 100644 index 00000000..2013b79d --- /dev/null +++ b/test/unit/form.js @@ -0,0 +1,29 @@ +if ($.support.pjax) { + module("handleSubmit", { + setup: function() { + var self = this + stop() + window.iframeLoad = function(frame) { + self.frame = frame + window.iframeLoad = $.noop + start() + } + $("#qunit-fixture").append("