Core_View_DocumentNavigatorWindow.js
import { DocumentProvider } from '../ViewModel/DocumentProvider';
import { Document } from '../Model/Document';
import { DocumentSearchFilter } from '../ViewModel/DocumentSearchFilter';
import {
createDateIntervalInput,
createDisplayable,
createLabelInput,
} from '@ud-viz/utils_browser';
/**
* @class Represents the navigator window for the documents. It contains the filters on
* the fields of a document.
*/
export class DocumentNavigatorWindow {
constructor(provider) {
this.provider = provider;
/** @type {HTMLElement} */
this.domElement = null;
/** @type {HTMLElement} */
this.documentListContainer = null;
/** @type {HTMLElement} */
this.docCountElement = null;
/** @type {HTMLElement} */
this.documentListElement = null;
/** @type {HTMLElement} */
this.displayableFiltersContainer = null;
/** @type {HTMLElement} */
this.inputFormElement = null;
/** @type {HTMLElement} */
this.inputKeywordsElement = null;
/** @type {HTMLElement} */
this.inputPubDateStartElement = null;
/** @type {HTMLElement} */
this.inputPubDateEndElement = null;
/** @type {HTMLElement} */
this.inputRefDateStartElement = null;
/** @type {HTMLElement} */
this.inputRefDateEndElement = null;
/** @type {HTMLElement} */
this.inputSourceElement = null;
/** @type {HTMLElement} */
this.inputRightsHolderElement = null;
/** @type {HTMLElement} */
this.clearButtonElement = null;
this.initHtml();
/**
* The filter corresponding to the research fields.
*
* @type {DocumentSearchFilter}
*/
this.searchFilter = new DocumentSearchFilter();
// init callbacks
this.inputFormElement.onsubmit = () => {
this.search();
return false;
};
this.clearButtonElement.onclick = () => {
this.clear();
};
this.provider.addFilter(this.searchFilter);
this.provider.addEventListener(
DocumentProvider.EVENT_FILTERED_DOCS_UPDATED,
(data) => this._onFilteredDocumentsUpdate(data.documents)
);
this.provider.addEventListener(
DocumentProvider.EVENT_DISPLAYED_DOC_CHANGED,
(data) => this._onDisplayedDocumentChange(data.document)
);
}
initHtml() {
this.domElement = document.createElement('div');
this.domElement.classList.add('root-document-navigator');
{
// document list container
this.documentListContainer = document.createElement('div');
this.domElement.appendChild(this.documentListContainer);
{
// label document count
const labelDocCount = document.createElement('h3');
labelDocCount.innerText = 'Document(s)';
this.documentListContainer.appendChild(labelDocCount);
{
this.docCountElement = document.createElement('span');
labelDocCount.appendChild(this.docCountElement);
}
// list
const listContainer = document.createElement('div');
listContainer.classList.add('documents-list');
this.documentListContainer.appendChild(listContainer);
{
this.documentListElement = document.createElement('ul');
listContainer.appendChild(this.documentListElement);
}
}
// filter displayable element
const displayableFilters = createDisplayable('Filters');
this.domElement.appendChild(displayableFilters.parent);
this.displayableFiltersContainer = displayableFilters.container;
{
const displayableAttributes = createDisplayable('Attributes');
this.displayableFiltersContainer.appendChild(
displayableAttributes.parent
);
this.inputFormElement = displayableAttributes.container;
{
// keywords
const labelInputKeywords = createLabelInput('Keywords', 'text');
displayableAttributes.container.appendChild(
labelInputKeywords.parent
);
this.inputKeywordsElement = labelInputKeywords.input;
// publication date
const dateIntervalInputPub =
createDateIntervalInput('Publication Date');
displayableAttributes.container.appendChild(
dateIntervalInputPub.parent
);
this.inputPubDateStartElement = dateIntervalInputPub.inputStartDate;
this.inputPubDateEndElement = dateIntervalInputPub.inputEndDate;
// ref date
const dateIntervalInputRef = createDateIntervalInput('Refering Date');
displayableAttributes.container.appendChild(
dateIntervalInputRef.parent
);
this.inputRefDateStartElement = dateIntervalInputRef.inputStartDate;
this.inputRefDateEndElement = dateIntervalInputRef.inputEndDate;
// source
const labelInputSource = createLabelInput('Source', 'text');
displayableAttributes.container.appendChild(labelInputSource.parent);
this.inputSourceElement = labelInputSource.input;
// right holder
const labelInputRightsHolder = createLabelInput(
'Rights holder',
'text'
);
displayableAttributes.container.appendChild(
labelInputRightsHolder.parent
);
this.inputRightsHolderElement = labelInputRightsHolder.input;
// clear button
this.clearButtonElement = document.createElement('button');
}
}
}
}
// ////////////////////////////
// /// DOCUMENT UPDATE TRIGGERS
/**
* Callback triggered when the list of filtered documents changes.
*
* @private
* @param {Array<Document>} documents The new array of filtered documents.
*/
_onFilteredDocumentsUpdate(documents) {
const list = this.documentListElement;
list.innerText = '';
for (const doc of documents) {
const item = document.createElement('li');
item.innerHTML = /* html*/ `
<div class='doc-title'>${doc.title}</div>
<div class='doc-info'>Refering ${new Date(
doc.refDate
).toLocaleDateString()}</div>
`;
item.classList.add('navigator-result-doc');
item.onclick = () => {
this.provider.setDisplayedDocument(doc);
};
list.appendChild(item);
}
this.docCountElement.innerText = documents.length;
}
/**
* Callback triggered when the displayed document changes.
*
* @private
* @param {Document} document The new displayed documents.
*/
_onDisplayedDocumentChange(document) {
const previouslySelected =
this.documentListElement.querySelector('.document-selected');
if (previouslySelected) {
previouslySelected.classList.remove('document-selected');
}
if (document) {
const newIndex = this.provider.getDisplayedDocumentIndex();
const newSelected = this.documentListElement.querySelector(
`li:nth-child(${newIndex + 1})`
);
newSelected.classList.add('document-selected');
}
}
// //////////////////////
// /// SEARCH AND FILTERS
/**
* Event on the 'search' button click.
*/
async search() {
const keywords = this.inputKeywordsElement.value
.split(/[ ,;]/)
.filter((k) => k !== '')
.map((k) => k.toLowerCase());
this.searchFilter.keywords = keywords;
const source = this.inputSourceElement.value.toLowerCase();
this.searchFilter.source = source !== '' ? source : undefined;
const rightsHolder = this.inputRightsHolderElement.value.toLowerCase();
this.searchFilter.rightsHolder =
rightsHolder !== '' ? rightsHolder : undefined;
const pubStartDate = this.inputPubDateStartElement.value;
this.searchFilter.pubStartDate = pubStartDate
? new Date(pubStartDate)
: undefined;
const pubEndDate = this.inputPubDateEndElement.value;
this.searchFilter.pubEndDate = pubEndDate
? new Date(pubEndDate)
: undefined;
const refStartDate = this.inputRefDateStartElement.value;
this.searchFilter.refStartDate = refStartDate
? new Date(refStartDate)
: undefined;
const refEndDate = this.inputRefDateEndElement.value;
this.searchFilter.refEndDate = refEndDate
? new Date(refEndDate)
: undefined;
this.provider.refreshDocumentList();
}
/**
* Clears the research fields.
*/
clear() {
this.inputSourceElement.value = '';
this.inputRightsHolderElement.value = '';
this.inputKeywordsElement.value = '';
this.inputRefDateEndElement.value = '';
this.inputRefDateStartElement.value = '';
this.inputPubDateEndElement.value = '';
this.inputPubDateStartElement.value = '';
this.provider.refreshDocumentList();
}
}