diff --git a/index.html b/index.html index d29b96b..c5bb4b3 100644 --- a/index.html +++ b/index.html @@ -89,21 +89,22 @@ +
+
-

Word

- Pronunciation - Part of Speech +

Loading Words

+ +
-
Definition
-
-

Markdown details

-
+
Please Wait...
+ +
diff --git a/src/constants.js b/src/constants.js index f352e20..d005963 100644 --- a/src/constants.js +++ b/src/constants.js @@ -48,4 +48,6 @@ export const DEFAULT_DICTIONARY = { }, lastUpdated: null, createdOn: 0, -}; \ No newline at end of file +}; + +export const DEFAULT_PAGE_SIZE = 50; \ No newline at end of file diff --git a/src/index.js b/src/index.js index 3b02763..75e118f 100644 --- a/src/index.js +++ b/src/index.js @@ -4,12 +4,15 @@ import { DEFAULT_DICTIONARY } from './constants'; import setupListeners from './js/setupListeners'; import { renderAll } from './js/render'; import { cloneObject } from './helpers'; +import { generateRandomWords } from './js/utilities'; function initialize() { console.log('initializing'); window.currentDictionary = cloneObject(DEFAULT_DICTIONARY); + generateRandomWords(100); setupListeners(); renderAll(); + console.log('Rendered!'); } window.onload = (function (oldLoad) { diff --git a/src/js/pagination.js b/src/js/pagination.js new file mode 100644 index 0000000..0dac4ef --- /dev/null +++ b/src/js/pagination.js @@ -0,0 +1,24 @@ +import { renderWords } from "./render"; + +export function goToPage(page) { + if (typeof page.target !== 'undefined') { + page = page.target.value; + } + window.currentPage = parseFloat(page); + + Array.from(document.getElementsByClassName('pagination')).forEach(pagination => { + console.log('setting loader'); + pagination.innerHTML = `Loading Page ${window.currentPage + 1}...`; + }); + + setTimeout(renderWords, 1); + // renderWords(); +} + +export function goToNextPage() { + goToPage((window.hasOwnProperty('currentPage') ? window.currentPage : 0) + 1); +} + +export function goToPreviousPage() { + goToPage((window.hasOwnProperty('currentPage') ? window.currentPage : 1) - 1); +} diff --git a/src/js/render.js b/src/js/render.js index 6f1ebc9..fddddeb 100644 --- a/src/js/render.js +++ b/src/js/render.js @@ -3,7 +3,8 @@ import { removeTags, slugify } from '../helpers'; import { getWordsStats, wordExists } from './utilities'; import { getMatchingSearchWords, highlightSearchTerm, getSearchFilters, getSearchTerm } from './search'; import { showSection } from './displayToggles'; -import { setupSearchFilters, setupWordOptionButtons } from './setupListeners'; +import { setupSearchFilters, setupWordOptionButtons, setupPagination } from './setupListeners'; +import { DEFAULT_PAGE_SIZE } from '../constants'; export function renderAll() { renderDictionaryDetails(); @@ -106,7 +107,13 @@ export function renderPartsOfSpeech() { export function renderWords() { const words = getMatchingSearchWords(); let wordsHTML = ''; - words.forEach(originalWord => { + + const pageSize = window.localStorage.getItem('pageSize') ? parseInt(window.localStorage.getItem('pageSize')) : DEFAULT_PAGE_SIZE; + const currentPage = window.hasOwnProperty('currentPage') ? window.currentPage : 0; + const start = currentPage * pageSize; + const end = typeof words[start + pageSize] !== 'undefined' ? start + pageSize : words.length - 1; + + words.slice(start, end).forEach(originalWord => { let detailsMarkdown = removeTags(originalWord.longDefinition); const references = detailsMarkdown.match(/\{\{.+?\}\}/g); if (references && Array.isArray(references)) { @@ -156,6 +163,31 @@ export function renderWords() { let resultsText = searchTerm !== '' || !filters.allPartsOfSpeechChecked ? words.length.toString() + ' Results' : ''; resultsText += !filters.allPartsOfSpeechChecked ? ' (Filtered)' : ''; document.getElementById('searchResults').innerHTML = resultsText; + + renderPagination(); +} + +export function renderPagination() { + const numWords = window.currentDictionary.words.length; + const pageSize = window.localStorage.getItem('pageSize') ? parseInt(window.localStorage.getItem('pageSize')) : DEFAULT_PAGE_SIZE; + const pages = Math.floor(numWords / pageSize); + const currentPage = window.hasOwnProperty('currentPage') ? window.currentPage : 0; + + if (pages > 0) { + let paginationHTML = (currentPage > 0 ? '« Previous' : '') + + '' + + (currentPage < pages - 1 ? 'Next »' : ''); + + Array.from(document.getElementsByClassName('pagination')).forEach(pagination => { + pagination.innerHTML = paginationHTML; + }); + + setupPagination(); + } } export function renderEditForm() { diff --git a/src/js/search.js b/src/js/search.js index 5aedd73..95c8d14 100644 --- a/src/js/search.js +++ b/src/js/search.js @@ -28,7 +28,6 @@ export function getSearchFilters() { export function getMatchingSearchWords() { const searchTerm = getSearchTerm(); const filters = getSearchFilters(); - console.log('filters', filters); const matchingWords = window.currentDictionary.words.slice().filter(word => { if (!filters.allPartsOfSpeechChecked) { const partOfSpeech = word.partOfSpeech === '' ? 'Unclassified' : word.partOfSpeech; @@ -47,11 +46,12 @@ export function getMatchingSearchWords() { export function highlightSearchTerm(word) { const searchTerm = getSearchTerm(); - const markedUpWord = cloneObject(word); if (searchTerm) { + const markedUpWord = cloneObject(word); markedUpWord.name = markedUpWord.name.replace(new RegExp(searchTerm, 'g'), `${searchTerm}`); markedUpWord.simpleDefinition = markedUpWord.simpleDefinition.replace(new RegExp(searchTerm, 'g'), `${searchTerm}`); markedUpWord.longDefinition = markedUpWord.longDefinition.replace(new RegExp(searchTerm, 'g'), `${searchTerm}`); + return markedUpWord; } - return markedUpWord; + return word; } \ No newline at end of file diff --git a/src/js/setupListeners.js b/src/js/setupListeners.js index ea79d3f..7ae3be4 100644 --- a/src/js/setupListeners.js +++ b/src/js/setupListeners.js @@ -4,6 +4,7 @@ import { validateWord, addWord } from './wordManagement'; import { removeTags } from '../helpers'; import { getNextId } from './utilities'; import { openEditModal, save, saveAndClose } from './dictionaryManagement'; +import { goToNextPage, goToPreviousPage, goToPage } from './pagination'; export default function setupListeners() { setupDetailsTabs(); @@ -171,3 +172,23 @@ export function setupWordOptionSelections() { } }); } + +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); + }); +} diff --git a/src/js/utilities.js b/src/js/utilities.js index 2ba34bc..7f4eb91 100644 --- a/src/js/utilities.js +++ b/src/js/utilities.js @@ -1,4 +1,5 @@ import { cloneObject } from '../helpers'; +import { addWord } from './wordManagement'; export function getNextId() { const lastId = window.currentDictionary.words.reduce((highestId, word) => { @@ -105,3 +106,28 @@ export function wordExists(word, returnId = false) { }); return foundWord ? (returnId ? foundWord.wordId : true) : false; } + +export function generateRandomWords(numberOfWords) { + console.log('Generating', numberOfWords, 'words...'); + const letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; + letters.forEach(letter => letters.push(letter.toUpperCase())); + const words = []; + while (words.length < numberOfWords) { + let word = ''; + while (word === '' || words.includes(word)) { + word += letters[Math.floor(Math.random() * letters.length)]; + } + words.push(word); + } + words.forEach((word, index) => { + addWord({ + name: word, + pronunciation: '/' + word + '/', + partOfSpeech: Math.random() > 0.5 ? 'Noun' : 'Verb', + simpleDefinition: word, + longDefinition: word + (index > 0 ? '\n\nRef: {{' + words[index - 1] + '}}' : ''), + wordId: getNextId(), + }, false); + }); + console.log('done'); +} diff --git a/src/js/wordManagement.js b/src/js/wordManagement.js index 2139c4a..2210a8c 100644 --- a/src/js/wordManagement.js +++ b/src/js/wordManagement.js @@ -1,5 +1,6 @@ import { renderWords } from "./render"; import { wordExists } from "./utilities"; +import removeDiacritics from "./StackOverflow/removeDiacritics"; export function validateWord(word, wordId = false) { const errorElementId = wordId === false ? 'wordErrorMessage' : 'wordErrorMessage_' + wordId, @@ -25,15 +26,17 @@ export function validateWord(word, wordId = false) { return errorMessage === ''; } -export function addWord(word) { +export function addWord(word, render = true) { const { sortByDefinition } = window.currentDictionary.settings; const sortBy = sortByDefinition ? 'simpleDefinition' : 'name'; window.currentDictionary.words.push(word); window.currentDictionary.words.sort((wordA, wordB) => { - if (wordA[sortBy] === wordB[sortBy]) return 0; - return wordA[sortBy] > wordB[sortBy] ? 1 : -1; + if (removeDiacritics(wordA[sortBy]).toLowerCase() === removeDiacritics(wordB[sortBy]).toLowerCase()) return 0; + return removeDiacritics(wordA[sortBy]).toLowerCase() > removeDiacritics(wordB[sortBy]).toLowerCase() ? 1 : -1; }); - renderWords(); + if (render) { + renderWords(); + } } diff --git a/src/styles/_elements.scss b/src/styles/_elements.scss index 980532a..f5e308f 100644 --- a/src/styles/_elements.scss +++ b/src/styles/_elements.scss @@ -170,4 +170,27 @@ span .tag { div.three-quarter { width: 72%; } -} \ No newline at end of file +} + +.pagination { + position: relative; + text-align: center; + margin: $general-padding 0; + + .page-selector { + padding: 5px 10px; + } + + .prev-button, + .next-button { + position: absolute; + } + + .prev-button { + left: 2.5%; + } + + .next-button { + right: 2.5%; + } +}