Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update standard and fix JavaScript lint errors #782

Merged
merged 13 commits into from
Dec 6, 2024
21 changes: 10 additions & 11 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,27 @@ $(document).ready(function () {
})

// Submit form when any change detected
$('.js-auto-submit').on('change', function(){
$(this).closest('form').submit();
});

$('.js-auto-submit').on('change', function () {
$(this).closest('form').submit()
})

if ($('.js-bulk-menu').length){
if ($('.js-bulk-menu').length) {
new MOJFrontend.ButtonMenu({
container: $('.js-bulk-menu .moj-button-menu'),
mq: '(min-width: 200em)',
buttonText: 'Bulk record actions',
buttonClasses: 'govuk-button--secondary moj-button-menu--secondary moj-button-menu__toggle-button--secondary',
_menuClasses: 'moj-button-menu__wrapper--right'
});
})
}

new MOJFrontend.ButtonMenu({
container: $(".moj-button-menu"),
mq: "(min-width: 200em)",
buttonText: "Change attendance",
container: $('.moj-button-menu'),
mq: '(min-width: 200em)',
buttonText: 'Change attendance',
buttonClasses:
"govuk-button--secondary moj-button-menu__toggle-button--secondary"
});
'govuk-button--secondary moj-button-menu__toggle-button--secondary'
})

$(document).ready(function () {
initAutocompletes()
Expand Down
10 changes: 5 additions & 5 deletions app/assets/javascripts/auto-store-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ $('body').on('submit', 'form', function (e) {
// all form data on the server, including checkboxes that are checked, then
// later unchecked

var $checkboxes = $(this).find('input:checkbox')
const $checkboxes = $(this).find('input:checkbox')

var $inputs = []
var names = {}
const $inputs = []
const names = {}

$checkboxes.each(function () {
var $this = $(this)
const $this = $(this)

if (!names[$this.attr('name')]) {
names[$this.attr('name')] = true
var $input = $('<input type="hidden">')
const $input = $('<input type="hidden">')
$input.attr('name', $this.attr('name'))
$input.attr('value', '_unchecked')
$inputs.push($input)
Expand Down
5 changes: 2 additions & 3 deletions app/assets/javascripts/autocomplete-sort.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const clean = s => s.trim().replace(/['’]/g, '').replace(/[.,"/#!$%^&*;:{}=\-_
// Determines how closely a query matches either an option's name/synonyms.
// Returns an integer ranging from 0 (no match) to 100 (exact name match).
const calculateWeight = (rawName, query, rawSynonyms = []) => {

const regexes = clean(query).split(/\s+/).map(word => new RegExp('\\b' + word, 'i'))
const name = clean(rawName)
const synonyms = rawSynonyms.map(s => clean(s))
Expand Down Expand Up @@ -62,10 +61,10 @@ function autocompleteSort (query, options) {
// them above an exact name match.
options.forEach(o => { o.weight = calculateWeight(o.name, query, o.synonyms) * (o.boost || 1) })

let results = options.filter(o => o.weight > 0)
const results = options.filter(o => o.weight > 0)
.sort(byWeightThenAlphabetically)

if (debugAutocomplete){
if (debugAutocomplete) {
console.log(results)
}
return results
Expand Down
138 changes: 65 additions & 73 deletions app/assets/javascripts/init-autocompletes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ const debugAutocomplete = false
// What should get set in the input once a value is selected
const valueForInput = (result) => {
if (!result) return ''
else if (typeof result == 'string'){
else if (typeof result === 'string') {
return result
}
else if (typeof result == 'object'){
} else if (typeof result === 'object') {
return result.name
}
}
Expand All @@ -15,47 +14,44 @@ const valueForInput = (result) => {
const menuResultItem = (result) => {
if (result) {
// If using DefaultValue, result can be a string - bug with autcomplete https://github.com/alphagov/accessible-autocomplete/issues/424
if (typeof result == 'string'){
if (typeof result === 'string') {
return result
}
// What our sort function returns
else if (typeof result == 'object'){
let name = (debugAutocomplete) ? `${result.name} (${result.weight})` : result.name
let output = result.append ? `<span>${name}</span> ${result.append}` : `<span>${name}</span>`
else if (typeof result === 'object') {
const name = (debugAutocomplete) ? `${result.name} (${result.weight})` : result.name
const output = result.append ? `<span>${name}</span> ${result.append}` : `<span>${name}</span>`
return result.hint ? `${output}<span class="autocomplete__option--hint">${result.hint}</span>` : output

}
}
else return ''
} else return ''
}

const onConfirm = function(selected) {

const onConfirm = function (selected) {
// Create a hidden input and use this to submit the value or the name

// Visible input that user interacts with
let autocompleteInput = document.getElementById(this.id)
let autocompleteId = autocompleteInput.id
const autocompleteInput = document.getElementById(this.id)
const autocompleteId = autocompleteInput.id

// Hidden input to store value / submit data
let autocompleteValueId = `${autocompleteId}-value`
const autocompleteValueId = `${autocompleteId}-value`
let autocompleteValueInput = document.getElementById(autocompleteValueId)

// Create hidden input if it doesn’t already exist
if (!autocompleteValueInput){
let hiddenInput = document.createElement('input')
hiddenInput.setAttribute("type", "hidden");
if (!autocompleteValueInput) {
const hiddenInput = document.createElement('input')
hiddenInput.setAttribute('type', 'hidden')

// Copy over attributes from visible input
hiddenInput.setAttribute("id", autocompleteValueId);
hiddenInput.setAttribute("name", `${this.name}`);
hiddenInput.setAttribute('id', autocompleteValueId)
hiddenInput.setAttribute('name', `${this.name}`)
hiddenInput.value = autocompleteInput.value

// Save the string from the input so we can compare it later
hiddenInput.setAttribute("data-text", autocompleteInput.value)
hiddenInput.setAttribute('data-text', autocompleteInput.value)

// Clear the original input's name, so it doesn't get submitted
autocompleteInput.setAttribute("name", '')
autocompleteInput.setAttribute('name', '')

// Append after the visible input
autocompleteInput.parentElement.append(hiddenInput)
Expand All @@ -67,31 +63,30 @@ const onConfirm = function(selected) {
// onConfirm gets called once an item is picked *and* on blur. When called on blur,
// selected is undefined.
// If we have a selected item we co
if (selected){
if (selected) {
autocompleteValueInput.value = selected.value || selected.name
autocompleteValueInput.setAttribute("data-text", selected.name)
autocompleteValueInput.setAttribute('data-text', selected.name)
}
// Probably running on blur
else {
// If the source input is blank, our value should be too
if (autocompleteInput.value == ''){
if (autocompleteInput.value === '') {
autocompleteValueInput.value = ''
autocompleteValueInput.setAttribute("data-text", '')
autocompleteValueInput.setAttribute('data-text', '')
}
// If the value is not blank and doesn’t match the stored data-text, then the user
// must have typed something in the autocomplete without picking an option. Therefore we
// need to store the current typed text.
else if (autocompleteInput.value != autocompleteValueInput.getAttribute('data-text') ){
else if (autocompleteInput.value != autocompleteValueInput.getAttribute('data-text')) {
autocompleteValueInput.value = autocompleteInput.value
autocompleteValueInput.setAttribute('data-text', autocompleteInput.value)
}
}

if (this.hasOnConfirmExtra){
if (this.hasOnConfirmExtra) {
onConfirmExtra(selected)
}

};
}

// Extract data attributes from select options
const enhanceSelectOption = (option) => {
Expand All @@ -106,7 +101,6 @@ const enhanceSelectOption = (option) => {
}

const setupAutocomplete = (component) => {

// Locate the elements
const selectElement = component.querySelector('select')
const inputElement = component.querySelector('input')
Expand All @@ -117,52 +111,51 @@ const setupAutocomplete = (component) => {
const id = element.id

// Get config for autocomplete
const autoselect = element.getAttribute('data-autoselect') || false
const classes = element.getAttribute('data-classes') || false
const describedByIds = element.getAttribute('aria-describedby') || false
const minLength = element.getAttribute('data-min-length') || 2
const placeholder = element.getAttribute('data-placeholder') || false
const showAllValues = element.getAttribute('data-show-all-values') || false
const showNoOptionsFound = element.getAttribute('data-show-no-options-found') || true
const showSuggestions = element.getAttribute('data-show-suggestions') || false
const hasOnConfirmExtra = element.getAttribute('data-on-confirm-extra') || false

// Default value should be set to '' if there's no item or else the autocomplete will display the
const autoselect = element.getAttribute('data-autoselect') || false
const classes = element.getAttribute('data-classes') || false
const describedByIds = element.getAttribute('aria-describedby') || false
const minLength = element.getAttribute('data-min-length') || 2
const placeholder = element.getAttribute('data-placeholder') || false
const showAllValues = element.getAttribute('data-show-all-values') || false
const showNoOptionsFound = element.getAttribute('data-show-no-options-found') || true
const showSuggestions = element.getAttribute('data-show-suggestions') || false
const hasOnConfirmExtra = element.getAttribute('data-on-confirm-extra') || false

// Default value should be set to '' if there's no item or else the autocomplete will display the
// initial value of the select 'please select'
const defaultValue = element.getAttribute('data-value') || ''
const defaultValue = element.getAttribute('data-value') || ''

let values = JSON.parse(element.getAttribute('data-autocomplete-values') || "[]")
let values = JSON.parse(element.getAttribute('data-autocomplete-values') || '[]')

// If the enhanced element has aria-describedBy, grab the description to pass
// to the autocomplete
let describedBy = null
if (describedByIds){

if (describedByIds) {
// Can be an array where the field is in error
let describedByIdsArray = describedByIds.trim().split(' ')
const describedByIdsArray = describedByIds.trim().split(' ')
describedBy = describedByIdsArray.map(describedById => {
let innerText = document.getElementById(describedById).innerText
// Make sure each item ends in a full stop.
if (!innerText.endsWith(".")){
if (!innerText.endsWith('.')) {
innerText = `${innerText}.`
}
}).join(' ')
}

// If enhancing a select and values not provided, fall back to options from select
if (!values.length && elementType == 'select'){
let selectOptions = Array.from(selectElement?.options)
if (!values.length && elementType === 'select') {
const selectOptions = Array.from(selectElement?.options)
// Remove empty or disabled select options
.filter(option => {
if (option.disabled || option.label == "") return false
if (option.disabled || option.label === '') return false
return true
})

// Extract values from data attributes in each option
values = selectOptions.map(option => enhanceSelectOption(option))
}

if (!values || values.length == 0){
if (!values || values.length === 0) {
console.log(`Autocomplete error: no values found for ${element?.id}`)
}

Expand All @@ -171,24 +164,24 @@ const setupAutocomplete = (component) => {
}

const filter = (query, populateResults) => {
let results = autocompleteSort(query, values)
const results = autocompleteSort(query, values)

// If in suggestions mode we don’t want to show a 'suggestions' banner when there are no results
if (showSuggestions){
if (results.length == 0) component.classList.add('app-autocomplete--with-suggestions-no-results')
if (showSuggestions) {
if (results.length === 0) component.classList.add('app-autocomplete--with-suggestions-no-results')
else {
component.classList.remove('app-autocomplete--with-suggestions-no-results')
}
}

populateResults(results)
}

// Alternate strings to use when in suggestions mode
const suggestionNoResults = () => 'No suggestions found. Enter your own answer'
const suggestionStatusNoResults = () => "No suggestions found"
const suggestionStatusNoResults = () => 'No suggestions found'

let autocompleteOptions = {
const autocompleteOptions = {
id,
name: element.name,
templates: {
Expand Down Expand Up @@ -221,30 +214,29 @@ const setupAutocomplete = (component) => {
// }
// else if (inputElement){

const autocompleteContainer = document.getElementById(`${element.id}-autocomplete-container`)
const autocompleteContainer = document.getElementById(`${element.id}-autocomplete-container`)

// Because of the govuk macros, the container for the autocomplete is initially
// placed _after_ the input. We now move the container within the input container.
const inputFormGroup = autocompleteContainer.previousElementSibling
if (inputFormGroup.contains(element)) {
inputFormGroup.appendChild(autocompleteContainer)
}
// Because of the govuk macros, the container for the autocomplete is initially
// placed _after_ the input. We now move the container within the input container.
const inputFormGroup = autocompleteContainer.previousElementSibling
if (inputFormGroup.contains(element)) {
inputFormGroup.appendChild(autocompleteContainer)
}

accessibleAutocomplete({
element: autocompleteContainer,
...autocompleteOptions
})
accessibleAutocomplete({
element: autocompleteContainer,
...autocompleteOptions
})
// }

// Remove the original input
element.remove()

// If there should be a default value, set this manually after the autocomplete input is
// If there should be a default value, set this manually after the autocomplete input is
// created. This avoids the issue documented at https://github.com/alphagov/accessible-autocomplete/issues/424
if (defaultValue){
if (defaultValue) {
document.getElementById(id).value = defaultValue
}

}

const initAutocompletes = () => {
Expand Down
Loading
Loading