Usability fixes

This commit is contained in:
Augusto Gunsch 2021-12-26 14:46:40 -03:00
parent ef4043b07c
commit 5a84789c7b
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
2 changed files with 174 additions and 166 deletions

View File

@ -16,7 +16,7 @@
<div class="containter" id="main"> <div class="containter" id="main">
<form class="sticky-top" id="search-form"> <form class="sticky-top" id="search-form">
<div class="ui-widget" id="search-widget"> <div class="ui-widget" id="search-widget">
<input id="search-bar" placeholder="Search..." type="text" autocorrect="off" autocapitalize="none"> <input id="search-bar" placeholder="Search..." type="text" autocorrect="off" autocapitalize="none" autofocus>
</div> </div>
<button type="submit" class="ui-button ui-widget ui-button-icon-only" id="search"> <button type="submit" class="ui-button ui-widget ui-button-icon-only" id="search">
<span class="ui-icon ui-icon-search"></span> <span class="ui-icon ui-icon-search"></span>

View File

@ -1,187 +1,195 @@
let polishSchemas = null; $(document).ready(() => {
let polishSchemas = null;
$.ajax({
url: '/static/schemas/polish.json',
success: data => polishSchemas = data
});
let searchBar = $('#search-bar');
searchBar.autocomplete({
source: (request, response) => {
$.ajax({
url: '/langs/polish/words?like=' + request.term + '&limit=20&offset=0',
success: data => response(data)
})
}
});
let bar = $('#search-bar')
bar.click((e) => {
bar[0].select();
});
$('#search-form').on('submit', (e) => {
e.preventDefault();
let word = e.target[0].value
getWord(word);
});
function getWord(word) {
$.ajax({ $.ajax({
url: '/langs/polish/words/' + word, url: '/static/schemas/polish.json',
success: data => {
success: (data) => { polishSchemas = data
$('#ajax-content').html(generateHtml(word, data)) if(window.location.hash) {
searchBar.autocomplete('close'); getWord();
},
error: err => console.error(err)
})
}
function getCells(forms, tags) {
if(tags.length === 0)
return undefined;
let cells = forms.filter(form =>
tags.every(value => form.tags.includes(value))
);
cells.forEach(cell =>
cell.used = true
);
if(cells.length === 0)
return undefined;
return cells;
}
function generateList(data) {
let html = '<ul>';
data.forEach(cell =>
html += `<li><strong>${cell.form}</strong> - ${cell.tags.join(', ')}</li>`
);
html += '</ul>';
return html;
}
function generateTable(schemas, pos, forms) {
let schema = schemas.find(schema => schema.pos.includes(pos));
// No schema was provided by the server - fallback to a list
if(!schema)
return generateList(forms);
let html = '<div class="table-responsive">';
html += '<table class="table table-sm table-bordered border-dark text-center align-middle">';
schema.rows.forEach(row => {
html += '<tr>';
row.forEach(cell => {
if('display' in cell) {
html += `<th class="table-light border-dark" colspan="${cell.colspan}" rowspan="${cell.rowspan}">${cell.display}</th>`;
} else {
let cells = getCells(forms, cell.tags);
let content = cells ? cells.map(cell => cell.form).join(', <br>') : '-';
html += `<td colspan="${cell.colspan}" rowspan="${cell.rowspan}">${content}</td>`;
} }
}); }
html += '</tr>';
}); });
html += '</table>'; window.onhashchange = () => {
html += '</div>'; getWord();
};
let unusedCells = forms.filter(cell => !cell.used); let searchBar = $('#search-bar');
if(schema.ignoreUnused) { searchBar.autocomplete({
unusedCells = unusedCells.filter(cell => source: (request, response) => {
!schema.ignoreUnused.map(tags => tags.every(tag => cell.tags.includes(tag))) $.ajax({
url: '/langs/polish/words?like=' + request.term + '&limit=20&offset=0',
success: data => response(data)
})
}
});
$('#search-bar').on('focus', e => {
setTimeout(() => e.currentTarget.select(), 100);
});
$('#search-form').on('submit', (e) => {
e.preventDefault();
let word = e.target[0].value
window.location.hash = `#${word}`;
});
function getWord() {
let word = window.location.hash.replace('#', '');
$.ajax({
url: '/langs/polish/words/' + word,
success: (data) => {
$('#ajax-content').html(generateHtml(word, data))
searchBar.autocomplete('close');
window.scrollTo(0, 0);
},
error: err => console.error(err)
})
}
function getCells(forms, tags) {
if(tags.length === 0)
return undefined;
let cells = forms.filter(form =>
tags.every(value => form.tags.includes(value))
); );
cells.forEach(cell =>
cell.used = true
);
if(cells.length === 0)
return undefined;
return cells;
} }
if(unusedCells.length > 0) { function generateList(data) {
html += '<h3>Other</h3>'; let html = '<ul>';
html += generateList(unusedCells); data.forEach(cell =>
html += `<li><strong>${cell.form}</strong> - ${cell.tags.join(', ')}</li>`
);
html += '</ul>';
return html;
} }
return html; function generateTable(schemas, pos, forms) {
} let schema = schemas.find(schema => schema.pos.includes(pos));
function generateHtml(word, data) { // No schema was provided by the server - fallback to a list
let html = ''; if(!schema)
return generateList(forms);
if(data.length === 0) { let html = '<div class="table-responsive">';
html += `<h1>Not found: <mark>${word}</mark></h1>`; html += '<table class="table table-sm table-bordered border-dark text-center align-middle">';
} else {
data.forEach(entry => {
html += `<h1>${entry.word} <span class="pos">(${entry.pos})</span></h1>`
if('senses' in entry) {
let tags = [];
entry.senses.forEach(sense => {
if('tags' in sense) {
tags.push(...sense.tags);
}
});
if(tags.length > 0) { schema.rows.forEach(row => {
tags = [...new Set(tags)]; html += '<tr>';
html += '<div class="tags">Tags: ' row.forEach(cell => {
html += tags.map(tag => `<mark>${tag}</mark>`).join(', ') if('display' in cell) {
html += '</div>' html += `<th class="table-light border-dark" colspan="${cell.colspan}" rowspan="${cell.rowspan}">${cell.display}</th>`;
}
html += '<h2>Senses</h2>';
html += '<ol>';
entry.senses.forEach(sense => {
html += '<li>'
if('form_of' in sense) {
let word = sense.form_of[0].word;
html += sense.glosses[0].replace(new RegExp(`of ${word}$`), '');
html += ` of <a href="#" class="link-primary" onclick="getWord('${word}')">${word}</a>`;
} else {
html += sense.glosses[0];
}
html += '</li>';
})
html += '</ol>';
}
if('forms' in entry) {
if(entry.pos === 'verb') {
let conjugation = entry.forms.filter(form =>
'source' in form && form.source === 'Conjugation');
if(conjugation.length > 0) {
html += '<h2>Conjugation</h2>';
html += generateTable(polishSchemas, entry.pos, conjugation);
}
} else { } else {
let declension = entry.forms.filter(form => let cells = getCells(forms, cell.tags);
'source' in form && form.source === 'Declension'); let content = cells ? cells.map(cell => cell.form).join(', <br>') : '-';
html += `<td colspan="${cell.colspan}" rowspan="${cell.rowspan}">${content}</td>`;
if(declension.length > 0) {
html += '<h2>Declension</h2>';
html += generateTable(polishSchemas, entry.pos, declension);
}
} }
} });
html += '</tr>';
}); });
html += '</table>';
html += '</div>';
let unusedCells = forms.filter(cell => !cell.used);
if(schema.ignoreUnused) {
unusedCells = unusedCells.filter(cell =>
!schema.ignoreUnused.map(tags => tags.every(tag => cell.tags.includes(tag)))
);
}
if(unusedCells.length > 0) {
html += '<h3>Other</h3>';
html += generateList(unusedCells);
}
return html;
} }
return html; function generateHtml(word, data) {
} let html = '';
$(document).ready(function() { if(data.length === 0) {
$('#search-bar').select(); html += `<h1>Not found: <mark>${word}</mark></h1>`;
} else {
data.forEach(entry => {
html += `<h1>${entry.word} <span class="pos">(${entry.pos})</span></h1>`
if('senses' in entry) {
let tags = [];
entry.senses.forEach(sense => {
if('tags' in sense) {
tags.push(...sense.tags);
}
});
if(tags.length > 0) {
tags = [...new Set(tags)];
html += '<div class="tags">Tags: '
html += tags.map(tag => `<mark>${tag}</mark>`).join(', ')
html += '</div>'
}
html += '<h2>Senses</h2>';
html += '<ol>';
entry.senses.forEach(sense => {
html += '<li>'
if('form_of' in sense) {
let word = sense.form_of[0].word;
html += sense.glosses[0].replace(new RegExp(`of ${word}$`), '');
html += ` of <a href="#${word}" class="link-primary">${word}</a>`;
} else {
html += sense.glosses[0];
}
html += '</li>';
})
html += '</ol>';
}
if('forms' in entry) {
if(entry.pos === 'verb') {
let conjugation = entry.forms.filter(form =>
'source' in form && form.source === 'Conjugation');
if(conjugation.length > 0) {
html += '<h2>Conjugation</h2>';
html += generateTable(polishSchemas, entry.pos, conjugation);
}
} else {
let declension = entry.forms.filter(form =>
'source' in form && form.source === 'Declension');
if(declension.length > 0) {
html += '<h2>Declension</h2>';
html += generateTable(polishSchemas, entry.pos, declension);
}
}
}
});
}
return html;
}
}); });