|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Dictionary</title> |
|
<style> |
|
body { |
|
font-family: sans-serif; |
|
margin: 20px; |
|
background-color: #f4f4f4; |
|
} |
|
|
|
#container { |
|
width: 80%; |
|
margin: 0 auto; |
|
background-color: white; |
|
padding: 20px; |
|
border-radius: 8px; |
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1); |
|
} |
|
|
|
input[type="file"], input[type="text"] { |
|
padding: 10px; |
|
margin-bottom: 10px; |
|
border: 1px solid #ddd; |
|
border-radius: 4px; |
|
width: calc(100% - 22px); |
|
} |
|
#search { |
|
margin-top: 20px; |
|
width: 98%; |
|
} |
|
|
|
|
|
#results { |
|
list-style: none; |
|
padding: 0; |
|
margin: 0; |
|
} |
|
|
|
#results li { |
|
padding: 15px; |
|
border-bottom: 1px solid #eee; |
|
margin-bottom: 5px; |
|
background-color: #fafafa; |
|
border-radius: 4px; |
|
} |
|
#results li:last-child { |
|
border-bottom: none; |
|
} |
|
|
|
|
|
.word-cell { |
|
font-weight: bold; |
|
font-size: 1.1em; |
|
margin-bottom: 5px; |
|
} |
|
|
|
.translation-cell { |
|
font-style: italic; |
|
color: #333; |
|
margin-bottom: 5px; |
|
} |
|
|
|
.additional-cell { |
|
color: #555; |
|
margin-bottom: 3px; |
|
} |
|
.hidden { |
|
display: none; |
|
} |
|
.error-message { |
|
color: red; |
|
margin-top: 5px; |
|
} |
|
|
|
</style> |
|
</head> |
|
<body> |
|
|
|
<div id="container"> |
|
<h2>Dictionary</h2> |
|
|
|
<input type="file" id="excelFile" accept=".xlsx, .xls, .csv" style="display: none;"> |
|
<input type="file" id="mappingFile" accept=".txt" style="display: none;"> |
|
|
|
<input type="text" id="search" placeholder="Search..."> |
|
<div id="errorMessageContainer" class="error-message"></div> |
|
|
|
<ul id="results"></ul> |
|
</div> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script> |
|
|
|
<script> |
|
const excelFileInput = document.getElementById('excelFile'); |
|
const mappingFileInput = document.getElementById('mappingFile'); |
|
const searchInput = document.getElementById('search'); |
|
const resultsList = document.getElementById('results'); |
|
const errorMessageContainer = document.getElementById('errorMessageContainer'); |
|
|
|
|
|
let excelData = []; |
|
let mapping = {}; |
|
|
|
|
|
|
|
|
|
async function fetchAndProcessFile(filename, fileType, processFunction) { |
|
try { |
|
const response = await fetch(filename); |
|
if (!response.ok) { |
|
if (response.status === 404){ |
|
throw new Error(`${fileType} file not found: ${filename}`); |
|
} |
|
throw new Error(`HTTP error! status: ${response.status} for ${filename}`); |
|
} |
|
const data = (fileType === 'Excel') ? await response.arrayBuffer() : await response.text(); |
|
processFunction(data); |
|
|
|
} catch (error) { |
|
console.error(`Error loading or processing ${fileType} file:`, error); |
|
errorMessageContainer.textContent = error.message; |
|
} |
|
} |
|
|
|
|
|
function processExcel(data) { |
|
const workbook = XLSX.read(data, { type: 'array', raw: false }); |
|
const sheetName = workbook.SheetNames[0]; |
|
excelData = XLSX.utils.sheet_to_json(workbook.Sheets[sheetName], { header: 1, raw: false }); |
|
if (Object.keys(mapping).length > 0) { |
|
displayData(); |
|
} |
|
} |
|
|
|
|
|
|
|
function processMapping(text) { |
|
parseMapping(text); |
|
if (excelData.length > 0){ |
|
displayData(); |
|
} |
|
} |
|
|
|
function parseMapping(text) { |
|
mapping = {}; |
|
const lines = text.trim().split('\n'); |
|
lines.forEach(line => { |
|
const [column, fieldName] = line.trim().split('|'); |
|
if (column && fieldName) { |
|
mapping[column.trim()] = fieldName.trim(); |
|
} |
|
}); |
|
|
|
} |
|
|
|
function displayData(filteredData = null) { |
|
resultsList.innerHTML = ''; |
|
errorMessageContainer.textContent = ''; |
|
|
|
const dataToDisplay = filteredData || excelData; |
|
|
|
dataToDisplay.forEach(row => { |
|
if (row.length === 0) return; |
|
|
|
const listItem = document.createElement('li'); |
|
let hasContent = false; |
|
|
|
|
|
if (mapping['A'] ) { |
|
const colIndexA = 'A'.charCodeAt(0) - 'A'.charCodeAt(0); |
|
if (row[colIndexA] != undefined){ |
|
const wordCell = document.createElement('div'); |
|
wordCell.className = 'word-cell'; |
|
wordCell.textContent = row[colIndexA]; |
|
listItem.appendChild(wordCell); |
|
hasContent = true; |
|
} |
|
|
|
} |
|
|
|
|
|
if (mapping['B']) { |
|
const colIndexB = 'B'.charCodeAt(0) - 'A'.charCodeAt(0); |
|
if (row[colIndexB] != undefined){ |
|
const translationCell = document.createElement('div'); |
|
translationCell.className = 'translation-cell'; |
|
translationCell.textContent = row[colIndexB]; |
|
listItem.appendChild(translationCell); |
|
hasContent = true; |
|
} |
|
|
|
} |
|
|
|
|
|
for (let i = 2; i < 26; i++) { |
|
const columnLetter = String.fromCharCode('A'.charCodeAt(0) + i); |
|
if (mapping[columnLetter]) { |
|
const colIndex = columnLetter.charCodeAt(0) - 'A'.charCodeAt(0); |
|
if(row[colIndex] != undefined) { |
|
const additionalCell = document.createElement('div'); |
|
additionalCell.className = 'additional-cell'; |
|
additionalCell.textContent = `${mapping[columnLetter]}: ${row[colIndex]}`; |
|
listItem.appendChild(additionalCell); |
|
hasContent = true; |
|
} |
|
|
|
} |
|
} |
|
|
|
if (hasContent) { |
|
resultsList.appendChild(listItem); |
|
} |
|
}); |
|
} |
|
|
|
|
|
|
|
|
|
searchInput.addEventListener('input', () => { |
|
const searchTerm = searchInput.value.toLowerCase().trim(); |
|
|
|
if (!searchTerm) { |
|
displayData(); |
|
return; |
|
} |
|
|
|
const filteredData = excelData.filter(row => { |
|
return row.some(cell => { |
|
if (typeof cell === 'string') { |
|
return cell.toLowerCase().includes(searchTerm); |
|
} else if (typeof cell === 'number') { |
|
return cell.toString().toLowerCase().includes(searchTerm); |
|
} |
|
return false; |
|
}); |
|
}); |
|
displayData(filteredData); |
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
fetchAndProcessFile('mapping.txt', 'Mapping', processMapping); |
|
|
|
|
|
const excelExtensions = ['.xlsx', '.xls', '.csv']; |
|
let excelLoaded = false; |
|
async function loadExcelWithDifferentExtensions() { |
|
|
|
|
|
for (const ext of excelExtensions) { |
|
if (excelLoaded) break; |
|
|
|
try { |
|
await fetchAndProcessFile(`dictionary${ext}`, 'Excel', (data) => { |
|
processExcel(data); |
|
excelLoaded = true; |
|
}); |
|
|
|
|
|
} |
|
catch (error) |
|
{ |
|
|
|
console.error(`dictionary${ext} did not load. `); |
|
} |
|
} |
|
if (!excelLoaded) |
|
{ |
|
|
|
errorMessageContainer.textContent = "No Excel file found (dictionary.xlsx, dictionary.xls, or dictionary.csv)"; |
|
} |
|
} |
|
|
|
loadExcelWithDifferentExtensions(); |
|
|
|
</script> |
|
</body> |
|
</html> |