UNPKG

ccs-digitalmarketplace-govuk-frontend

Version:

Digital Marketplace GOV.UK Frontend contains the code you need to start building a user interface for Digital Marketplace.

209 lines (164 loc) 5.5 kB
const MAX_NUMBER_OF_ROWS = 10 class AnswerListRowInput { constructor ($row) { this.$input = $row.find('.dm-list__item-input') this.$label = $row.find('.govuk-label') this.$labelCounter = this.$label.find('.dm-list__item-label-counter') this.$prefixText = $row.find('.govuk-input__prefix') } getValue () { return this.$input.val() } clearValue () { this.$input.val('') this.$input.attr('value', '') } updateIndex (newIndex) { const newId = `input-${this.$input.attr('name')}-${newIndex}` this.$label.attr('for', newId) this.$labelCounter.text(newIndex + 1) this.$prefixText.text(`${newIndex + 1}.`) this.$input.attr('id', newId) } } class AnswerListRowRemoveButton { constructor (answerListRow, $row) { this.answerListRow = answerListRow this.$button = $row.find('.dm-list__item-remove') this.$removeButtonCounter = this.$button.find('.dm-list__item-remove-counter') } init () { this.toggleVisibility(true) this.$button.on('click', () => { this.answerListRow.removeRow() }) } toggleVisibility (isShown) { this.$button.toggleClass('govuk-visually-hidden', !isShown) } updateIndex (newIndex) { this.$removeButtonCounter.text(newIndex + 1) } } class AnswerListRow { constructor (answerList, index, $row) { this.$row = $row this.answerList = answerList this.index = index this.answerListRowInput = new AnswerListRowInput($row) this.answerListRowRemoveButton = new AnswerListRowRemoveButton(this, $row) } init () { this.answerListRowRemoveButton.init() } updateIndex (newIndex) { this.index = newIndex this.answerListRowInput.updateIndex(newIndex) this.answerListRowRemoveButton.updateIndex(newIndex) } removeRow () { this.answerList.removeRow(this.index) this.deleteRow() } deleteRow () { this.$row.remove() } toggleRemoveButtonVisibility (isShown) { this.answerListRowRemoveButton.toggleVisibility(isShown) } inputValue () { return this.answerListRowInput.getValue() } } class AnswerListAddButton { constructor (answerList, $button) { this.answerList = answerList this.$button = $button this.$buttonCounter = $button.find('.dm-list__item-add-counter') } init (numberOfRows) { this.$button.on('click', () => { this.answerList.addRow() }) this.updateButtonText(MAX_NUMBER_OF_ROWS - numberOfRows) } updateButtonText (numberRemaining) { this.$buttonCounter.text(numberRemaining) } toggleVisibility (isShown) { this.$button.toggleClass('govuk-visually-hidden', !isShown) } } class AnswerList { constructor (answerList) { this.$answerList = $(answerList) this.$answerListItems = this.$answerList.find('.dm-list__items') this.answerListRows = this.$answerList.find('.dm-list__item').get().map((row, index) => new AnswerListRow(this, index, $(row))) this.answerListAddButton = new AnswerListAddButton(this, this.$answerList.find('.dm-list__item-add')) } init () { const rowValues = this.answerListRows.map((answerListRow) => answerListRow.inputValue()) let indexToDeleteFrom if (rowValues.every((rowValue) => !rowValue)) { indexToDeleteFrom = 2 } else { indexToDeleteFrom = rowValues.indexOf('') } if (indexToDeleteFrom >= 0) { this.answerListRows.slice(indexToDeleteFrom).forEach((answerListRow) => answerListRow.deleteRow()) this.answerListRows.splice(indexToDeleteFrom) } this.answerListAddButton.init(this.answerListRows.length) this.answerListRows.forEach((answerListRow) => answerListRow.init()) this.updateIfMinRows() this.updateAnswerButton() } removeRow (indexToRemove) { this.answerListRows.splice(indexToRemove, 1) this.answerListRows.slice(indexToRemove).forEach((answerListRow, index) => { answerListRow.updateIndex(indexToRemove + index) }) this.updateIfMinRows() this.updateAnswerButton() this.focusOnRow(indexToRemove) } addRow () { const numberOfRows = this.answerListRows.length if (numberOfRows < MAX_NUMBER_OF_ROWS) { const $newRow = this.answerListRows[0].$row.clone() const answerListRow = new AnswerListRow(this, numberOfRows, $newRow) answerListRow.updateIndex(numberOfRows) answerListRow.answerListRowInput.clearValue() this.answerListRows.push(answerListRow) this.$answerListItems.append($newRow) this.answerListRows[numberOfRows].init() this.updateIfMinRows() this.updateAnswerButton() this.focusOnRow(numberOfRows) } } updateIfMinRows () { if (this.answerListRows.length === 1) { this.answerListRows[0].toggleRemoveButtonVisibility(false) } else { this.answerListRows[0].toggleRemoveButtonVisibility(true) } } updateAnswerButton () { if (this.answerListRows.length === MAX_NUMBER_OF_ROWS) { this.answerListAddButton.toggleVisibility(false) } else { this.answerListAddButton.toggleVisibility(true) this.answerListAddButton.updateButtonText(MAX_NUMBER_OF_ROWS - this.answerListRows.length) } } focusOnRow (targetIndexToFocus) { const numberOfRows = this.answerListRows.length let indexToFocus = targetIndexToFocus if (targetIndexToFocus >= numberOfRows) { indexToFocus = numberOfRows - 1 } this.answerListRows[indexToFocus].answerListRowInput.$input.focus() } } export default AnswerList