Skip to content

Commit

Permalink
Determination javascript using Gov.UK recommended style
Browse files Browse the repository at this point in the history
... and without jQuery.
  • Loading branch information
jrmhaig committed Jul 10, 2023
1 parent c6f1bb6 commit f66f596
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 119 deletions.
2 changes: 1 addition & 1 deletion app/views/layouts/application.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
%script
!= ga_outlet

%body{ class: "govuk-template__body controller-#{controller.controller_name}" }
%body{ class: "govuk-template__body controller-#{controller.controller_name} govuk-frontend-supported" }
:javascript
document.body.className = ((document.body.className) ? document.body.className + ' js-enabled' : 'js-enabled');

Expand Down
2 changes: 1 addition & 1 deletion app/views/shared/_determinations_form.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
%div
= validation_error_message(@error_presenter, :determinations)

= govuk_table( id: 'determinations', class: 'js-cw-claim-assessment', data: { apply_vat: "#{claim.apply_vat}", vat_url: vat_path(format: :json), submitted_date: claim.vat_date(:db), scheme: claim.agfs? ? 'agfs' : 'lgfs' }) do
= govuk_table( id: 'determinations', class: 'js-cw-claim-assessment', data: { module: 'govuk-determination', apply_vat: "#{claim.apply_vat}", vat_url: vat_path(format: :json), submitted_date: claim.vat_date(:db), scheme: claim.agfs? ? 'agfs' : 'lgfs' }) do
= govuk_table_caption(class: 'govuk-visually-hidden') do
%h3.govuk-heading-m
= t('.assessment_summary')
Expand Down

This file was deleted.

78 changes: 78 additions & 0 deletions app/webpack/javascripts/modules/determination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/**
* Component name
*/
export class Determination {
/**
* @param {Element} $module - HTML element to use for component
*/
constructor($module) {
if (!($module instanceof HTMLElement) || !document.body.classList.contains('govuk-frontend-supported')) {
return this
}

this.$module = $module

// Code goes here
}

/**
* Initialise component
*/
init() {
// Check that required elements are present
if (!this.$module) {
return
}

// Code goes here
const $module = this.$module

this.$totalExclVat = document.getElementsByClassName('js-total-exc-vat-determination')[0]
this.$totalVat = $module.getElementsByClassName('js-vat-determination')[0]
this.$LgfsVat = $module.getElementsByClassName('js-lgfs-vat-determination')[0]
this.$totalInclVat = $module.getElementsByClassName('js-total-determination')[0]
this.scheme = $module.dataset.scheme
// Should this be this.applyVat?
this.ajaxVat = $module.dataset.applyVat
this.vatUrl = $module.dataset.vatUrl
this.vatDate = $module.dataset.submittedDate

this.fields = [
document.getElementById('claim_assessment_attributes_fees'),
document.getElementById('claim_assessment_attributes_expenses'),
document.getElementById('claim_assessment_attributes_disbursements'),
document.getElementById('claim_assessment_attributes_vat_amount')
].filter(field => field)
this.fields.forEach(element => element.addEventListener('change', async () => await this.calculateTotalRows()))
}

async calculateTotalRows() {
const total = this.fields.reduce((n, field) => n + this.parsedValue(field), 0).toFixed(2)
const data = await this.applyVat(total)
this.$totalExclVat.innerHTML = data.net_amount
if (this.$totalVat) { this.$totalVat.innerHTML = data.vat_amount }
this.$totalInclVat.innerHTML = data.total_inc_vat
}

parsedValue(field) {
const value = parseFloat(field?.value)
if (value) {
return Math.max(0.0, value)
} else {
return 0.0
}
}

async applyVat(netAmount) {
const params = new URLSearchParams({
scheme: this.scheme,
lgfs_vat_amount: this.$LgfsVat?.value,
date: this.vatDate,
apply_vat: this.ajaxVat,
net_amount: netAmount
})
const response = await fetch(this.vatUrl + '?' + params.toString())

return await response.json()
}
}
1 change: 0 additions & 1 deletion app/webpack/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import '../javascripts/modules/Modules.ExpensesDataTable.js'
import '../javascripts/modules/Modules.Debounce.js'
import '../javascripts/modules/case_worker/admin/Modules.ManagementInformation.js'
import '../javascripts/modules/case_worker/Allocation.js'
import '../javascripts/modules/case_worker/claims/DeterminationCalculator.js'
import '../javascripts/modules/external_users/claims/FeeFieldsDisplay.js'
import '../javascripts/modules/external_users/claims/DisbursementsCtrl.js'
import '../javascripts/modules/external_users/claims/FeeTypeCtrl.js'
Expand Down
7 changes: 7 additions & 0 deletions app/webpack/packs/govuk-frontend.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import '../stylesheets/govuk-frontend.scss'

import { Determination } from '../javascripts/modules/determination.js'

// fonts & images
require.context('govuk-frontend/govuk/assets', true)

const determinations = document.querySelectorAll('[data-module="govuk-determination"]')
determinations.forEach((determination) => {
new Determination(determination).init()
})

require('govuk-frontend').initAll()
26 changes: 25 additions & 1 deletion docs/javascript_restructure.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,28 @@ class Example {
The primary benefits of refactoring our Javascript is to have a single, consistent style so that future developers can better understand the codebase.
Specifically using the recommended Gov.UK style will further facilitate new developers who have worked on other Gov.UK projects.

This is a *work in progress* so javascript modules may be written in any of the above formats but the ideal is the class design pattern.
This is a *work in progress* so javascript modules may be written in any of the above formats but the ideal is the class design pattern.

### Removal of jQuery

There has also been a long-standing plan to remove the dependency on jQuery as modern versions of Javascript have all (most?) of the features that jQuery provided. There are some [notes here](https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/) to help with migrating jQuery to vanilla Javascript and below are some further pointers.

#### Accessing the data of elements

jQuery provides a way of accessing data from elements as follows;

```javascript
// <table id="determinations" data-scheme="agfs">

table = $('#determinations')
scheme = table.data('scheme')
```

Without jQuery this becomes;

```javascript
// <table id="determinations" data-scheme="agfs">

table = document.getElementById('determinations')
scheme = table.dataset.scheme
```

0 comments on commit f66f596

Please sign in to comment.