search results modal

This commit is contained in:
Oleg Belyaev 2025-03-23 12:35:13 +03:00
parent 0b4fd5f468
commit 6e7cf5a3f1
3 changed files with 150 additions and 59 deletions

View file

@ -455,13 +455,40 @@ details[open] summary {}
dialog {} dialog {}
dialog::backdrop {} dialog::backdrop {}
dialog#modal_map > article { dialog > article {
width: 75vw !important; width: 75vw !important;
height: 85vh !important; height: 85vh !important;
max-width: 75vw !important; max-width: 75vw !important;
max-height: 85vh !important; max-height: 85vh !important;
} }
dialog#modal_searchResults > article {
padding-top: 0;
padding-bottom: 0;
}
dialog#modal_searchResults > article > table > thead {
position: sticky;
top: 0;
z-index: 1055;
}
dialog#modal_searchResults > article > header {
position: sticky;
top: 0;
z-index: 1055;
}
dialog#modal_searchResults > article > footer {
position: sticky;
bottom: 0;
z-index: 1055;
}
/*dialog#modal_searchResults > article > p > table > tbody {
height:100%;
overflow-y: scroll;
}*/
/* Some form fields, `details`, elements with `tabindex`, and possibly other /* Some form fields, `details`, elements with `tabindex`, and possibly other
elements can be focussed. You should use `:focus-visible` instead of `:focus` elements can be focussed. You should use `:focus-visible` instead of `:focus`
whenever possible. As the former is not yet widely supported, you need to do it whenever possible. As the former is not yet widely supported, you need to do it

View file

@ -1,28 +1,10 @@
$( document ).ready(function() { $( document ).ready(function() {
// GLOBALS
// Link elements that do not have href out of the box // Link elements that do not have href out of the box
$('.link').on("click", function () { $('.link').on("click", function () {
window.location=$(this)[0].dataset.href+window.location.search+window.location.hash; window.location=$(this)[0].dataset.href+window.location.search+window.location.hash;
}); });
function bindMapOpen() {
// $('#modal_map').data('abv-entry',$(this).data('abv-entry'));
// $('#modal_map')[0].showModal();
let url = `./dict/map-info/${$(this).data('abv-entry')}`;
fetch(url)
.then(res => res.json())
.then(out => {
$('#modal_map').data('map',out);
$('#modal_map')[0].showModal();
})
.catch(err => console.log(err));
}
// Event to open map modal. We have to bind it
// when the button is shown, otherwise it will
// not work for newly loaded entries.
$('.abv-map').on("click", bindMapOpen);
// init Infinite Scroll // init Infinite Scroll
$('main').infiniteScroll({ $('main').infiniteScroll({
path: '.pagination__next', path: '.pagination__next',
@ -31,10 +13,71 @@ $( document ).ready(function() {
//hideNav: '.pagination', //hideNav: '.pagination',
}); });
// SEARCH RESULTS MODAL
$('#abv-btn-searchResults').on("click", function () {
$('#modal_searchResults')[0].showModal();
});
// Close search modal
$('.abv-close-search').on("click", function () {
$('#modal_searchResults')[0].close();
});
// MAP MODAL
// This event binding is done on page load and also whenever new entries are loaded.
bindMapOpen = function () {
let url = `./dict/map-info/${$(this).data('abv-entry')}`;
fetch(url)
.then(res => res.json())
.then(out => {
$('#modal_map').data('map',out);
$('#modal_map')[0].showModal();
})
.catch(err => console.log(err));
};
// Event to open map modal.
$('.abv-map').on("click", bindMapOpen);
$('main').on( 'append.infiniteScroll', function( event, body, path, response ) { $('main').on( 'append.infiniteScroll', function( event, body, path, response ) {
$('.abv-map').on("click", bindMapOpen); $('.abv-map').on("click", bindMapOpen);
}); });
// Close map modal
$('.abv-close-map').on("click", function () {
$('#modal_map')[0].close();
});
// Load map data when dialog opens
$('#modal_map').on("toggle", function () {
map = document.getElementById('map_display');
var layout = {
// title: {
// text: 'Canadian cities',
// font: {
// family: 'Droid Serif, serif',
// size: 16
// }
// },
geo: {
scope: 'world',
resolution: 50,
fitbounds: 'locations',
showrivers: true,
rivercolor: '#fff',
showlakes: true,
lakecolor: '#fff',
showland: true,
landcolor: '#EAEAAE',
showcountries: false,
subunitcolor: '#d3d3d3'
}
};
Plotly.newPlot(map, [$(this).data('map')], layout);
});
// HASH NAVIGATION
// If the hash is on the page, scroll a little bit above to account for top nav height // If the hash is on the page, scroll a little bit above to account for top nav height
if ( $(decodeURI(document.location.hash)).length > 0) { if ( $(decodeURI(document.location.hash)).length > 0) {
window.scrollBy(0,-$('header').height()); window.scrollBy(0,-$('header').height());
@ -54,6 +97,7 @@ $( document ).ready(function() {
} }
}); });
// ENTRY LIST SIDE PANEL
// Function to scroll the entry list to the selected entry OR to the first entry displayed on the current page if there is no hash in the URL // Function to scroll the entry list to the selected entry OR to the first entry displayed on the current page if there is no hash in the URL
function scrollView() { function scrollView() {
var $container = $('#entrylist') var $container = $('#entrylist')
@ -108,39 +152,6 @@ $( document ).ready(function() {
return false; return false;
}); });
// Close map modal
$('.abv-close-map').on("click", function () {
$('#modal_map')[0].close();
});
// Load map data when dialog opens
$('#modal_map').on("toggle", function () {
map = document.getElementById('map_display');
var layout = {
// title: {
// text: 'Canadian cities',
// font: {
// family: 'Droid Serif, serif',
// size: 16
// }
// },
geo: {
scope: 'world',
resolution: 50,
fitbounds: 'locations',
showrivers: true,
rivercolor: '#fff',
showlakes: true,
lakecolor: '#fff',
showland: true,
landcolor: '#EAEAAE',
showcountries: false,
subunitcolor: '#d3d3d3'
}
};
Plotly.newPlot(map, [$(this).data('map')], layout);
});
// Event handler to show subentries // Event handler to show subentries
$('#show-re').on("change", function () { $('#show-re').on("change", function () {
if($(this).prop('checked')) { if($(this).prop('checked')) {

View file

@ -120,7 +120,7 @@ declare function page:header($lang as xs:string, $href-other as xs:string) {
<path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/> <path fill-rule="evenodd" d="M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8"/>
</svg> </svg>
</button>, </button>,
<button disabled="true">{session:get('searchN')}/{array:size(session:get('searchData'))}</button> <button type="button" id="abv-btn-searchResults">{session:get('searchN')}/{array:size(session:get('searchData'))}</button>
, ,
if (session:get('searchN') and session:get('searchN') < array:size(session:get('searchData'))) then if (session:get('searchN') and session:get('searchN') < array:size(session:get('searchData'))) then
<button type="button" class="link" data-href="./search/next"> <button type="button" class="link" data-href="./search/next">
@ -208,7 +208,17 @@ declare %rest:path("{$lang}/search/prev")
let $r1 := session:set('searchN', $n) let $r1 := session:set('searchN', $n)
let $sd := session:get('searchData') let $sd := session:get('searchData')
return page:by-id($lang, $sd($n)('entry_id'), string-join($sd($n)('path')?*,"|")) return page:by-id($lang, $sd($n)('entry_id'), string-join($sd($n)('path')?*,"|"))
}; };
declare %rest:path("{$lang}/search/position")
%rest:query-param("p", "{$p}")
%output:method("html")
%output:html-version('5')
function page:search-position($lang,$p) {
let $r1 := session:set('searchN', $p)
let $sd := session:get('searchData')
return page:by-id($lang, $sd($p)('entry_id'), string-join($sd($p)('path')?*,"|"))
};
declare %rest:path("{$lang}/search/clear") declare %rest:path("{$lang}/search/clear")
%output:method("html") %output:method("html")
@ -543,18 +553,61 @@ declare %rest:path("{$lang}/dict")
<!-- Modal for map display --> <!-- Modal for map display -->
<dialog id="modal_map"> <dialog id="modal_map">
<article> <article>
<header><button class="abv-close-map" aria-label="Close" rel="prev"></button> <header>
<p>Map</p> <button class="abv-close-map" aria-label="Close" rel="prev">
</button>
<p>{if ($lang = 'ru') then 'Карта' else 'Map'}</p>
</header> </header>
<p> <p>
<div id="map_display" style="width:100%;height:80%;"></div> <div id="map_display" style="width:100%;height:80%;"></div>
</p> </p>
<footer><button class="abv-close-map">Close</button></footer> <footer><button class="abv-close-map">{if ($lang = 'ru') then 'Закрыть' else 'Close'}</button></footer>
</article> </article>
</dialog> </dialog>
{if (session:get('searchQuery')) then <!-- Modal for search results -->
{if (exists(session:get('searchData'))) then
<dialog id="modal_searchResults"> <dialog id="modal_searchResults">
<article>
<header>
<button class="abv-close-search" aria-label="Close" rel="prev"/>
<p>{if ($lang = 'ru') then 'Результаты поиска'
else 'Search results'}</p>
</header>
<table>
<thead>
<tr>
<td>{if ($lang = 'ru') then '№' else 'No.'}</td>
<td>{if ($lang = 'ru') then 'Лемма' else 'Lemma'}</td>
<td>{if ($lang = 'ru') then 'Фрагмент' else 'Fragment'}</td>
</tr>
</thead>
<tbody>
{
for $res in session:get('searchData')?*
count $pos
return <tr>
<td>{$pos}</td>
<td>
<a href="./search/position?p={$pos}">
{
abv-m:entry-form-by-id($res('entry_id'))
}
</a>
</td>
<td>
{
xquery:eval($res('path')(1), {'': doc(`abaevdict_{$lang}/xml/{$res('entry_id')}.xml`)})
}
</td>
</tr>
}
</tbody>
</table>
<footer>
<button class="abv-close-search">{if ($lang = 'ru') then 'Закрыть' else 'Close'}</button>
</footer>
</article>
</dialog>} </dialog>}
</body> </body>
</html> </html>