diff --git a/src/js/account/setupListeners.js b/src/js/account/setupListeners.js index 20ccb11..c934317 100644 --- a/src/js/account/setupListeners.js +++ b/src/js/account/setupListeners.js @@ -3,7 +3,7 @@ import { setCookie } from "../StackOverflow/cookie"; import { changeDictionary, createNewDictionary } from "./dictionaryManagement"; import { addMessage } from "../utilities"; import { renderForgotPasswordForm } from "./passwordReset"; -import { setupMaximizeButtons } from "../setupListeners"; +import { setupMaximizeButtons } from "../setupListeners/buttons"; export function setupLoginModal(modal) { const closeElements = modal.querySelectorAll('.modal-background, .close-button'); diff --git a/src/js/render/details.js b/src/js/render/details.js index 77a0fa7..2aa05f0 100644 --- a/src/js/render/details.js +++ b/src/js/render/details.js @@ -2,9 +2,7 @@ import md from 'marked'; import { removeTags, slugify } from '../../helpers'; import { getWordsStats, hasToken } from '../utilities'; import { showSection } from '../displayToggles'; -import { - setupSearchFilters, -} from '../setupListeners'; +import { setupSearchFilters } from '../setupListeners/search'; import { parseReferences } from '../wordManagement'; import { getPublicLink } from '../account/utilities'; diff --git a/src/js/render/modals.js b/src/js/render/modals.js index ea96bda..5c5e472 100644 --- a/src/js/render/modals.js +++ b/src/js/render/modals.js @@ -1,9 +1,9 @@ +import { setupIPAFields } from '../setupListeners'; import { setupMaximizeModal, setupInfoModal, setupIPATable, - setupIPAFields -} from '../setupListeners'; +} from '../setupListeners/modals'; import ipaTableFile from '../KeyboardFire/phondue/ipa-table.html'; export function renderIPAHelp() { diff --git a/src/js/render/words.js b/src/js/render/words.js index bb37206..b611d3a 100644 --- a/src/js/render/words.js +++ b/src/js/render/words.js @@ -7,7 +7,7 @@ import { setupPagination, setupWordOptionSelections, setupWordEditFormButtons, -} from '../setupListeners'; +} from '../setupListeners/words'; import { getPaginationData } from '../pagination'; import { getOpenEditForms, translateOrthography, parseReferences } from '../wordManagement'; import { renderAd } from '../ads'; diff --git a/src/js/setupListeners.js b/src/js/setupListeners.js deleted file mode 100644 index 8c0f6a8..0000000 --- a/src/js/setupListeners.js +++ /dev/null @@ -1,392 +0,0 @@ -import {showSection, hideDetailsPanel} from './displayToggles'; -import { renderWords, renderEditForm } from './render/words'; -import { renderMaximizedTextbox, renderInfoModal, renderIPATable, renderIPAHelp } from './render/modals'; -import { confirmEditWord, cancelEditWord, confirmDeleteWord, submitWordForm } from './wordManagement'; -import { openEditModal, saveEditModal, saveAndCloseEditModal, exportDictionary, exportWords, importDictionary, importWords, confirmDeleteDictionary } from './dictionaryManagement'; -import { goToNextPage, goToPreviousPage, goToPage } from './pagination'; -import { insertAtCursor, getInputSelection, setSelectionRange } from './StackOverflow/inputCursorManagement'; -import { usePhondueDigraphs } from './KeyboardFire/phondue/ipaField'; -import { openSettingsModal, saveSettingsModal, saveAndCloseSettingsModal } from './settings'; -import { enableHotKeys } from './hotkeys'; -import { showSearchModal, clearSearchText, checkAllPartsOfSpeechFilters, uncheckAllPartsOfSpeechFilters } from './search'; -import helpFile from '../markdown/help.md'; -import termsFile from '../markdown/terms.md'; -import privacyFile from '../markdown/privacy.md'; -import { dismiss, isDismissed } from './announcements'; -import { fadeOutElement } from './utilities'; - -export default function setupListeners() { - setupAnnouncements(); - setupDetailsTabs(); - setupHeaderButtons(); - setupWordForm(); - setupMobileWordFormButton(); - setupInfoButtons(); - if (window.settings.useHotkeys) { - enableHotKeys(); - } -} - -export function setupHeaderButtons() { - setupSearchBar(); - setupSettingsModal(); - - document.getElementById('loginCreateAccountButton').addEventListener('click', () => { - import('./account/index.js').then(account => { - account.showLoginForm(); - }); - }); -} - -function setupAnnouncements() { - const announcements = document.querySelectorAll('.announcement'); - Array.from(announcements).forEach(announcement => { - if (announcement.id && isDismissed(announcement.id)) { - fadeOutElement(announcement); - } else { - announcement.querySelector('.close-button').addEventListener('click', () => dismiss(announcement)); - } - }); -} - -function setupDetailsTabs() { - const tabs = document.querySelectorAll('#detailsSection nav li'); - tabs.forEach(tab => { - tab.addEventListener('click', () => { - const section = tab.innerText.toLowerCase(); - if (section === 'edit') { - openEditModal(); - // import('../test.js').then(function (test) { - // // Render page - // test.aaa(); - // }); - } else { - const isActive = tab.classList.contains('active'); - tabs.forEach(t => t.classList.remove('active')); - if (isActive) { - hideDetailsPanel(); - } else { - tab.classList.add('active'); - showSection(section); - } - } - }); - }); - setupEditFormTabs(); - setupEditFormInteractions(); - setupEditFormButtons(); -} - -function setupEditFormTabs() { - const tabs = document.querySelectorAll('#editModal nav li'); - tabs.forEach(tab => { - tab.addEventListener('click', () => { - tabs.forEach(t => { - t.classList.remove('active'); - document.getElementById('edit' + t.innerText + 'Tab').style.display = 'none'; - }); - tab.classList.add('active'); - document.getElementById('edit' + tab.innerText + 'Tab').style.display = ''; - }); - }); -} - -function setupEditFormInteractions() { - const preventDuplicatesBox = document.getElementById('editPreventDuplicates'); - preventDuplicatesBox.addEventListener('change', () => { - const caseSensitiveBox = document.getElementById('editCaseSensitive'); - if (preventDuplicatesBox.checked) { - caseSensitiveBox.disabled = false; - } else { - caseSensitiveBox.disabled = true; - caseSensitiveBox.checked = false; - } - }); -} - -function setupEditFormButtons() { - document.getElementById('editSave').addEventListener('click', saveEditModal); - document.getElementById('editSaveAndClose').addEventListener('click', saveAndCloseEditModal); - document.getElementById('importDictionaryFile').addEventListener('change', importDictionary); - document.getElementById('importWordsCSV').addEventListener('change', importWords); - document.getElementById('exportDictionaryButton').addEventListener('click', exportDictionary); - document.getElementById('exportWordsButton').addEventListener('click', exportWords); - document.getElementById('deleteDictionaryButton').addEventListener('click', confirmDeleteDictionary); - - setupMaximizeButtons(); -} - -function setupSearchBar() { - const searchBox = document.getElementById('searchBox'), - clearSearchButton = document.getElementById('clearSearchButton'), - openSearchModal = document.getElementById('openSearchModal'), - searchIgnoreDiacritics = document.getElementById('searchIgnoreDiacritics'), - searchExactWords = document.getElementById('searchExactWords'), - searchIncludeDetails = document.getElementById('searchIncludeDetails'); - searchBox.addEventListener('change', () => { - renderWords(); - }); - searchBox.addEventListener('input', event => { - openSearchModal.value = event.target.value; - }); - clearSearchButton.addEventListener('click', clearSearchText); - openSearchModal.addEventListener('click', showSearchModal); - - const toggleDetailsCheck = function() { - if (searchExactWords.checked) { - searchIncludeDetails.checked = false; - searchIncludeDetails.disabled = true; - } else { - searchIncludeDetails.disabled = false; - searchIncludeDetails.checked = true; - } - } - - searchIgnoreDiacritics.addEventListener('change', () => { - if (searchIgnoreDiacritics.checked) { - searchExactWords.checked = false; - searchExactWords.disabled = true; - } else { - searchExactWords.disabled = false; - } - toggleDetailsCheck(); - }); - - searchExactWords.addEventListener('change', () => toggleDetailsCheck()); -} - -export function setupSearchFilters() { - const searchFilters = document.querySelectorAll('#searchOptions input[type="checkbox"]'), - searchBox = document.getElementById('searchBox'); - Array.from(searchFilters).concat([searchBox]).forEach(filter => { - filter.removeEventListener('change', renderWords); - filter.addEventListener('change', renderWords); - }); - document.getElementById('checkAllFilters').removeEventListener('click', checkAllPartsOfSpeechFilters); - document.getElementById('checkAllFilters').addEventListener('click', checkAllPartsOfSpeechFilters); - document.getElementById('uncheckAllFilters').removeEventListener('click', uncheckAllPartsOfSpeechFilters); - document.getElementById('uncheckAllFilters').addEventListener('click', uncheckAllPartsOfSpeechFilters); -} - -function setupWordForm() { - const wordForm = document.getElementById('wordForm'), - addWordButton = document.getElementById('addWordButton'); - wordForm.addEventListener('submit', event => { - // Allow semantic form and prevent it from getting submitted - event.preventDefault(); - return false; - }); - addWordButton.addEventListener('click', submitWordForm); - - setupIPAFields(); - setupMaximizeButtons(); -} - -export function setupWordOptionButtons() { - const wordOptionButtons = document.getElementsByClassName('word-option-button'); - const showWordOptions = function() { - this.parentElement.querySelector('.word-option-list').style.display = ''; - } - const hideWordOptions = function(e) { - if (!e.target.classList.contains('word-option-button')) { - const allWordOptions = document.querySelectorAll('.word-option-list'); - Array.from(allWordOptions).forEach(wordOptionList => { - wordOptionList.style.display = 'none'; - }); - } - } - - Array.from(wordOptionButtons).forEach(button => { - button.removeEventListener('click', showWordOptions); - button.addEventListener('click', showWordOptions); - }); - - document.removeEventListener('click', hideWordOptions); - document.addEventListener('click', hideWordOptions); - -} - -export function setupWordOptionSelections() { - const wordOptions = document.getElementsByClassName('word-option'); - Array.from(wordOptions).forEach(option => { - switch (option.innerText) { - case 'Edit': { - option.removeEventListener('click', renderEditForm); - option.addEventListener('click', renderEditForm); - break; - } - case 'Delete': { - option.removeEventListener('click', confirmDeleteWord); - option.addEventListener('click', confirmDeleteWord); - break; - } - } - }); -} - -export function setupSettingsModal() { - document.getElementById('settingsButton').addEventListener('click', openSettingsModal); - document.getElementById('settingsSave').addEventListener('click', saveSettingsModal); - document.getElementById('settingsSaveAndClose').addEventListener('click', saveAndCloseSettingsModal); -} - -export function setupWordEditFormButtons() { - const saveChangesButtons = document.getElementsByClassName('edit-save-changes'), - cancelChangesButtons = document.getElementsByClassName('edit-cancel'); - Array.from(saveChangesButtons).forEach(button => { - button.removeEventListener('click', confirmEditWord); - button.addEventListener('click', confirmEditWord); - }); - Array.from(cancelChangesButtons).forEach(button => { - button.removeEventListener('click', cancelEditWord); - button.addEventListener('click', cancelEditWord); - }); - - setupIPAFields(); - setupMaximizeButtons(); -} - -export function setupMobileWordFormButton() { - const mobileButton = document.getElementById('mobileWordFormShow'), - wordForm = document.getElementById('wordForm'); - - mobileButton.addEventListener('click', () => { - if (mobileButton.innerText === '+') { - wordForm.style.display = 'block'; - mobileButton.innerHTML = '×︎'; - } else { - wordForm.style.display = ''; - mobileButton.innerHTML = '+'; - } - }); -} - -export function setupPagination() { - const nextButtons = document.getElementsByClassName('next-button'), - prevButtons = document.getElementsByClassName('prev-button'), - pageSelectors = document.getElementsByClassName('page-selector'); - - Array.from(nextButtons).forEach(nextButton => { - nextButton.removeEventListener('click', goToNextPage); - nextButton.addEventListener('click', goToNextPage); - }); - Array.from(prevButtons).forEach(prevButton => { - prevButton.removeEventListener('click', goToPreviousPage); - prevButton.addEventListener('click', goToPreviousPage); - }); - - Array.from(pageSelectors).forEach(pageSelector => { - pageSelector.removeEventListener('change', goToPage); - pageSelector.addEventListener('change', goToPage); - }); -} - -export function setupIPAFields() { - if (window.settings.useIPAPronunciationField) { - const ipaFields = document.getElementsByClassName('ipa-field'); - Array.from(ipaFields).forEach(field => { - field.removeEventListener('keypress', usePhondueDigraphs); - field.addEventListener('keypress', usePhondueDigraphs); - }); - } - - setupIPAButtons(); -} - -export function setupIPAButtons() { - const ipaTableButtons = document.getElementsByClassName('ipa-table-button'), - ipaFieldHelpButtons = document.getElementsByClassName('ipa-field-help-button'); - - Array.from(ipaTableButtons).forEach(button => { - button.removeEventListener('click', renderIPATable); - button.addEventListener('click', renderIPATable); - }); - - Array.from(ipaFieldHelpButtons).forEach(button => { - button.removeEventListener('click', renderIPAHelp); - button.addEventListener('click', renderIPAHelp); - }); -} - -export function setupIPATable(modal, textBox) { - const closeElements = modal.querySelectorAll('.modal-background, .close-button, .done-button'), - headerTextBox = modal.querySelector('header input'), - ipaButtons = modal.querySelectorAll('.td-btn button'); - Array.from(closeElements).forEach(close => { - close.addEventListener('click', () => { - textBox.focus(); - const endOfTextbox = textBox.value.length; - setSelectionRange(textBox, endOfTextbox, endOfTextbox); - modal.parentElement.removeChild(modal); - }); - }); - - headerTextBox.addEventListener('change', () => { - textBox.value = headerTextBox.value; - }); - - Array.from(ipaButtons).forEach(button => { - button.addEventListener('click', () => { - insertAtCursor(headerTextBox, button.innerText); - textBox.value = headerTextBox.value; - }); - }); - - setTimeout(() => { - headerTextBox.focus(); - const endOfTextbox = headerTextBox.value.length; - setSelectionRange(headerTextBox, endOfTextbox, endOfTextbox); - }, 1); -} - -export function setupMaximizeButtons() { - const maximizeButtons = document.getElementsByClassName('maximize-button'); - Array.from(maximizeButtons).forEach(button => { - button.removeEventListener('click', renderMaximizedTextbox); - button.addEventListener('click', renderMaximizedTextbox); - }); -} - -export function setupMaximizeModal(modal, textBox) { - const closeElements = modal.querySelectorAll('.modal-background, .close-button, .done-button'), - maximizedTextBox = modal.querySelector('textarea'); - Array.from(closeElements).forEach(close => { - close.addEventListener('click', () => { - const selection = getInputSelection(maximizedTextBox); - textBox.focus(); - setSelectionRange(textBox, selection.start, selection.end); - modal.parentElement.removeChild(modal); - }); - }); - - maximizedTextBox.addEventListener('change', () => { - textBox.value = maximizedTextBox.value; - }) - - setTimeout(() => { - const selection = getInputSelection(textBox); - maximizedTextBox.focus(); - setSelectionRange(maximizedTextBox, selection.start, selection.end); - }, 1); -} - -export function setupInfoButtons() { - document.getElementById('helpInfoButton').addEventListener('click', () => { - renderInfoModal(helpFile); - }); - document.getElementById('termsInfoButton').addEventListener('click', () => { - renderInfoModal(termsFile); - }); - document.getElementById('privacyInfoButton').addEventListener('click', () => { - renderInfoModal(privacyFile); - }); -} - -export function setupInfoModal(modal) { - const closeElements = modal.querySelectorAll('.modal-background, .close-button'); - Array.from(closeElements).forEach(close => { - close.addEventListener('click', () => { - modal.parentElement.removeChild(modal); - }); - }); -} diff --git a/src/js/setupListeners/buttons.js b/src/js/setupListeners/buttons.js new file mode 100644 index 0000000..7d2acaf --- /dev/null +++ b/src/js/setupListeners/buttons.js @@ -0,0 +1,52 @@ +import { renderMaximizedTextbox, renderInfoModal, renderIPATable, renderIPAHelp } from '../render/modals'; +import helpFile from '../../markdown/help.md'; +import termsFile from '../../markdown/terms.md'; +import privacyFile from '../../markdown/privacy.md'; +import { setupSearchBar } from './search'; +import { setupSettingsModal } from './modals'; + +export function setupHeaderButtons() { + setupSearchBar(); + setupSettingsModal(); + + document.getElementById('loginCreateAccountButton').addEventListener('click', () => { + import('../account/index.js').then(account => { + account.showLoginForm(); + }); + }); +} + +export function setupIPAButtons() { + const ipaTableButtons = document.getElementsByClassName('ipa-table-button'), + ipaFieldHelpButtons = document.getElementsByClassName('ipa-field-help-button'); + + Array.from(ipaTableButtons).forEach(button => { + button.removeEventListener('click', renderIPATable); + button.addEventListener('click', renderIPATable); + }); + + Array.from(ipaFieldHelpButtons).forEach(button => { + button.removeEventListener('click', renderIPAHelp); + button.addEventListener('click', renderIPAHelp); + }); +} + +export function setupMaximizeButtons() { + const maximizeButtons = document.getElementsByClassName('maximize-button'); + Array.from(maximizeButtons).forEach(button => { + button.removeEventListener('click', renderMaximizedTextbox); + button.addEventListener('click', renderMaximizedTextbox); + }); +} + +export function setupInfoButtons() { + document.getElementById('helpInfoButton').addEventListener('click', () => { + renderInfoModal(helpFile); + }); + document.getElementById('termsInfoButton').addEventListener('click', () => { + renderInfoModal(termsFile); + }); + document.getElementById('privacyInfoButton').addEventListener('click', () => { + renderInfoModal(privacyFile); + }); +} \ No newline at end of file diff --git a/src/js/setupListeners/details.js b/src/js/setupListeners/details.js new file mode 100644 index 0000000..2d8626c --- /dev/null +++ b/src/js/setupListeners/details.js @@ -0,0 +1,66 @@ +import { showSection, hideDetailsPanel } from '../displayToggles'; +import { openEditModal, saveEditModal, saveAndCloseEditModal, exportDictionary, exportWords, importDictionary, importWords, confirmDeleteDictionary } from '../dictionaryManagement'; +import { setupMaximizeButtons } from './buttons'; + +export function setupDetailsTabs() { + const tabs = document.querySelectorAll('#detailsSection nav li'); + tabs.forEach(tab => { + tab.addEventListener('click', () => { + const section = tab.innerText.toLowerCase(); + if (section === 'edit') { + openEditModal(); + } else { + const isActive = tab.classList.contains('active'); + tabs.forEach(t => t.classList.remove('active')); + if (isActive) { + hideDetailsPanel(); + } else { + tab.classList.add('active'); + showSection(section); + } + } + }); + }); + setupEditFormTabs(); + setupEditFormInteractions(); + setupEditFormButtons(); +} + +function setupEditFormTabs() { + const tabs = document.querySelectorAll('#editModal nav li'); + tabs.forEach(tab => { + tab.addEventListener('click', () => { + tabs.forEach(t => { + t.classList.remove('active'); + document.getElementById('edit' + t.innerText + 'Tab').style.display = 'none'; + }); + tab.classList.add('active'); + document.getElementById('edit' + tab.innerText + 'Tab').style.display = ''; + }); + }); +} + +function setupEditFormInteractions() { + const preventDuplicatesBox = document.getElementById('editPreventDuplicates'); + preventDuplicatesBox.addEventListener('change', () => { + const caseSensitiveBox = document.getElementById('editCaseSensitive'); + if (preventDuplicatesBox.checked) { + caseSensitiveBox.disabled = false; + } else { + caseSensitiveBox.disabled = true; + caseSensitiveBox.checked = false; + } + }); +} + +function setupEditFormButtons() { + document.getElementById('editSave').addEventListener('click', saveEditModal); + document.getElementById('editSaveAndClose').addEventListener('click', saveAndCloseEditModal); + document.getElementById('importDictionaryFile').addEventListener('change', importDictionary); + document.getElementById('importWordsCSV').addEventListener('change', importWords); + document.getElementById('exportDictionaryButton').addEventListener('click', exportDictionary); + document.getElementById('exportWordsButton').addEventListener('click', exportWords); + document.getElementById('deleteDictionaryButton').addEventListener('click', confirmDeleteDictionary); + + setupMaximizeButtons(); +} \ No newline at end of file diff --git a/src/js/setupListeners/index.js b/src/js/setupListeners/index.js new file mode 100644 index 0000000..d663cc7 --- /dev/null +++ b/src/js/setupListeners/index.js @@ -0,0 +1,42 @@ +import { usePhondueDigraphs } from '../KeyboardFire/phondue/ipaField'; +import { enableHotKeys } from '../hotkeys'; +import { dismiss, isDismissed } from '../announcements'; +import { fadeOutElement } from '../utilities'; +import { setupDetailsTabs } from './details'; +import { setupWordForm, setupMobileWordFormButton } from './words'; +import { setupIPAButtons, setupHeaderButtons, setupInfoButtons } from './buttons'; + +export default function setupListeners() { + setupAnnouncements(); + setupDetailsTabs(); + setupHeaderButtons(); + setupWordForm(); + setupMobileWordFormButton(); + setupInfoButtons(); + if (window.settings.useHotkeys) { + enableHotKeys(); + } +} + +function setupAnnouncements() { + const announcements = document.querySelectorAll('.announcement'); + Array.from(announcements).forEach(announcement => { + if (announcement.id && isDismissed(announcement.id)) { + fadeOutElement(announcement); + } else { + announcement.querySelector('.close-button').addEventListener('click', () => dismiss(announcement)); + } + }); +} + +export function setupIPAFields() { + if (window.settings.useIPAPronunciationField) { + const ipaFields = document.getElementsByClassName('ipa-field'); + Array.from(ipaFields).forEach(field => { + field.removeEventListener('keypress', usePhondueDigraphs); + field.addEventListener('keypress', usePhondueDigraphs); + }); + } + + setupIPAButtons(); +} diff --git a/src/js/setupListeners/modals.js b/src/js/setupListeners/modals.js new file mode 100644 index 0000000..e03aa2a --- /dev/null +++ b/src/js/setupListeners/modals.js @@ -0,0 +1,71 @@ +import { insertAtCursor, getInputSelection, setSelectionRange } from '../StackOverflow/inputCursorManagement'; +import { openSettingsModal, saveSettingsModal, saveAndCloseSettingsModal } from '../settings'; + +export function setupSettingsModal() { + document.getElementById('settingsButton').addEventListener('click', openSettingsModal); + document.getElementById('settingsSave').addEventListener('click', saveSettingsModal); + document.getElementById('settingsSaveAndClose').addEventListener('click', saveAndCloseSettingsModal); +} + +export function setupIPATable(modal, textBox) { + const closeElements = modal.querySelectorAll('.modal-background, .close-button, .done-button'), + headerTextBox = modal.querySelector('header input'), + ipaButtons = modal.querySelectorAll('.td-btn button'); + Array.from(closeElements).forEach(close => { + close.addEventListener('click', () => { + textBox.focus(); + const endOfTextbox = textBox.value.length; + setSelectionRange(textBox, endOfTextbox, endOfTextbox); + modal.parentElement.removeChild(modal); + }); + }); + + headerTextBox.addEventListener('change', () => { + textBox.value = headerTextBox.value; + }); + + Array.from(ipaButtons).forEach(button => { + button.addEventListener('click', () => { + insertAtCursor(headerTextBox, button.innerText); + textBox.value = headerTextBox.value; + }); + }); + + setTimeout(() => { + headerTextBox.focus(); + const endOfTextbox = headerTextBox.value.length; + setSelectionRange(headerTextBox, endOfTextbox, endOfTextbox); + }, 1); +} + +export function setupMaximizeModal(modal, textBox) { + const closeElements = modal.querySelectorAll('.modal-background, .close-button, .done-button'), + maximizedTextBox = modal.querySelector('textarea'); + Array.from(closeElements).forEach(close => { + close.addEventListener('click', () => { + const selection = getInputSelection(maximizedTextBox); + textBox.focus(); + setSelectionRange(textBox, selection.start, selection.end); + modal.parentElement.removeChild(modal); + }); + }); + + maximizedTextBox.addEventListener('change', () => { + textBox.value = maximizedTextBox.value; + }) + + setTimeout(() => { + const selection = getInputSelection(textBox); + maximizedTextBox.focus(); + setSelectionRange(maximizedTextBox, selection.start, selection.end); + }, 1); +} + +export function setupInfoModal(modal) { + const closeElements = modal.querySelectorAll('.modal-background, .close-button'); + Array.from(closeElements).forEach(close => { + close.addEventListener('click', () => { + modal.parentElement.removeChild(modal); + }); + }); +} \ No newline at end of file diff --git a/src/js/setupListeners/search.js b/src/js/setupListeners/search.js new file mode 100644 index 0000000..6cfd43f --- /dev/null +++ b/src/js/setupListeners/search.js @@ -0,0 +1,54 @@ +import { renderWords } from '../render/words'; +import { showSearchModal, clearSearchText, checkAllPartsOfSpeechFilters, uncheckAllPartsOfSpeechFilters } from '../search'; + +export function setupSearchBar() { + const searchBox = document.getElementById('searchBox'), + clearSearchButton = document.getElementById('clearSearchButton'), + openSearchModal = document.getElementById('openSearchModal'), + searchIgnoreDiacritics = document.getElementById('searchIgnoreDiacritics'), + searchExactWords = document.getElementById('searchExactWords'), + searchIncludeDetails = document.getElementById('searchIncludeDetails'); + searchBox.addEventListener('change', () => { + renderWords(); + }); + searchBox.addEventListener('input', event => { + openSearchModal.value = event.target.value; + }); + clearSearchButton.addEventListener('click', clearSearchText); + openSearchModal.addEventListener('click', showSearchModal); + + const toggleDetailsCheck = function() { + if (searchExactWords.checked) { + searchIncludeDetails.checked = false; + searchIncludeDetails.disabled = true; + } else { + searchIncludeDetails.disabled = false; + searchIncludeDetails.checked = true; + } + } + + searchIgnoreDiacritics.addEventListener('change', () => { + if (searchIgnoreDiacritics.checked) { + searchExactWords.checked = false; + searchExactWords.disabled = true; + } else { + searchExactWords.disabled = false; + } + toggleDetailsCheck(); + }); + + searchExactWords.addEventListener('change', () => toggleDetailsCheck()); +} + +export function setupSearchFilters() { + const searchFilters = document.querySelectorAll('#searchOptions input[type="checkbox"]'), + searchBox = document.getElementById('searchBox'); + Array.from(searchFilters).concat([searchBox]).forEach(filter => { + filter.removeEventListener('change', renderWords); + filter.addEventListener('change', renderWords); + }); + document.getElementById('checkAllFilters').removeEventListener('click', checkAllPartsOfSpeechFilters); + document.getElementById('checkAllFilters').addEventListener('click', checkAllPartsOfSpeechFilters); + document.getElementById('uncheckAllFilters').removeEventListener('click', uncheckAllPartsOfSpeechFilters); + document.getElementById('uncheckAllFilters').addEventListener('click', uncheckAllPartsOfSpeechFilters); +} \ No newline at end of file diff --git a/src/js/setupListeners/words.js b/src/js/setupListeners/words.js new file mode 100644 index 0000000..3ddee00 --- /dev/null +++ b/src/js/setupListeners/words.js @@ -0,0 +1,112 @@ +import { renderEditForm } from '../render/words'; +import { confirmEditWord, cancelEditWord, confirmDeleteWord, submitWordForm } from '../wordManagement'; +import { goToNextPage, goToPreviousPage, goToPage } from '../pagination'; +import { setupMaximizeButtons } from './buttons'; +import { setupIPAFields } from '.'; + +export function setupWordForm() { + const wordForm = document.getElementById('wordForm'), + addWordButton = document.getElementById('addWordButton'); + wordForm.addEventListener('submit', event => { + // Allow semantic form and prevent it from getting submitted + event.preventDefault(); + return false; + }); + addWordButton.addEventListener('click', submitWordForm); + + setupIPAFields(); + setupMaximizeButtons(); +} + +export function setupWordOptionButtons() { + const wordOptionButtons = document.getElementsByClassName('word-option-button'); + const showWordOptions = function() { + this.parentElement.querySelector('.word-option-list').style.display = ''; + } + const hideWordOptions = function(e) { + if (!e.target.classList.contains('word-option-button')) { + const allWordOptions = document.querySelectorAll('.word-option-list'); + Array.from(allWordOptions).forEach(wordOptionList => { + wordOptionList.style.display = 'none'; + }); + } + } + + Array.from(wordOptionButtons).forEach(button => { + button.removeEventListener('click', showWordOptions); + button.addEventListener('click', showWordOptions); + }); + + document.removeEventListener('click', hideWordOptions); + document.addEventListener('click', hideWordOptions); + +} + +export function setupWordOptionSelections() { + const wordOptions = document.getElementsByClassName('word-option'); + Array.from(wordOptions).forEach(option => { + switch (option.innerText) { + case 'Edit': { + option.removeEventListener('click', renderEditForm); + option.addEventListener('click', renderEditForm); + break; + } + case 'Delete': { + option.removeEventListener('click', confirmDeleteWord); + option.addEventListener('click', confirmDeleteWord); + break; + } + } + }); +} + +export function setupWordEditFormButtons() { + const saveChangesButtons = document.getElementsByClassName('edit-save-changes'), + cancelChangesButtons = document.getElementsByClassName('edit-cancel'); + Array.from(saveChangesButtons).forEach(button => { + button.removeEventListener('click', confirmEditWord); + button.addEventListener('click', confirmEditWord); + }); + Array.from(cancelChangesButtons).forEach(button => { + button.removeEventListener('click', cancelEditWord); + button.addEventListener('click', cancelEditWord); + }); + + setupIPAFields(); + setupMaximizeButtons(); +} + +export function setupMobileWordFormButton() { + const mobileButton = document.getElementById('mobileWordFormShow'), + wordForm = document.getElementById('wordForm'); + + mobileButton.addEventListener('click', () => { + if (mobileButton.innerText === '+') { + wordForm.style.display = 'block'; + mobileButton.innerHTML = '×︎'; + } else { + wordForm.style.display = ''; + mobileButton.innerHTML = '+'; + } + }); +} + +export function setupPagination() { + const nextButtons = document.getElementsByClassName('next-button'), + prevButtons = document.getElementsByClassName('prev-button'), + pageSelectors = document.getElementsByClassName('page-selector'); + + Array.from(nextButtons).forEach(nextButton => { + nextButton.removeEventListener('click', goToNextPage); + nextButton.addEventListener('click', goToNextPage); + }); + Array.from(prevButtons).forEach(prevButton => { + prevButton.removeEventListener('click', goToPreviousPage); + prevButton.addEventListener('click', goToPreviousPage); + }); + + Array.from(pageSelectors).forEach(pageSelector => { + pageSelector.removeEventListener('change', goToPage); + pageSelector.addEventListener('change', goToPage); + }); +} \ No newline at end of file diff --git a/src/js/view/render.js b/src/js/view/render.js index 6421f0a..cd83db8 100644 --- a/src/js/view/render.js +++ b/src/js/view/render.js @@ -3,9 +3,10 @@ import { removeTags, slugify } from '../../helpers'; import { getWordsStats, getHomonymnNumber } from './utilities'; import { getMatchingSearchWords, highlightSearchTerm, getSearchFilters, getSearchTerm } from './search'; import { showSection } from './displayToggles'; -import { setupSearchFilters, setupInfoModal } from './setupListeners'; import { renderAd } from '../ads'; import { sortWords } from './wordManagement'; +import { setupInfoModal } from '../setupListeners/modals'; +import { setupSearchFilters } from '../setupListeners/search'; export function renderAll() { renderTheme();