From 8661d856ce91249d055e90a8637264819e70d8fe Mon Sep 17 00:00:00 2001 From: Jake Benilov Date: Wed, 22 Apr 2015 16:00:25 +0000 Subject: [PATCH 01/11] report-a-problem: split responsibilities `window.GOVUK.reportAProblem` has been split into a `ReportAProblem` class (which is responsible for the entire report-a-problem widget) and a `ReportAProblemForm`, which is scoped to just the form. This refactoring makes the code less procedural. --- app/assets/javascripts/report-a-problem.js | 152 +++++++++++++-------- spec/javascripts/report-a-problem-spec.js | 2 +- 2 files changed, 96 insertions(+), 58 deletions(-) diff --git a/app/assets/javascripts/report-a-problem.js b/app/assets/javascripts/report-a-problem.js index 31dd3512a..7e05eaecf 100644 --- a/app/assets/javascripts/report-a-problem.js +++ b/app/assets/javascripts/report-a-problem.js @@ -11,74 +11,112 @@ $('.report-a-problem-content').html(response); }, - promptUserToEnterValidData: function() { - GOVUK.reportAProblem.enableSubmitButton(); - $('

Please enter details of what you were doing.

').insertAfter('.report-a-problem-container h2'); + showConfirmation: function(data) { + $('.report-a-problem-content').html(data.message); }, + } - disableSubmitButton: function() { - $('.report-a-problem-container .button').attr("disabled", true); - }, + var ReportAProblemForm = function($form) { + this.$form = $form; - enableSubmitButton: function() { - $('.report-a-problem-container .button').attr("disabled", false); - }, + this.appendHiddenContextInformation(); + this.configureSubmission(); + } - showConfirmation: function(data) { - $('.report-a-problem-content').html(data.message); - }, + ReportAProblemForm.prototype.appendHiddenContextInformation = function() { + // form submission for reporting a problem + this.$form.append(''); + this.$form.append($('').val(document.referrer || "unknown")); + }; + + ReportAProblemForm.prototype.configureSubmission = function() { + this.$form.submit($.proxy(this.submit, this)); + }; + + ReportAProblemForm.prototype.hidePrompt = function() { + this.$form.find('.error-notification').remove(); + }; + + ReportAProblemForm.prototype.disableSubmitButton = function() { + this.$form.find('.button').attr("disabled", true); + }; + + ReportAProblemForm.prototype.enableSubmitButton = function() { + this.$form.find('.button').attr("disabled", false); + }; + + ReportAProblemForm.prototype.promptUserToEnterValidData = function() { + this.enableSubmitButton(); + var $prompt = $('

Please enter details of what you were doing.

'); + this.$form.prepend($prompt); + }; - submit: function() { - $('.report-a-problem-container .error-notification').remove(); - $('input#url').val(window.location); - - GOVUK.reportAProblem.disableSubmitButton(); - $.ajax({ - type: "POST", - url: "/contact/govuk/problem_reports", - dataType: "json", - data: $('.report-a-problem-container form').serialize(), - success: GOVUK.reportAProblem.showConfirmation, - error: function(jqXHR, status) { - if (status === 'error' || !jqXHR.responseText) { - if (jqXHR.status == 422) { - GOVUK.reportAProblem.promptUserToEnterValidData(); - } - else { - GOVUK.reportAProblem.showErrorMessage(); - } - } - }, - statusCode: { - 500: GOVUK.reportAProblem.showErrorMessage - } - }); - return false; + ReportAProblemForm.prototype.handleError = function(jqXHR, status) { + if (status === 'error' || !jqXHR.responseText) { + if (jqXHR.status == 422) { + this.promptUserToEnterValidData(); + } + else { + GOVUK.reportAProblem.showErrorMessage(); + } } + }; + + ReportAProblemForm.prototype.setUrl = function() { + this.$form.find('input#url').val(window.location); } - $(document).ready(function() { - // Add in the toggle link for reporting a problem at the bottom of the page - var toggleBlock = ''; - var $container = $('.report-a-problem-container') - $container.before(toggleBlock); - - // Add a click handler for the toggle - $('.report-a-problem-toggle a').on('click', function() { + ReportAProblemForm.prototype.postFormViaAjax = function() { + $.ajax({ + type: "POST", + url: "/contact/govuk/problem_reports", + dataType: "json", + data: this.$form.serialize(), + success: GOVUK.reportAProblem.showConfirmation, + error: $.proxy(this.handleError, this), + statusCode: { + 500: GOVUK.reportAProblem.showErrorMessage + } + }); + } + + ReportAProblemForm.prototype.submit = function() { + this.hidePrompt(); + this.setUrl(); + this.disableSubmitButton(); + this.postFormViaAjax(); + + return false; + }; + + GOVUK.ReportAProblemForm = ReportAProblemForm; + + var ReportAProblem = function ($container) { + this.$container = $container; + + this.form = new GOVUK.ReportAProblemForm($container.find('form')); + + this.addToggleLink(); + }; + + ReportAProblem.prototype.addToggleLink = function() { + var $toggleBlock = $(''); + this.$container.before($toggleBlock); + + var $container = this.$container; + $toggleBlock.on("click", '.report-a-problem-toggle a', function(evt) { $container.toggle(); - return false; + evt.preventDefault(); }); + }; - // form submission for reporting a problem - var $form = $container.find('form'); - $form.append(''); - $form.append($('').val(document.referrer || "unknown")); - $form.submit(GOVUK.reportAProblem.submit); + GOVUK.ReportAProblem = ReportAProblem; + $(document).ready(function() { + new GOVUK.ReportAProblem($('.report-a-problem-container')); }); - }()); diff --git a/spec/javascripts/report-a-problem-spec.js b/spec/javascripts/report-a-problem-spec.js index 6fdcefbb9..a4d155ead 100644 --- a/spec/javascripts/report-a-problem-spec.js +++ b/spec/javascripts/report-a-problem-spec.js @@ -9,7 +9,7 @@ describe("form submission for reporting a problem", function () { beforeEach(function() { setFixtures(FORM_TEXT); form = $('form'); - form.submit(GOVUK.reportAProblem.submit); + new GOVUK.ReportAProblem($('.report-a-problem-container')); }); describe("while the request is being handled", function() { From 3dbd39656a214dee86a3a4f61d3908c148e63939 Mon Sep 17 00:00:00 2001 From: Jake Benilov Date: Wed, 22 Apr 2015 17:06:55 +0100 Subject: [PATCH 02/11] report-a-problem: increase test coverage --- spec/javascripts/report-a-problem-spec.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/javascripts/report-a-problem-spec.js b/spec/javascripts/report-a-problem-spec.js index a4d155ead..9ce8e050d 100644 --- a/spec/javascripts/report-a-problem-spec.js +++ b/spec/javascripts/report-a-problem-spec.js @@ -12,6 +12,28 @@ describe("form submission for reporting a problem", function () { new GOVUK.ReportAProblem($('.report-a-problem-container')); }); + it("should append a hidden 'javascript_enabled' field to the form", function() { + expect(form.find("[name=javascript_enabled]").val()).toBe("true"); + }); + + it("should append a hidden 'referrer' field to the form", function() { + expect(form.find("[name=referrer]").val()).toBe("unknown"); + }); + + describe("clicking on the toggle", function(){ + it("should toggle the visibility of the form", function() { + expect(form).toBeVisible(); + + $('a').click(); + + expect(form).toBeHidden(); + + $('a').click(); + + expect(form).toBeVisible(); + }); + }); + describe("while the request is being handled", function() { it("should disable the submit button to prevent multiple problem reports", function () { spyOn($, "ajax").and.callFake(function(options) {}); From 1bdd02bc344570ce2642ea61a959718f79b7b4df Mon Sep 17 00:00:00 2001 From: Paul Hayes Date: Wed, 22 Apr 2015 13:21:53 +0100 Subject: [PATCH 03/11] Move `show` message methods into form Remove last use of `reportAProblem` --- app/assets/javascripts/report-a-problem.js | 31 +++++++++++----------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/app/assets/javascripts/report-a-problem.js b/app/assets/javascripts/report-a-problem.js index 7e05eaecf..0a1cdceb3 100644 --- a/app/assets/javascripts/report-a-problem.js +++ b/app/assets/javascripts/report-a-problem.js @@ -3,19 +3,6 @@ window.GOVUK = window.GOVUK || {}; - window.GOVUK.reportAProblem = { - showErrorMessage: function (jqXHR) { - var response = "

Sorry, we're unable to receive your message right now.

" + - "

We have other ways for you to provide feedback on the " + - "contact page.

" - $('.report-a-problem-content').html(response); - }, - - showConfirmation: function(data) { - $('.report-a-problem-content').html(data.message); - }, - } - var ReportAProblemForm = function($form) { this.$form = $form; @@ -72,13 +59,13 @@ url: "/contact/govuk/problem_reports", dataType: "json", data: this.$form.serialize(), - success: GOVUK.reportAProblem.showConfirmation, + success: $.proxy(this.showConfirmation, this), error: $.proxy(this.handleError, this), statusCode: { - 500: GOVUK.reportAProblem.showErrorMessage + 500: $.proxy(this.showErrorMessage, this), } }); - } + }; ReportAProblemForm.prototype.submit = function() { this.hidePrompt(); @@ -89,6 +76,18 @@ return false; }; + ReportAProblemForm.prototype.showConfirmation = function(data) { + $('.report-a-problem-content').html(data.message); + }; + + ReportAProblemForm.prototype.showErrorMessage = function(jqXHR) { + var response = "

Sorry, we're unable to receive your message right now.

" + + "

We have other ways for you to provide feedback on the " + + "contact page.

"; + + $('.report-a-problem-content').html(response); + }; + GOVUK.ReportAProblemForm = ReportAProblemForm; var ReportAProblem = function ($container) { From 2debdfdd7169b691b47183bfeeb748ace40eaf72 Mon Sep 17 00:00:00 2001 From: Paul Hayes Date: Wed, 22 Apr 2015 13:25:20 +0100 Subject: [PATCH 04/11] Move ReportAProblemForm into file Split ReportAProblemForm and ReportAProblem into two files for clarity. --- app/assets/javascripts/header-footer-only.js | 1 + .../javascripts/report-a-problem-form.js | 91 +++++++++++++++++++ app/assets/javascripts/report-a-problem.js | 88 ------------------ 3 files changed, 92 insertions(+), 88 deletions(-) create mode 100644 app/assets/javascripts/report-a-problem-form.js diff --git a/app/assets/javascripts/header-footer-only.js b/app/assets/javascripts/header-footer-only.js index af2946172..d4983d667 100644 --- a/app/assets/javascripts/header-footer-only.js +++ b/app/assets/javascripts/header-footer-only.js @@ -3,6 +3,7 @@ //= require analytics //= require user-satisfaction-survey //= require core +//= require report-a-problem-form //= require report-a-problem //= require govuk/selection-buttons //= require govuk-component/govspeak-enhance-youtube-video-links diff --git a/app/assets/javascripts/report-a-problem-form.js b/app/assets/javascripts/report-a-problem-form.js new file mode 100644 index 000000000..714a2e801 --- /dev/null +++ b/app/assets/javascripts/report-a-problem-form.js @@ -0,0 +1,91 @@ +(function() { + "use strict"; + window.GOVUK = window.GOVUK || {}; + + var ReportAProblemForm = function($form) { + this.$form = $form; + + this.appendHiddenContextInformation(); + this.configureSubmission(); + } + + ReportAProblemForm.prototype.appendHiddenContextInformation = function() { + // form submission for reporting a problem + this.$form.append(''); + this.$form.append($('').val(document.referrer || "unknown")); + }; + + ReportAProblemForm.prototype.configureSubmission = function() { + this.$form.submit($.proxy(this.submit, this)); + }; + + ReportAProblemForm.prototype.hidePrompt = function() { + this.$form.find('.error-notification').remove(); + }; + + ReportAProblemForm.prototype.disableSubmitButton = function() { + this.$form.find('.button').attr("disabled", true); + }; + + ReportAProblemForm.prototype.enableSubmitButton = function() { + this.$form.find('.button').attr("disabled", false); + }; + + ReportAProblemForm.prototype.promptUserToEnterValidData = function() { + this.enableSubmitButton(); + var $prompt = $('

Please enter details of what you were doing.

'); + this.$form.prepend($prompt); + }; + + ReportAProblemForm.prototype.handleError = function(jqXHR, status) { + if (status === 'error' || !jqXHR.responseText) { + if (jqXHR.status == 422) { + this.promptUserToEnterValidData(); + } + else { + GOVUK.reportAProblem.showErrorMessage(); + } + } + }; + + ReportAProblemForm.prototype.setUrl = function() { + this.$form.find('input#url').val(window.location); + } + + ReportAProblemForm.prototype.postFormViaAjax = function() { + $.ajax({ + type: "POST", + url: "/contact/govuk/problem_reports", + dataType: "json", + data: this.$form.serialize(), + success: $.proxy(this.showConfirmation, this), + error: $.proxy(this.handleError, this), + statusCode: { + 500: $.proxy(this.showErrorMessage, this), + } + }); + }; + + ReportAProblemForm.prototype.submit = function() { + this.hidePrompt(); + this.setUrl(); + this.disableSubmitButton(); + this.postFormViaAjax(); + + return false; + }; + + ReportAProblemForm.prototype.showConfirmation = function(data) { + $('.report-a-problem-content').html(data.message); + }; + + ReportAProblemForm.prototype.showErrorMessage = function(jqXHR) { + var response = "

Sorry, we're unable to receive your message right now.

" + + "

We have other ways for you to provide feedback on the " + + "contact page.

"; + + $('.report-a-problem-content').html(response); + }; + + GOVUK.ReportAProblemForm = ReportAProblemForm; +}()); diff --git a/app/assets/javascripts/report-a-problem.js b/app/assets/javascripts/report-a-problem.js index 0a1cdceb3..ec6daa70c 100644 --- a/app/assets/javascripts/report-a-problem.js +++ b/app/assets/javascripts/report-a-problem.js @@ -1,95 +1,7 @@ (function() { "use strict"; - window.GOVUK = window.GOVUK || {}; - var ReportAProblemForm = function($form) { - this.$form = $form; - - this.appendHiddenContextInformation(); - this.configureSubmission(); - } - - ReportAProblemForm.prototype.appendHiddenContextInformation = function() { - // form submission for reporting a problem - this.$form.append(''); - this.$form.append($('').val(document.referrer || "unknown")); - }; - - ReportAProblemForm.prototype.configureSubmission = function() { - this.$form.submit($.proxy(this.submit, this)); - }; - - ReportAProblemForm.prototype.hidePrompt = function() { - this.$form.find('.error-notification').remove(); - }; - - ReportAProblemForm.prototype.disableSubmitButton = function() { - this.$form.find('.button').attr("disabled", true); - }; - - ReportAProblemForm.prototype.enableSubmitButton = function() { - this.$form.find('.button').attr("disabled", false); - }; - - ReportAProblemForm.prototype.promptUserToEnterValidData = function() { - this.enableSubmitButton(); - var $prompt = $('

Please enter details of what you were doing.

'); - this.$form.prepend($prompt); - }; - - ReportAProblemForm.prototype.handleError = function(jqXHR, status) { - if (status === 'error' || !jqXHR.responseText) { - if (jqXHR.status == 422) { - this.promptUserToEnterValidData(); - } - else { - GOVUK.reportAProblem.showErrorMessage(); - } - } - }; - - ReportAProblemForm.prototype.setUrl = function() { - this.$form.find('input#url').val(window.location); - } - - ReportAProblemForm.prototype.postFormViaAjax = function() { - $.ajax({ - type: "POST", - url: "/contact/govuk/problem_reports", - dataType: "json", - data: this.$form.serialize(), - success: $.proxy(this.showConfirmation, this), - error: $.proxy(this.handleError, this), - statusCode: { - 500: $.proxy(this.showErrorMessage, this), - } - }); - }; - - ReportAProblemForm.prototype.submit = function() { - this.hidePrompt(); - this.setUrl(); - this.disableSubmitButton(); - this.postFormViaAjax(); - - return false; - }; - - ReportAProblemForm.prototype.showConfirmation = function(data) { - $('.report-a-problem-content').html(data.message); - }; - - ReportAProblemForm.prototype.showErrorMessage = function(jqXHR) { - var response = "

Sorry, we're unable to receive your message right now.

" + - "

We have other ways for you to provide feedback on the " + - "contact page.

"; - - $('.report-a-problem-content').html(response); - }; - - GOVUK.ReportAProblemForm = ReportAProblemForm; - var ReportAProblem = function ($container) { this.$container = $container; From 57202c332eee99a337bfdacef6f9e575b0a1d654 Mon Sep 17 00:00:00 2001 From: Paul Hayes Date: Wed, 22 Apr 2015 13:30:11 +0100 Subject: [PATCH 05/11] Cleanup addToggleLink method MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Don’t concatenate string, use `\` line break * Move `var` declaration to top * Keep quotes consistent --- app/assets/javascripts/report-a-problem.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/report-a-problem.js b/app/assets/javascripts/report-a-problem.js index ec6daa70c..22ba85477 100644 --- a/app/assets/javascripts/report-a-problem.js +++ b/app/assets/javascripts/report-a-problem.js @@ -4,22 +4,21 @@ var ReportAProblem = function ($container) { this.$container = $container; - this.form = new GOVUK.ReportAProblemForm($container.find('form')); - this.addToggleLink(); }; ReportAProblem.prototype.addToggleLink = function() { - var $toggleBlock = $(''); - this.$container.before($toggleBlock); + var $container = this.$container, + $toggle = $('\ + '); - var $container = this.$container; - $toggleBlock.on("click", '.report-a-problem-toggle a', function(evt) { + $container.before($toggle); + $toggle.on("click", ".report-a-problem-toggle a", function(evt) { $container.toggle(); evt.preventDefault(); }); From d878d21381009b066b0c9d84736574775a62c700 Mon Sep 17 00:00:00 2001 From: Paul Hayes Date: Wed, 22 Apr 2015 13:34:41 +0100 Subject: [PATCH 06/11] Minimise use of `this` in report a problem Improve readability of module --- app/assets/javascripts/report-a-problem.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/report-a-problem.js b/app/assets/javascripts/report-a-problem.js index 22ba85477..5ac8d493c 100644 --- a/app/assets/javascripts/report-a-problem.js +++ b/app/assets/javascripts/report-a-problem.js @@ -3,14 +3,13 @@ window.GOVUK = window.GOVUK || {}; var ReportAProblem = function ($container) { - this.$container = $container; - this.form = new GOVUK.ReportAProblemForm($container.find('form')); - this.addToggleLink(); + var form = new GOVUK.ReportAProblemForm($container.find('form')); + + this.addToggleLink($container); }; - ReportAProblem.prototype.addToggleLink = function() { - var $container = this.$container, - $toggle = $('\ + ReportAProblem.prototype.addToggleLink = function($container) { + var $toggle = $('\