From 9031ca5845c8f48a34798e2f90e6cd6f7e0c65b5 Mon Sep 17 00:00:00 2001 From: Stephan Porada Date: Wed, 15 Apr 2020 14:55:29 +0200 Subject: [PATCH] New context options --- app/corpora/events.py | 2 +- app/corpora/forms.py | 18 +--- app/static/js/nopaque.lists.js | 105 ++++++++++++++----- app/templates/corpora/analyse_corpus.html.j2 | 88 +++++++++------- 4 files changed, 133 insertions(+), 80 deletions(-) diff --git a/app/corpora/events.py b/app/corpora/events.py index bec50125..1fc3fb5d 100644 --- a/app/corpora/events.py +++ b/app/corpora/events.py @@ -93,7 +93,7 @@ def corpus_analysis_inspect_match(payload): try: corpus = client.corpora.get('CORPUS') s = corpus.structural_attributes.get('s') - payload = s.export(payload['first_cpos'], payload['last_cpos'], context=3) + payload = s.export(payload['first_cpos'], payload['last_cpos'], context=10) payload['cpos_ranges'] = True except cqi.errors.CQiException as e: payload = {'code': e.code, 'desc': e.description, 'msg': e.name} diff --git a/app/corpora/forms.py b/app/corpora/forms.py index 82745e76..99f6b733 100644 --- a/app/corpora/forms.py +++ b/app/corpora/forms.py @@ -1,7 +1,7 @@ from flask_wtf import FlaskForm from wtforms import (BooleanField, FileField, StringField, SubmitField, ValidationError, IntegerField, SelectField) -from wtforms.validators import DataRequired, Length +from wtforms.validators import DataRequired, Length, NumberRange class AddCorpusFileForm(FlaskForm): @@ -88,19 +88,9 @@ class DisplayOptionsForm(FlaskForm): class InspectDisplayOptionsForm(FlaskForm): expert_mode_inspect = BooleanField('Expert mode') highlight_sentences = BooleanField('Highlight sentences') - context_sentences = SelectField('Context sentences', - choices=[('', 'Choose your option'), - ('1', '1'), - ('2', '2'), - ('3', '3'), - ('4', '4'), - ('5', '5'), - ('6', '6'), - ('7', '7'), - ('8', '8'), - ('9', '9'), - ('10', '10')], - default=3) + context_sentences = IntegerField('Context sentences', + validators=[NumberRange(min=0, max=10)], + default=3) class QueryDownloadForm(FlaskForm): diff --git a/app/static/js/nopaque.lists.js b/app/static/js/nopaque.lists.js index 8cfda3c9..009a5bf9 100644 --- a/app/static/js/nopaque.lists.js +++ b/app/static/js/nopaque.lists.js @@ -177,62 +177,111 @@ class ResultsList extends List { ); } + HTMLTStroElement(htmlStr) { + // https://stackoverflow.com/questions/494143/creating-a-new-dom-element-from-an-html-string-using-built-in-dom-methods-or-pro/35385518#35385518 + let template = document.createElement("template"); + htmlStr = htmlStr.trim(); + template.innerHTML = htmlStr; + return template.content.firstChild; + } + showMatchContext(response) { + this.contextData; let c; - let contextData; let contextModalLoading; let contextModalReady; let contextResultsElement; let expertModeSwitchElement; let lc; + let modalTokenElements; let partElement; let rc; let token; - let tokenElement; - let tokenElements; - contextData = response.payload; + let tokenHTMLArray; + let uniqueS; + let htmlTokenStr; + let tokenHTMlElement; + + this.contextData = response.payload; contextResultsElement = document.getElementById("context-results"); expertModeSwitchElement = document.getElementById("display-options-form-expert_mode"); + uniqueS = new Set(); // check if cpos ranges are used or not - if (contextData.cpos_ranges == true) { + if (this.contextData.cpos_ranges == true) { // python range like function from MDN // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Sequence_generator_(range) const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => start + (i * step)); - lc = range(contextData.match.lc[0], contextData.match.lc[1], 1) - c = range(contextData.match.c[0], contextData.match.c[1], 1) - rc = range(contextData.match.rc[0], contextData.match.rc[1], 1) + lc = range(this.contextData.match.lc[0], this.contextData.match.lc[1], 1) + c = range(this.contextData.match.c[0], this.contextData.match.c[1], 1) + rc = range(this.contextData.match.rc[0], this.contextData.match.rc[1], 1) } else { - lc = contextData.match.lc; - c = contextData.match.c; - rc = contextData.match.rc; + lc = this.contextData.match.lc; + c = this.contextData.match.c; + rc = this.contextData.match.rc; } // create sentence strings as tokens - partElement = document.createElement("p"); + tokenHTMLArray = []; for (let cpos of lc) { - token = contextData.cpos_lookup[cpos]; - partElement.insertAdjacentHTML("beforeend", - `${token.word} `); - contextResultsElement.append(partElement); + token = this.contextData.cpos_lookup[cpos]; + uniqueS.add(token.s) + htmlTokenStr = `` + + `${token.word}` + + ``; + tokenHTMlElement = this.HTMLTStroElement(htmlTokenStr) + tokenHTMLArray.push(tokenHTMlElement); } for (let cpos of c) { - token = contextData.cpos_lookup[cpos]; - partElement.insertAdjacentHTML("beforeend", - `${token.word} `); - contextResultsElement.append(partElement); + token = this.contextData.cpos_lookup[cpos]; + uniqueS.add(token.s) + htmlTokenStr = `` + + `${token.word}` + + ``; + tokenHTMlElement = this.HTMLTStroElement(htmlTokenStr) + tokenHTMLArray.push(tokenHTMlElement); } for (let cpos of rc) { - token = contextData.cpos_lookup[cpos]; - partElement.insertAdjacentHTML("beforeend", - `${token.word} `); - contextResultsElement.append(partElement); + token = this.contextData.cpos_lookup[cpos]; + uniqueS.add(token.s) + htmlTokenStr = `` + + `${token.word}` + + ``; + tokenHTMlElement = this.HTMLTStroElement(htmlTokenStr) + tokenHTMLArray.push(tokenHTMlElement); } + console.log(tokenHTMLArray); + console.log(uniqueS); + + partElement = document.createElement("p"); + for (let sId of uniqueS) { + let htmlSentence = `
`; + let sentenceElement = this.HTMLTStroElement(htmlSentence); + for (let tokenElement of tokenHTMLArray) { + if (tokenElement.dataset.sid == sId) { + sentenceElement.appendChild(tokenElement); + sentenceElement.insertAdjacentHTML("beforeend", ` `); + } else { + continue; + } + } + partElement.appendChild(sentenceElement); + } + contextResultsElement.appendChild(partElement); + if (expertModeSwitchElement.checked) { - tokenElements = partElement.getElementsByClassName("token"); this.expertModeOn(); } } + changeSentenceContext(sValue) { + } + // ###### Display options changing live how the matches are being displayed ###### // Event function that changes the shown hits per page. @@ -309,6 +358,9 @@ class ResultsList extends List { // console.log("Create Tooltip on mouseover."); let token; token = results.resultsJSON.cpos_lookup[event.target.dataset.cpos]; + if (!token) { + token = this.contextData.cpos_lookup[event.target.dataset.cpos]; + } this.addToolTipToTokenElement(event.target, token); } @@ -321,7 +373,6 @@ class ResultsList extends List { expertModeOn() { // console.log("Expert mode is on."); - let token; this.currentExpertTokenElements = document.getElementsByClassName("token"); this.tooltipEventCreateBind = this.tooltipEventCreate.bind(this); this.tooltipEventDestroyBind = this.tooltipEventDestroy.bind(this); diff --git a/app/templates/corpora/analyse_corpus.html.j2 b/app/templates/corpora/analyse_corpus.html.j2 index bbd9fa31..02f30024 100644 --- a/app/templates/corpora/analyse_corpus.html.j2 +++ b/app/templates/corpora/analyse_corpus.html.j2 @@ -201,38 +201,46 @@

Match context

-
Display options
-
-
-

Expert Mode

-
-
-
- +
+
Display options
+
+
+

{{ inspect_display_options_form.expert_mode_inspect.label.text }}

+
+
+
+ +
+
+
+

{{ inspect_display_options_form.highlight_sentences.label.text }}

+
+
+
+ +
+
+
+

Nr. of sentences around the match

+
+
+
+

+ +

+
-
-

Highlight sentences

-
-
-
- -
-
-
-
- format_list_numbered - {{ inspect_display_options_form.context_sentences() }} - {{ inspect_display_options_form.context_sentences.label }} -
-
-
+
@@ -257,16 +265,20 @@ var collapsibleElements; // All collapsibleElements on this page var collapsibleElements; // all collapsibles on site var contextModal; // Modal to open on inspect for further match context + var contextPerItemElement; + var contextSentencesElement; var displayOptionsData; // Getting form data from display options var displayOptionsFormElement; // Form holding the display informations var downloadResultsJSONElement; // button for downloading results as JSON var expertModeSwitchElement; // Expert mode switch Element var exportModal; // Download options modal var firstPageElement; // first page element of resultsList pagination + var hitsPerPageInputElement; var initDisplay; // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined var initDisplayElement; // Element for initialization using initDisplay var initModal; var matchCountElement; // Total nr. of matches will be displayed in this element + var paginationElements; var progress; // global progress value var queryDisplay; // CorpusAnalysisDisplay object first undfined on DOMContentLoaded defined var queryDisplayElement; // Element for initialization using queryDisplay @@ -282,20 +294,19 @@ var resultsListOptions; // specifies ResultsList options var textLookupCountElement // Nr of texts the matches occured in will be shown in this element var xpath; // xpath to grab first resultsList page pagination element - var hitsPerPageInputElement; - var paginationElements; - var contextPerItemElement; // ###### Initialize variables ###### client = undefined; collapsibleElements = document.querySelector('.collapsible.expandable'); contextModal = document.getElementById("context-modal"); + contextSentencesElement = document.getElementById("context-sentences"); displayOptionsFormElement = document.getElementById("display-options-form"); expertModeSwitchElement = document.getElementById("display-options-form-expert_mode"); exportModal = document.getElementById("query-results-download-modal"); initDisplay = undefined; initDisplayElement = document.getElementById("init-display"); matchCountElement = document.getElementById("match-count"); + paginationElements = document.getElementsByClassName("pagination"); queryDisplay = undefined; queryDisplayElement = document.getElementById("query-display"); queryFormElement = document.getElementById("query-form"); @@ -305,7 +316,6 @@ queryResultsUserFeedbackElement = document.getElementById("query-results-user-feedback"); receivedMatchCountElement = document.getElementById("received-match-count"); textLookupCountElement = document.getElementById("text-lookup-count"); - paginationElements = document.getElementsByClassName("pagination"); // ###### js list options and intialization ###### displayOptionsData = ResultsList.getDisplayOptions(displayOptionsFormElement); @@ -388,6 +398,12 @@ contextPerItemElement = document.getElementById("display-options-form-result_context"); contextPerItemElement.onchange = results.resultsList.changeContext; + // live update of context sentences in inspect modal + contextSentencesElement.onchange = (event) => { + let sValue = event.target.value; + console.log(sValue); + } + // eventListener if pagination is used to apply new context size to new page // and also activate inspect match if progress is 100 for (let element of paginationElements) { @@ -395,10 +411,6 @@ element.addEventListener("click", results.resultsList.activateInspect); } - // epxert mode table view - // TODO: Redo this - // - This replicates itself on expertModeSwitchElement use - // - Replication should be fixed expertModeSwitchElement.addEventListener("change", (event) => { if (event.target.checked) { results.resultsList.expertModeOn();