Loading plugins/ead_search/default_config.xml 0 → 100644 +17 −0 Changes for plugins/ead_search/default_config.xml: 17 added lines, 0 removed lines. Original line number Diff line number Diff line <?xml version="1.0"?> <search> <tags> <tag name="corpname" label="corpname"/> <tag name="famname" label="famname"/> <tag name="function" label="Fonction"/> <tag name="genreform" label="genreform"/> <tag name="geogname" label="geogname"/> <tag name="occupation" label="Occupation"/> <tag name="name" label="Nom"/> <tag name="persname" label="Nom de personne"/> <tag name="subject" label="Sujet"/> <tag name="title" label="Titre"/> </tags> <dates format="YYYY"></dates> </search> No newline at end of file plugins/ead_search/ead_search.css +21 −0 Changes for plugins/ead_search/ead_search.css: 21 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -44,3 +44,24 @@ #ead-search-results { border-top: 1px solid #888; } .ead-search-popup-wrap{ display: inline; position: relative; } .ead-search-popup{ display: none; position: absolute; top:0; left: 10px; border:1px solid #999; min-width:400px; background-color: white; z-index:10; font-size:0.8rem; } .ead-search-popup-alphabet{ text-align :center; } No newline at end of file plugins/ead_search/ead_search.js +74 −9 Changes for plugins/ead_search/ead_search.js: 74 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -5,40 +5,103 @@ import {Plugin} from '../../core/ui/js/Plugin.js'; class EadSearchPlugin extends Plugin{ constructor(name) { super(name); this.withDatesFilter = document.getElementById('ead-search-date-cb').checked; this.filters = {} if(document.getElementById('ead-search-section')) this.fetchIndexLists(); if(document.getElementById('ead-search-section')){ document.getElementById('ead-search-date-cb').addEventListener('click', (evt) => { this.withDatesFilter = evt.target.checked; if(!this.withDatesFilter){ document.getElementById('ead-search-date-from').setAttribute('disabled', true); document.getElementById('ead-search-date-to').setAttribute('disabled', true); } else{ document.getElementById('ead-search-date-from').removeAttribute('disabled'); document.getElementById('ead-search-date-to').removeAttribute('disabled') } }) this.bindIndexAutocompletes(); } // this.fetchIndexLists(); } fetchIndexLists(){ let indexList = document.querySelectorAll('.ead-search-input') bindIndexAutocompletes(){ let indexList = document.querySelectorAll('.ead-search-input'); indexList.forEach((e) => { e.addEventListener('input', (evt) => { let indexName = e.dataset.index; fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { let q = e.value; if(q.trim() !==''){ let url = baseURI + projectId + '/search-index/'+indexName+'.json?q='+ q ; let datalist = document.getElementById(indexName); fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { datalist.innerHTML = ''; let entries = json.entries entries.forEach((entry) => { let option = document.createElement('option'); option.value = decodeURIComponent(entry.normal); datalist.appendChild(option); }) document.getElementById(indexName+'-input').addEventListener('input', (event) => { //alert(event.target.value) if(event.inputType === 'insertReplacementText'){ this.addIndexFilter(indexName, event.target.value) } }); }) } }) }) } popupIndex(tagName){ let popupElt = document.getElementById('ead-search-popup-'+tagName); let popupContent = document.getElementById('ead-search-popup-'+tagName+"-contents"); popupContent.innerHTML = ''; let url = baseURI + projectId + '/search-index/'+tagName+'.json'; let list = document.createElement('ol'); fetch(baseURI + projectId + '/search-index/'+tagName+'.json').then((res) => res.json()).then( (json) => { let entries = json.entries entries.forEach((entry) => { let li = document.createElement('li'); li.innerHTML = decodeURIComponent(entry.normal); list.appendChild(li); }) }) popupContent.appendChild(list); popupElt.style.display='block'; } // // fetchIndexLists(){ // let indexList = document.querySelectorAll('.ead-search-input') // // indexList.forEach((e) => { // let indexName = e.dataset.index; // fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { // let datalist = document.getElementById(indexName); // let entries = json.entries // entries.forEach((entry) => { // let option = document.createElement('option'); // option.value = decodeURIComponent(entry.normal); // datalist.appendChild(option); // // }) // // document.getElementById(indexName+'-input').addEventListener('input', (event) => { // //alert(event.target.value) // if(event.inputType === 'insertReplacementText'){ // this.addIndexFilter(indexName, event.target.value) // } // // }); // }) // // // }) // } addIndexFilter(filterType, filterValue){ if(filterValue.trim() === '') Loading Loading @@ -78,6 +141,7 @@ class EadSearchPlugin extends Plugin{ query = baseURI + projectId + '/' +query; if(this.withDatesFilter){ //date let dateMode = document.querySelector('input[name=ead-search-radio-date]:checked').value if(dateMode === 'interval'){ Loading @@ -90,6 +154,7 @@ class EadSearchPlugin extends Plugin{ let dateIn = document.getElementById('ead-search-date-in').value; query+=(!filtered ? "?" : "&") + "in="+dateIn } } fetch(query).then(res => res.text()).then(text => { document.getElementById('ead-search-results').innerHTML = text Loading plugins/ead_search/ead_search.xqm +98 −68 Changes for plugins/ead_search/ead_search.xqm: 98 added lines, 68 removed lines. Original line number Diff line number Diff line Loading @@ -3,35 +3,14 @@ xquery version "3.0"; module namespace max.plugin.ead_search = 'pddn/max/plugin/ead_search'; import module namespace max.config = 'pddn/max/config' at '../../rxq/config.xqm'; import module namespace max.html = 'pddn/max/html' at '../../rxq/html.xqm'; import module namespace max.cons = 'pddn/max/cons' at '../../rxq/cons.xqm'; import module namespace max = 'pddn/max' at '../../max.xq'; import module namespace max.util = 'pddn/max/util' at '../../rxq/util.xqm'; import module namespace max.i18n = 'pddn/max/i18n' at '../../rxq/i18n.xqm'; (:declare variable $max.plugin.search:PLUGIN_ID := "search";:) (:declare variable $max.plugin.search:ALL_TXT := "all_txt";:) (:declare variable $max.plugin.search:SELECTION := "selection";:) (:Plugin parameters - should be defined in MAX CONFIGURATION FILE:) (:declare variable $max.plugin.search:TAG_PARAMETER := "tag";:) (:declare variable $max.plugin.search:BACK_TO_TEXT_ID_PARAMETER := "backToTextID";:) declare variable $max.plugin.ead_search:INDEX_TAGS := <search> <tags> <tag name="corpname" attribute="role" value="scriptorium"/> <tag name="famname"/> <tag name="function"/> <tag name="genreform"/> <tag name="geogname"/> <tag name="occupation"/> <tag name="name"/> <tag name="persname"/> <tag name="subject"/> <tag name="title" attribute="type" value="subscriptio"/> </tags> <dates format="YYYY"></dates> </search>; declare %private function max.plugin.ead_search:getSearchConfiguration($project){ let $p:=max.config:getPluginParameterValue($project, 'ead_search', 'searchForm') return if($p) then $p else doc(max.util:maxHome()||'/plugins/ead_search/default_config.xml') }; declare %rest:GET Loading @@ -41,14 +20,23 @@ function max.plugin.ead_search:searchPage($project){ let $dbPath := max.config:getProjectDBPath($project) let $datalists := <section id="ead-search-section" class="ead-search"> { for $indexTag in $max.plugin.ead_search:INDEX_TAGS//tag for $indexTag in max.plugin.ead_search:getSearchConfiguration($project)//tag let $tagName := string($indexTag/@name) return if(count(collection($dbPath)//*[fn:local-name()=$tagName and @normal]) > 0) then <div> <label>{$tagName}s</label> <label>{string($indexTag/@label)}</label> <input type="text" class="ead-search-input" data-index="{$tagName}" id="{$tagName}-input" list="{$tagName}" multiple="multiple"></input> <div class="ead-search-popup-wrap"> <button onclick="window.eadSearch.popupIndex('{$tagName}')">📖</button> <div class="ead-search-popup" id="ead-search-popup-{$tagName}"> <div id="ead-search-popup-{$tagName}-alphabet" class="ead-search-popup-alphabet"> {for $l in 1 to 26 return <a>{codepoints-to-string(($l+64))}</a>} </div> <div id="ead-search-popup-{$tagName}-contents"></div> </div> </div> <ul id="{$tagName}-ul" class="ead-search-ul"> </ul> <datalist id="{$tagName}" class="ead-index-list"></datalist> Loading @@ -56,6 +44,7 @@ function max.plugin.ead_search:searchPage($project){ else () } <div id="ead-search-date-wrap"> <input type="checkbox" checked="checked" id="ead-search-date-cb"/> <label>Année de production</label> <!--<div> <input type="radio" name="ead-search-radio-date" checked="checked" value="in"/> Loading Loading @@ -95,7 +84,9 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s let $subqueries := for $index at $i in $indexes let $p := request:parameter($index||'[]') return let $or := string-join(for $n in $p return '@normal="'||$n||'" or contains(./text(),"'||$n||'")',' or ' ) (: chercher aussi ds les noeuds text() ? - commenté pour le moment:) (: 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 ' Loading @@ -110,14 +101,15 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s (: fn:string-join($subqueries,'') || ' ' || max.plugin.ead_search:buildDateQuery($project, $from, $to, $in)||' return $c':) (: return $fullQuery:) return try{ let $matches := max.plugin.ead_search:dateFilter( $from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) $project,$from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) let $html:= <ul>{ for $c in $matches return <li>{$c/*:did/*:unitid/text()}</li> return <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li> } </ul> Loading @@ -126,25 +118,50 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s <h4>XQuery = {$fullQuery} - (db = {$dbPath})</h4> {$html} </section> } catch * { max:max-error("Erreur code " || $err:code, $err:description ||'('||$fullQuery||')',$err:module, $err:line-number) } }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string, $format as xs:string){ try { switch ($format) case "YYYY" return xs:date($strDate||'-01-01') case "YYYY-MM" return xs:date($strDate||'-01') default return xs:date($strDate) } catch * { admin:write-log("Wrong date entry :" || $strDate || ' format = '|| $format), xs:date('0001-01-01') } }; declare %private function max.plugin.ead_search:dateFilter( $project as xs:string, $from as xs:string?, $to as xs:string?, $in as xs:string?, $matches){ let $dateFormat :=string(max.plugin.ead_search:getSearchConfiguration($project)//dates/@format) return if($from and $to) then max.plugin.ead_search:dateIntervalFilter($from, $to, $matches) else if($in) then () (:todo:) then max.plugin.ead_search:dateIntervalFilter($from, $to, $dateFormat, $matches) else if($in) then () (:todo:) else $matches }; declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:string, $to as xs:string, $matches as item()+){ let $fromDateTime := max.plugin.ead_search:parseDateParameter($from) let $toDateTime := max.plugin.ead_search:parseDateParameter($to) 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) let $toDateTime := max.plugin.ead_search:parseDateParameter($to,$dateFormat) return for $m in $matches Loading @@ -153,14 +170,14 @@ declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:s return if(contains($unitDate,'/')) then let $dates := tokenize($unitDate,'/') let $unitFrom := max.plugin.ead_search:parseDateParameter($dates[1]) let $unitTo:= max.plugin.ead_search:parseDateParameter($dates[2]) let $unitFrom := max.plugin.ead_search:parseDateParameter($dates[1], $dateFormat) let $unitTo:= max.plugin.ead_search:parseDateParameter($dates[2], $dateFormat) return if($fromDateTime <= $unitFrom and $toDateTime >= $unitTo) then $m else() else let $unitFrom := max.plugin.ead_search:parseDateParameter($unitDate) let $unitFrom := max.plugin.ead_search:parseDateParameter($unitDate, $dateFormat) return if($fromDateTime <= $unitFrom) then $m else () Loading @@ -176,49 +193,62 @@ declare function max.plugin.ead_search:buildSimpleDateQuery($project as xs:strin declare %rest:GET %output:method("json") %rest:query-param("q", "{$query}") %rest:query-param("page", "{$page}",1) %rest:path("/{$project}/search-index/{$tag}.json") function max.plugin.ead_search:searchIndexesList($project, $tag){ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer, $query as xs:string?){ let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, $page, $query) let $jsonStr := for $entry in $entries/* order by $entry/@normal where fn:string-length($entry/@normal) > 0 return '{"normal":"' || encode-for-uri($entry/@normal) || '", "tag":"' || $tag || '", "role" :"'||$entry/@role||'"}' return json:parse('{"entries" :[' || string-join($jsonStr,',') ||']}') }; declare %private function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:integer, $query as xs:string?){ let $dbPath := max.config:getProjectDBPath($project) let $tagParameters := $max.plugin.ead_search:INDEX_TAGS//tag[@name=$tag] let $tagParameters := max.plugin.ead_search:getSearchConfiguration($project)//tag[@name=$tag] (:select all nodes with required tag and attributes :) let $allEntries := for $elt in collection($dbPath)//*[fn:local-name()=$tag and @normal] where let $allEntries := for $elt in collection($dbPath)//*[fn:local-name()=$tag and @normal] where( if($tagParameters/@attribute) then $elt/@*[local-name(.)=string($tagParameters/@attribute) and string(.)=string($tagParameters/@value)] else true() ) and ( if($query) then $elt/@normal[contains(., $query)] else true() ) return $elt (:get their normal forms:) let $allNormals := for $e in $allEntries return string($e/@normal) let $allNormals := for $e in $allEntries return string($e/@normal) (:positions computing according to page number:) let $start := $page * 10 - 9 let $end := $start + 10 (:filter : avoid doublons:) let $entries := for $normal in distinct-values($allNormals) return <entries>{ for $normal at $pos in distinct-values($allNormals) order by $normal where $pos >= $start and $pos < $end return $allEntries[@normal=$normal][1] }</entries> let $jsonStr := for $entry in $entries order by $entry/@normal where fn:string-length($entry/@normal) > 0 return '{"normal":"' || encode-for-uri($entry/@normal) || '", "tag":"' || $tag || '", "role" :"'||$entry/@role||'"}' return json:parse('{"entries" :[' || string-join($jsonStr,',') ||']}') }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string){ let $format := string($max.plugin.ead_search:INDEX_TAGS/dates/@format) return try { switch ($format) case "YYYY" return xs:date($strDate||'-01-01') case "YYYY-MM" return xs:date($strDate||'-01') default return xs:date($strDate) } catch * { xs:date('0001-01-01') } }; (:test index:) Loading Loading
plugins/ead_search/default_config.xml 0 → 100644 +17 −0 Changes for plugins/ead_search/default_config.xml: 17 added lines, 0 removed lines. Original line number Diff line number Diff line <?xml version="1.0"?> <search> <tags> <tag name="corpname" label="corpname"/> <tag name="famname" label="famname"/> <tag name="function" label="Fonction"/> <tag name="genreform" label="genreform"/> <tag name="geogname" label="geogname"/> <tag name="occupation" label="Occupation"/> <tag name="name" label="Nom"/> <tag name="persname" label="Nom de personne"/> <tag name="subject" label="Sujet"/> <tag name="title" label="Titre"/> </tags> <dates format="YYYY"></dates> </search> No newline at end of file
plugins/ead_search/ead_search.css +21 −0 Changes for plugins/ead_search/ead_search.css: 21 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -44,3 +44,24 @@ #ead-search-results { border-top: 1px solid #888; } .ead-search-popup-wrap{ display: inline; position: relative; } .ead-search-popup{ display: none; position: absolute; top:0; left: 10px; border:1px solid #999; min-width:400px; background-color: white; z-index:10; font-size:0.8rem; } .ead-search-popup-alphabet{ text-align :center; } No newline at end of file
plugins/ead_search/ead_search.js +74 −9 Changes for plugins/ead_search/ead_search.js: 74 added lines, 9 removed lines. Original line number Diff line number Diff line Loading @@ -5,40 +5,103 @@ import {Plugin} from '../../core/ui/js/Plugin.js'; class EadSearchPlugin extends Plugin{ constructor(name) { super(name); this.withDatesFilter = document.getElementById('ead-search-date-cb').checked; this.filters = {} if(document.getElementById('ead-search-section')) this.fetchIndexLists(); if(document.getElementById('ead-search-section')){ document.getElementById('ead-search-date-cb').addEventListener('click', (evt) => { this.withDatesFilter = evt.target.checked; if(!this.withDatesFilter){ document.getElementById('ead-search-date-from').setAttribute('disabled', true); document.getElementById('ead-search-date-to').setAttribute('disabled', true); } else{ document.getElementById('ead-search-date-from').removeAttribute('disabled'); document.getElementById('ead-search-date-to').removeAttribute('disabled') } }) this.bindIndexAutocompletes(); } // this.fetchIndexLists(); } fetchIndexLists(){ let indexList = document.querySelectorAll('.ead-search-input') bindIndexAutocompletes(){ let indexList = document.querySelectorAll('.ead-search-input'); indexList.forEach((e) => { e.addEventListener('input', (evt) => { let indexName = e.dataset.index; fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { let q = e.value; if(q.trim() !==''){ let url = baseURI + projectId + '/search-index/'+indexName+'.json?q='+ q ; let datalist = document.getElementById(indexName); fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { datalist.innerHTML = ''; let entries = json.entries entries.forEach((entry) => { let option = document.createElement('option'); option.value = decodeURIComponent(entry.normal); datalist.appendChild(option); }) document.getElementById(indexName+'-input').addEventListener('input', (event) => { //alert(event.target.value) if(event.inputType === 'insertReplacementText'){ this.addIndexFilter(indexName, event.target.value) } }); }) } }) }) } popupIndex(tagName){ let popupElt = document.getElementById('ead-search-popup-'+tagName); let popupContent = document.getElementById('ead-search-popup-'+tagName+"-contents"); popupContent.innerHTML = ''; let url = baseURI + projectId + '/search-index/'+tagName+'.json'; let list = document.createElement('ol'); fetch(baseURI + projectId + '/search-index/'+tagName+'.json').then((res) => res.json()).then( (json) => { let entries = json.entries entries.forEach((entry) => { let li = document.createElement('li'); li.innerHTML = decodeURIComponent(entry.normal); list.appendChild(li); }) }) popupContent.appendChild(list); popupElt.style.display='block'; } // // fetchIndexLists(){ // let indexList = document.querySelectorAll('.ead-search-input') // // indexList.forEach((e) => { // let indexName = e.dataset.index; // fetch(baseURI + projectId + '/search-index/'+indexName+'.json').then((res) => res.json()).then( (json) => { // let datalist = document.getElementById(indexName); // let entries = json.entries // entries.forEach((entry) => { // let option = document.createElement('option'); // option.value = decodeURIComponent(entry.normal); // datalist.appendChild(option); // // }) // // document.getElementById(indexName+'-input').addEventListener('input', (event) => { // //alert(event.target.value) // if(event.inputType === 'insertReplacementText'){ // this.addIndexFilter(indexName, event.target.value) // } // // }); // }) // // // }) // } addIndexFilter(filterType, filterValue){ if(filterValue.trim() === '') Loading Loading @@ -78,6 +141,7 @@ class EadSearchPlugin extends Plugin{ query = baseURI + projectId + '/' +query; if(this.withDatesFilter){ //date let dateMode = document.querySelector('input[name=ead-search-radio-date]:checked').value if(dateMode === 'interval'){ Loading @@ -90,6 +154,7 @@ class EadSearchPlugin extends Plugin{ let dateIn = document.getElementById('ead-search-date-in').value; query+=(!filtered ? "?" : "&") + "in="+dateIn } } fetch(query).then(res => res.text()).then(text => { document.getElementById('ead-search-results').innerHTML = text Loading
plugins/ead_search/ead_search.xqm +98 −68 Changes for plugins/ead_search/ead_search.xqm: 98 added lines, 68 removed lines. Original line number Diff line number Diff line Loading @@ -3,35 +3,14 @@ xquery version "3.0"; module namespace max.plugin.ead_search = 'pddn/max/plugin/ead_search'; import module namespace max.config = 'pddn/max/config' at '../../rxq/config.xqm'; import module namespace max.html = 'pddn/max/html' at '../../rxq/html.xqm'; import module namespace max.cons = 'pddn/max/cons' at '../../rxq/cons.xqm'; import module namespace max = 'pddn/max' at '../../max.xq'; import module namespace max.util = 'pddn/max/util' at '../../rxq/util.xqm'; import module namespace max.i18n = 'pddn/max/i18n' at '../../rxq/i18n.xqm'; (:declare variable $max.plugin.search:PLUGIN_ID := "search";:) (:declare variable $max.plugin.search:ALL_TXT := "all_txt";:) (:declare variable $max.plugin.search:SELECTION := "selection";:) (:Plugin parameters - should be defined in MAX CONFIGURATION FILE:) (:declare variable $max.plugin.search:TAG_PARAMETER := "tag";:) (:declare variable $max.plugin.search:BACK_TO_TEXT_ID_PARAMETER := "backToTextID";:) declare variable $max.plugin.ead_search:INDEX_TAGS := <search> <tags> <tag name="corpname" attribute="role" value="scriptorium"/> <tag name="famname"/> <tag name="function"/> <tag name="genreform"/> <tag name="geogname"/> <tag name="occupation"/> <tag name="name"/> <tag name="persname"/> <tag name="subject"/> <tag name="title" attribute="type" value="subscriptio"/> </tags> <dates format="YYYY"></dates> </search>; declare %private function max.plugin.ead_search:getSearchConfiguration($project){ let $p:=max.config:getPluginParameterValue($project, 'ead_search', 'searchForm') return if($p) then $p else doc(max.util:maxHome()||'/plugins/ead_search/default_config.xml') }; declare %rest:GET Loading @@ -41,14 +20,23 @@ function max.plugin.ead_search:searchPage($project){ let $dbPath := max.config:getProjectDBPath($project) let $datalists := <section id="ead-search-section" class="ead-search"> { for $indexTag in $max.plugin.ead_search:INDEX_TAGS//tag for $indexTag in max.plugin.ead_search:getSearchConfiguration($project)//tag let $tagName := string($indexTag/@name) return if(count(collection($dbPath)//*[fn:local-name()=$tagName and @normal]) > 0) then <div> <label>{$tagName}s</label> <label>{string($indexTag/@label)}</label> <input type="text" class="ead-search-input" data-index="{$tagName}" id="{$tagName}-input" list="{$tagName}" multiple="multiple"></input> <div class="ead-search-popup-wrap"> <button onclick="window.eadSearch.popupIndex('{$tagName}')">📖</button> <div class="ead-search-popup" id="ead-search-popup-{$tagName}"> <div id="ead-search-popup-{$tagName}-alphabet" class="ead-search-popup-alphabet"> {for $l in 1 to 26 return <a>{codepoints-to-string(($l+64))}</a>} </div> <div id="ead-search-popup-{$tagName}-contents"></div> </div> </div> <ul id="{$tagName}-ul" class="ead-search-ul"> </ul> <datalist id="{$tagName}" class="ead-index-list"></datalist> Loading @@ -56,6 +44,7 @@ function max.plugin.ead_search:searchPage($project){ else () } <div id="ead-search-date-wrap"> <input type="checkbox" checked="checked" id="ead-search-date-cb"/> <label>Année de production</label> <!--<div> <input type="radio" name="ead-search-radio-date" checked="checked" value="in"/> Loading Loading @@ -95,7 +84,9 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s let $subqueries := for $index at $i in $indexes let $p := request:parameter($index||'[]') return let $or := string-join(for $n in $p return '@normal="'||$n||'" or contains(./text(),"'||$n||'")',' or ' ) (: chercher aussi ds les noeuds text() ? - commenté pour le moment:) (: 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 ' Loading @@ -110,14 +101,15 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s (: fn:string-join($subqueries,'') || ' ' || max.plugin.ead_search:buildDateQuery($project, $from, $to, $in)||' return $c':) (: return $fullQuery:) return try{ let $matches := max.plugin.ead_search:dateFilter( $from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) $project,$from, $to, $in, xquery:eval($fullQuery, map { '': db:open($dbPath) })) let $html:= <ul>{ for $c in $matches return <li>{$c/*:did/*:unitid/text()}</li> return <li>{$c/*:did/*:unitid/text()} | <em>{string($c/*:did/*:unitdate[1]/@normal)}</em></li> } </ul> Loading @@ -126,25 +118,50 @@ function max.plugin.ead_search:runSearch($project as xs:string, $indexes as xs:s <h4>XQuery = {$fullQuery} - (db = {$dbPath})</h4> {$html} </section> } catch * { max:max-error("Erreur code " || $err:code, $err:description ||'('||$fullQuery||')',$err:module, $err:line-number) } }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string, $format as xs:string){ try { switch ($format) case "YYYY" return xs:date($strDate||'-01-01') case "YYYY-MM" return xs:date($strDate||'-01') default return xs:date($strDate) } catch * { admin:write-log("Wrong date entry :" || $strDate || ' format = '|| $format), xs:date('0001-01-01') } }; declare %private function max.plugin.ead_search:dateFilter( $project as xs:string, $from as xs:string?, $to as xs:string?, $in as xs:string?, $matches){ let $dateFormat :=string(max.plugin.ead_search:getSearchConfiguration($project)//dates/@format) return if($from and $to) then max.plugin.ead_search:dateIntervalFilter($from, $to, $matches) else if($in) then () (:todo:) then max.plugin.ead_search:dateIntervalFilter($from, $to, $dateFormat, $matches) else if($in) then () (:todo:) else $matches }; declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:string, $to as xs:string, $matches as item()+){ let $fromDateTime := max.plugin.ead_search:parseDateParameter($from) let $toDateTime := max.plugin.ead_search:parseDateParameter($to) 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) let $toDateTime := max.plugin.ead_search:parseDateParameter($to,$dateFormat) return for $m in $matches Loading @@ -153,14 +170,14 @@ declare %private function max.plugin.ead_search:dateIntervalFilter($from as xs:s return if(contains($unitDate,'/')) then let $dates := tokenize($unitDate,'/') let $unitFrom := max.plugin.ead_search:parseDateParameter($dates[1]) let $unitTo:= max.plugin.ead_search:parseDateParameter($dates[2]) let $unitFrom := max.plugin.ead_search:parseDateParameter($dates[1], $dateFormat) let $unitTo:= max.plugin.ead_search:parseDateParameter($dates[2], $dateFormat) return if($fromDateTime <= $unitFrom and $toDateTime >= $unitTo) then $m else() else let $unitFrom := max.plugin.ead_search:parseDateParameter($unitDate) let $unitFrom := max.plugin.ead_search:parseDateParameter($unitDate, $dateFormat) return if($fromDateTime <= $unitFrom) then $m else () Loading @@ -176,49 +193,62 @@ declare function max.plugin.ead_search:buildSimpleDateQuery($project as xs:strin declare %rest:GET %output:method("json") %rest:query-param("q", "{$query}") %rest:query-param("page", "{$page}",1) %rest:path("/{$project}/search-index/{$tag}.json") function max.plugin.ead_search:searchIndexesList($project, $tag){ function max.plugin.ead_search:searchIndexesListAsJSON($project, $tag, $page as xs:integer, $query as xs:string?){ let $entries := max.plugin.ead_search:searchIndexesList($project, $tag, $page, $query) let $jsonStr := for $entry in $entries/* order by $entry/@normal where fn:string-length($entry/@normal) > 0 return '{"normal":"' || encode-for-uri($entry/@normal) || '", "tag":"' || $tag || '", "role" :"'||$entry/@role||'"}' return json:parse('{"entries" :[' || string-join($jsonStr,',') ||']}') }; declare %private function max.plugin.ead_search:searchIndexesList($project, $tag, $page as xs:integer, $query as xs:string?){ let $dbPath := max.config:getProjectDBPath($project) let $tagParameters := $max.plugin.ead_search:INDEX_TAGS//tag[@name=$tag] let $tagParameters := max.plugin.ead_search:getSearchConfiguration($project)//tag[@name=$tag] (:select all nodes with required tag and attributes :) let $allEntries := for $elt in collection($dbPath)//*[fn:local-name()=$tag and @normal] where let $allEntries := for $elt in collection($dbPath)//*[fn:local-name()=$tag and @normal] where( if($tagParameters/@attribute) then $elt/@*[local-name(.)=string($tagParameters/@attribute) and string(.)=string($tagParameters/@value)] else true() ) and ( if($query) then $elt/@normal[contains(., $query)] else true() ) return $elt (:get their normal forms:) let $allNormals := for $e in $allEntries return string($e/@normal) let $allNormals := for $e in $allEntries return string($e/@normal) (:positions computing according to page number:) let $start := $page * 10 - 9 let $end := $start + 10 (:filter : avoid doublons:) let $entries := for $normal in distinct-values($allNormals) return <entries>{ for $normal at $pos in distinct-values($allNormals) order by $normal where $pos >= $start and $pos < $end return $allEntries[@normal=$normal][1] }</entries> let $jsonStr := for $entry in $entries order by $entry/@normal where fn:string-length($entry/@normal) > 0 return '{"normal":"' || encode-for-uri($entry/@normal) || '", "tag":"' || $tag || '", "role" :"'||$entry/@role||'"}' return json:parse('{"entries" :[' || string-join($jsonStr,',') ||']}') }; declare %private function max.plugin.ead_search:parseDateParameter($strDate as xs:string){ let $format := string($max.plugin.ead_search:INDEX_TAGS/dates/@format) return try { switch ($format) case "YYYY" return xs:date($strDate||'-01-01') case "YYYY-MM" return xs:date($strDate||'-01') default return xs:date($strDate) } catch * { xs:date('0001-01-01') } }; (:test index:) Loading