Loading plugins/ead_search/ead_search.css +7 −0 Original line number Diff line number Diff line Loading @@ -119,3 +119,10 @@ font-weight: bold; text-align:right; } .ead-search-alpha { cursor : pointer; } .ead-search-alpha.selected{ color: black; font-weight: bold; } No newline at end of file plugins/ead_search/ead_search.js +31 −15 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ const PAGE_LENGTH = 10; class EadSearchPlugin extends Plugin{ constructor(name) { super(name); this.currentFirstLetterFilter = null; this.withDatesFilter = document.getElementById('ead-search-date-cb').checked; this.filters = {} if(document.getElementById('ead-search-section')){ Loading Loading @@ -35,24 +36,26 @@ class EadSearchPlugin extends Plugin{ let indexName = e.dataset.index; let q = e.value; if(q.trim() !==''){ let url = baseURI + projectId + '/search-index/'+indexName+'.json?q='+ q ; let url = baseURI + projectId + '/search-index/'+indexName+'.json?q=.*'+ q +'.*' ; url += e.dataset.attr ? ('&attr=' +e.dataset.attr + '&value='+e.dataset.value) : ''; let datalist = document.getElementById(indexId); fetch(url).then((res) => res.json()).then( (json) => { datalist.innerHTML = ''; let entries = json.entries datalist.querySelectorAll('*').forEach(n => n.remove()); let entries = json.entries; let options ='' entries.forEach((entry) => { let option = document.createElement('option'); option.value = decodeURIComponent(entry.normal); datalist.appendChild(option); }) options += '<option value="'+decodeURIComponent(entry.normal)+'"/>'; }); datalist.innerHTML=options; }); document.getElementById(indexId+'-input').addEventListener('input', (event) => { if(event.inputType === 'insertReplacementText'){ this.addIndexFilter(indexName, event.target.value, indexId) } }); }) } }) }) Loading @@ -69,6 +72,8 @@ class EadSearchPlugin extends Plugin{ } popupIndex(tagId){ this.currentFirstLetterFilter = null; document.getElementById('alpha-'+tagId).classList.toggle('selected') document.querySelectorAll('.ead-search-popup').forEach((p) => p.style.display='none') if(!document.getElementById('ul-'+tagId)){//needs first fetch this.fetchPage(tagId, 1); Loading @@ -92,15 +97,19 @@ class EadSearchPlugin extends Plugin{ let tagName = inputTarget.dataset.index; let url = baseURI + projectId + '/search-index/'+tagName+'.json?page='+pageNumber; url += inputTarget.dataset.attr ? ('&attr=' +inputTarget.dataset.attr + '&value='+inputTarget.dataset.value) : ''; if(this.currentFirstLetterFilter) url += "&q=^"+this.currentFirstLetterFilter fetch(url) .then((res) => res.json()).then( (json) => { let entries = json.entries let total = json.total; if(pageNumber === 1) { let totalElt = document.createElement('h5'); totalElt.innerHTML = total + (entries > 1 ? ' entrée' : ' entrées'); let totalElt = document.getElementById('ead-search-nb-entries-'+tagId) if(!totalElt) { totalElt = document.createElement('h5'); totalElt.setAttribute('id','ead-search-nb-entries-'+tagId) popupContent.appendChild(totalElt); } totalElt.innerHTML = total + (entries > 1 ? ' entrée' : ' entrées'); listTarget.innerHTML = ''; entries.forEach((entry, n) => { let li = document.createElement('li'); Loading Loading @@ -149,6 +158,13 @@ class EadSearchPlugin extends Plugin{ // }) // } fetchIndexEntriesByLetter(letter, tagId) { this.currentFirstLetterFilter = letter.trim() === '' ? null : letter; document.querySelectorAll('.ead-search-alpha.selected').forEach(e => {e.classList.toggle('selected')}) document.getElementById("alpha-"+tagId+(this.currentFirstLetterFilter ? '-'+ this.currentFirstLetterFilter : '')).classList.toggle('selected') this.fetchPage(tagId, 1) } addIndexFilter(filterType, filterValue, filterId){ if(filterValue.trim() === '') return; Loading plugins/ead_search/ead_search.xqm +52 −18 Original line number Diff line number Diff line Loading @@ -45,13 +45,25 @@ function max.plugin.ead_search:searchPage($project){ <div class="ead-search-popup" id="ead-search-popup-{$tagId}"> <button class="ead-search-close-popup" onclick="window.eadSearch.togglePopup('{$tagId}')">×</button> <div id="ead-search-popup-{$tagId}-alphabet" class="ead-search-popup-alphabet"> {for $l in 1 to 26 return <a onclick="window.eadSearch.fetchIndexEntriesByLetter('','{$tagId}')" class="ead-search-alpha" id="alpha-{$tagId}" > Tout </a> | { (: for $l in max.plugin.ead_search:indexFirstLetters($project, $tagName, $attr, $value):) (: return <a>{$l}</a>:) for $l in 1 to 26 return let $letter:= codepoints-to-string($l+64) return <a>{codepoints-to-string($l+64)}</a> (: if(max.plugin.ead_search:countTagsWithFirstLetter($project, $tagName, $letter) > 0):) (: then <a>{codepoints-to-string($l+64)}</a>:) (: else():) return <a onclick="window.eadSearch.fetchIndexEntriesByLetter('{$letter}','{$tagId}')" class="ead-search-alpha" id="alpha-{$tagId}-{$letter}"> {codepoints-to-string($l+64)} </a> } </div> <div id="ead-search-popup-{$tagId}-contents"></div> </div> Loading Loading @@ -107,8 +119,8 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s (: let $or := string-join(for $n in $p return '@normal="'||$n||'" or contains(./text(),"'||$n||'")',' or ' ):) let $or := string-join(for $n in $p return '@normal="'||$n||'"',' or ' ) return if($i = 1) then ' where count($c//*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' else ' and count($c//*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' if($i = 1) then ' where count($c/*[not(local-name(.)="c")]//*:'||$index||'['||$or||'])>0 ' else ' and count($c/*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' let $joinedSubQueries := fn:string-join($subqueries,'') let $fullQuery := $queryStart || $joinedSubQueries || ' return $c' Loading @@ -117,14 +129,16 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s let $matches := max.plugin.ead_search:dateFilter( $project,$from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) let $html:= <ul>{ for $c in $matches return <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li> let $html:= <ol class="ead-search-results">{ for $c at $pos in $matches return max.plugin.ead_search:formatSearchResult($c, $pos) (:<li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li>:) } </ul> </ol> return <section> <h3>Résultats - {count($matches)}</h3> <h3>Résultats - {count($html/li/@id)}</h3> <h4>XQuery = {$fullQuery} - (db = {$dbPath})</h4> {$html} </section> Loading @@ -133,7 +147,15 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s max:max-error("Erreur code " || $err:code, $err:description ||'('||$fullQuery||')',$err:module, $err:line-number) } }; declare %private function max.plugin.ead_search:formatSearchResult($c as node(), $n as xs:integer){ <li class="ead-search-result" id="{$n}">{ let $titles := for $i in $c/ancestor-or-self::*:c return (string-join($i/*:did/*:unitid/text(),'')) return string-join($titles, " ▸ ") }</li> (: for $c in :) (: <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li>:) }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string, $format as xs:string){ try { switch ($format) Loading @@ -151,6 +173,7 @@ declare %private function max.plugin.ead_search:parseDateParameter($strDate as x }; (:filters ead:c according to their unitdate:) declare %private function max.plugin.ead_search:dateFilter( $project as xs:string, $from as xs:string?, Loading @@ -168,6 +191,7 @@ declare %private function max.plugin.ead_search:dateFilter( }; (:fiters ead:c between $from and $to dates:) declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:string, $to as xs:string, $dateFormat as xs:string, $matches as item()*){ let $fromDateTime := max.plugin.ead_search:parseDateParameter($from,$dateFormat) Loading Loading @@ -207,7 +231,7 @@ declare %rest:query-param("q", "{$query}") %rest:query-param("page", "{$page}",1) %rest:path("/{$project}/search-index/{$tag}.json") function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer,$attr, $value, $query as xs:string?){ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer,$attr as xs:string, $value as xs:string, $query as xs:string?){ let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, $page, $attr, $value, $query) let $jsonStr := for $entry in $entries/* Loading @@ -225,6 +249,16 @@ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as (:declare %private function max.plugin.ead_search:indexFirstLetters($project, $tag as xs:string, $attr as xs:string, $value as xs:string){:) (: $page = -1 means all entries :) (:let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, -1, $attr, $value, ()):) (:let $letters := for $entry in distinct-values($entries//@normal) return substring($entry,1,1):) (:return distinct-values($letters):) (:};:) declare %rest:GET %rest:query-param("attr", "{$attr}") Loading @@ -247,7 +281,7 @@ function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:int ) and ( if($query) then $elt/@normal[contains(., $query)] then $elt/@normal[matches(., $query,'i')] else true() ) return $elt Loading @@ -258,8 +292,8 @@ function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:int return string($e/@normal) (:positions computing according to page number:) let $start := $page * $pageLength - ($pageLength -1) let $end := $start + $pageLength let $start := if($page = -1) then 1 else $page * $pageLength - ($pageLength -1) let $end := if($page = -1) then count($allNormals) else $start + $pageLength (:filter : avoid doublons:) return Loading Loading
plugins/ead_search/ead_search.css +7 −0 Original line number Diff line number Diff line Loading @@ -119,3 +119,10 @@ font-weight: bold; text-align:right; } .ead-search-alpha { cursor : pointer; } .ead-search-alpha.selected{ color: black; font-weight: bold; } No newline at end of file
plugins/ead_search/ead_search.js +31 −15 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ const PAGE_LENGTH = 10; class EadSearchPlugin extends Plugin{ constructor(name) { super(name); this.currentFirstLetterFilter = null; this.withDatesFilter = document.getElementById('ead-search-date-cb').checked; this.filters = {} if(document.getElementById('ead-search-section')){ Loading Loading @@ -35,24 +36,26 @@ class EadSearchPlugin extends Plugin{ let indexName = e.dataset.index; let q = e.value; if(q.trim() !==''){ let url = baseURI + projectId + '/search-index/'+indexName+'.json?q='+ q ; let url = baseURI + projectId + '/search-index/'+indexName+'.json?q=.*'+ q +'.*' ; url += e.dataset.attr ? ('&attr=' +e.dataset.attr + '&value='+e.dataset.value) : ''; let datalist = document.getElementById(indexId); fetch(url).then((res) => res.json()).then( (json) => { datalist.innerHTML = ''; let entries = json.entries datalist.querySelectorAll('*').forEach(n => n.remove()); let entries = json.entries; let options ='' entries.forEach((entry) => { let option = document.createElement('option'); option.value = decodeURIComponent(entry.normal); datalist.appendChild(option); }) options += '<option value="'+decodeURIComponent(entry.normal)+'"/>'; }); datalist.innerHTML=options; }); document.getElementById(indexId+'-input').addEventListener('input', (event) => { if(event.inputType === 'insertReplacementText'){ this.addIndexFilter(indexName, event.target.value, indexId) } }); }) } }) }) Loading @@ -69,6 +72,8 @@ class EadSearchPlugin extends Plugin{ } popupIndex(tagId){ this.currentFirstLetterFilter = null; document.getElementById('alpha-'+tagId).classList.toggle('selected') document.querySelectorAll('.ead-search-popup').forEach((p) => p.style.display='none') if(!document.getElementById('ul-'+tagId)){//needs first fetch this.fetchPage(tagId, 1); Loading @@ -92,15 +97,19 @@ class EadSearchPlugin extends Plugin{ let tagName = inputTarget.dataset.index; let url = baseURI + projectId + '/search-index/'+tagName+'.json?page='+pageNumber; url += inputTarget.dataset.attr ? ('&attr=' +inputTarget.dataset.attr + '&value='+inputTarget.dataset.value) : ''; if(this.currentFirstLetterFilter) url += "&q=^"+this.currentFirstLetterFilter fetch(url) .then((res) => res.json()).then( (json) => { let entries = json.entries let total = json.total; if(pageNumber === 1) { let totalElt = document.createElement('h5'); totalElt.innerHTML = total + (entries > 1 ? ' entrée' : ' entrées'); let totalElt = document.getElementById('ead-search-nb-entries-'+tagId) if(!totalElt) { totalElt = document.createElement('h5'); totalElt.setAttribute('id','ead-search-nb-entries-'+tagId) popupContent.appendChild(totalElt); } totalElt.innerHTML = total + (entries > 1 ? ' entrée' : ' entrées'); listTarget.innerHTML = ''; entries.forEach((entry, n) => { let li = document.createElement('li'); Loading Loading @@ -149,6 +158,13 @@ class EadSearchPlugin extends Plugin{ // }) // } fetchIndexEntriesByLetter(letter, tagId) { this.currentFirstLetterFilter = letter.trim() === '' ? null : letter; document.querySelectorAll('.ead-search-alpha.selected').forEach(e => {e.classList.toggle('selected')}) document.getElementById("alpha-"+tagId+(this.currentFirstLetterFilter ? '-'+ this.currentFirstLetterFilter : '')).classList.toggle('selected') this.fetchPage(tagId, 1) } addIndexFilter(filterType, filterValue, filterId){ if(filterValue.trim() === '') return; Loading
plugins/ead_search/ead_search.xqm +52 −18 Original line number Diff line number Diff line Loading @@ -45,13 +45,25 @@ function max.plugin.ead_search:searchPage($project){ <div class="ead-search-popup" id="ead-search-popup-{$tagId}"> <button class="ead-search-close-popup" onclick="window.eadSearch.togglePopup('{$tagId}')">×</button> <div id="ead-search-popup-{$tagId}-alphabet" class="ead-search-popup-alphabet"> {for $l in 1 to 26 return <a onclick="window.eadSearch.fetchIndexEntriesByLetter('','{$tagId}')" class="ead-search-alpha" id="alpha-{$tagId}" > Tout </a> | { (: for $l in max.plugin.ead_search:indexFirstLetters($project, $tagName, $attr, $value):) (: return <a>{$l}</a>:) for $l in 1 to 26 return let $letter:= codepoints-to-string($l+64) return <a>{codepoints-to-string($l+64)}</a> (: if(max.plugin.ead_search:countTagsWithFirstLetter($project, $tagName, $letter) > 0):) (: then <a>{codepoints-to-string($l+64)}</a>:) (: else():) return <a onclick="window.eadSearch.fetchIndexEntriesByLetter('{$letter}','{$tagId}')" class="ead-search-alpha" id="alpha-{$tagId}-{$letter}"> {codepoints-to-string($l+64)} </a> } </div> <div id="ead-search-popup-{$tagId}-contents"></div> </div> Loading Loading @@ -107,8 +119,8 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s (: let $or := string-join(for $n in $p return '@normal="'||$n||'" or contains(./text(),"'||$n||'")',' or ' ):) let $or := string-join(for $n in $p return '@normal="'||$n||'"',' or ' ) return if($i = 1) then ' where count($c//*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' else ' and count($c//*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' if($i = 1) then ' where count($c/*[not(local-name(.)="c")]//*:'||$index||'['||$or||'])>0 ' else ' and count($c/*[local-name(.)!="c"]//*:'||$index||'['||$or||'])>0 ' let $joinedSubQueries := fn:string-join($subqueries,'') let $fullQuery := $queryStart || $joinedSubQueries || ' return $c' Loading @@ -117,14 +129,16 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s let $matches := max.plugin.ead_search:dateFilter( $project,$from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) let $html:= <ul>{ for $c in $matches return <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li> let $html:= <ol class="ead-search-results">{ for $c at $pos in $matches return max.plugin.ead_search:formatSearchResult($c, $pos) (:<li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li>:) } </ul> </ol> return <section> <h3>Résultats - {count($matches)}</h3> <h3>Résultats - {count($html/li/@id)}</h3> <h4>XQuery = {$fullQuery} - (db = {$dbPath})</h4> {$html} </section> Loading @@ -133,7 +147,15 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s max:max-error("Erreur code " || $err:code, $err:description ||'('||$fullQuery||')',$err:module, $err:line-number) } }; declare %private function max.plugin.ead_search:formatSearchResult($c as node(), $n as xs:integer){ <li class="ead-search-result" id="{$n}">{ let $titles := for $i in $c/ancestor-or-self::*:c return (string-join($i/*:did/*:unitid/text(),'')) return string-join($titles, " ▸ ") }</li> (: for $c in :) (: <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li>:) }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string, $format as xs:string){ try { switch ($format) Loading @@ -151,6 +173,7 @@ declare %private function max.plugin.ead_search:parseDateParameter($strDate as x }; (:filters ead:c according to their unitdate:) declare %private function max.plugin.ead_search:dateFilter( $project as xs:string, $from as xs:string?, Loading @@ -168,6 +191,7 @@ declare %private function max.plugin.ead_search:dateFilter( }; (:fiters ead:c between $from and $to dates:) declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:string, $to as xs:string, $dateFormat as xs:string, $matches as item()*){ let $fromDateTime := max.plugin.ead_search:parseDateParameter($from,$dateFormat) Loading Loading @@ -207,7 +231,7 @@ declare %rest:query-param("q", "{$query}") %rest:query-param("page", "{$page}",1) %rest:path("/{$project}/search-index/{$tag}.json") function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer,$attr, $value, $query as xs:string?){ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer,$attr as xs:string, $value as xs:string, $query as xs:string?){ let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, $page, $attr, $value, $query) let $jsonStr := for $entry in $entries/* Loading @@ -225,6 +249,16 @@ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as (:declare %private function max.plugin.ead_search:indexFirstLetters($project, $tag as xs:string, $attr as xs:string, $value as xs:string){:) (: $page = -1 means all entries :) (:let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, -1, $attr, $value, ()):) (:let $letters := for $entry in distinct-values($entries//@normal) return substring($entry,1,1):) (:return distinct-values($letters):) (:};:) declare %rest:GET %rest:query-param("attr", "{$attr}") Loading @@ -247,7 +281,7 @@ function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:int ) and ( if($query) then $elt/@normal[contains(., $query)] then $elt/@normal[matches(., $query,'i')] else true() ) return $elt Loading @@ -258,8 +292,8 @@ function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:int return string($e/@normal) (:positions computing according to page number:) let $start := $page * $pageLength - ($pageLength -1) let $end := $start + $pageLength let $start := if($page = -1) then 1 else $page * $pageLength - ($pageLength -1) let $end := if($page = -1) then count($allNormals) else $start + $pageLength (:filter : avoid doublons:) return Loading