Skip to content

Commit c310416

Browse files
committed
[academic_query] add DnD and search
SQUASHED: AUTO-COMMIT-src-components-widgets-academic-query.js,AUTO-COMMIT-src-components-widgets-academic-subquery.html,AUTO-COMMIT-src-components-widgets-academic-subquery.js,
1 parent d0ceae7 commit c310416

File tree

3 files changed

+107
-52
lines changed

3 files changed

+107
-52
lines changed

src/components/widgets/academic-query.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ export default class AcademicQuery extends Morph {
6363
}
6464
var input = <input id="queryInput" value={this.textContent} style="width: 300px"></input>;
6565
var updateButton = <button click={() => this.setQuery(input.value)}>update</button>;
66+
var searchButton = <button click={() => lively.openBrowser("academic://expr:" + this.textContent + "?count=100")}>search</button>;
6667

6768
pane.innerHTML = ""
6869
pane.appendChild(<div>
69-
{input} {updateButton}
70+
{input} {updateButton} {searchButton}
7071
{queryView}
7172
</div>);
7273
}

src/components/widgets/academic-subquery.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,16 @@
3838
font-size: 10px
3939
}
4040

41-
/*.tooltip .tooltiptext::after {
42-
content: "";
43-
position: absolute;
44-
top: 100%;
45-
left: 50%;
46-
margin-left: -5px;
47-
border-width: 5px;
48-
border-style: solid;
49-
border-color: #555 transparent transparent transparent;
50-
}*/
41+
.dropTarget {
42+
border: 3px solid white;
43+
}
44+
.dropTarget.over {
45+
border: 3px dotted #666;
46+
}
47+
48+
.queryPart:blank {
49+
background: pink;
50+
}
5151

5252
.hover:hover .hovercontent {
5353
visibility: visible;

src/components/widgets/academic-subquery.js

Lines changed: 95 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,10 @@ export default class AcademicSubquery extends Morph {
162162
observer = new MutationObserver((mutations) => {
163163
mutations.forEach(mutation => {
164164
//lively.notify("observation", mutation.type)
165-
165+
clearTimeout(timeout);
166166
timeout = setTimeout(async () => {
167167
if (mutation.type == "characterData") {
168+
lively.notify("THIS", this)
168169
this.textContent = await this.viewToQuery();
169170
}
170171
if (mutation.type == "childList") {
@@ -193,10 +194,10 @@ export default class AcademicSubquery extends Morph {
193194

194195
// TODO: falls ich das umbaue, sodass eine subquery einfach als
195196
// html Element in updateView erstellt wird, muss das hier auch da rein
196-
this.addEventListener('dragstart', (evt) => this.onDragStart(evt))
197-
this.addEventListener('dragend', (evt) => this.onDragEnd(evt))
198-
this.addEventListener('dragover', (evt) => this.onDragOver(evt))
199-
this.addEventListener('drop', (evt) => this.onDrop(evt))
197+
// this.addEventListener('dragstart', (evt) => this.onDragStart(evt))
198+
// this.addEventListener('dragend', (evt) => this.onDragEnd(evt))
199+
// this.addEventListener('dragover', (evt) => this.onDragOver(evt))
200+
// this.addEventListener('drop', (evt) => this.onDrop(evt))
200201

201202
this.style.draggable = 'true';
202203
// "drag",
@@ -209,26 +210,75 @@ export default class AcademicSubquery extends Morph {
209210
}
210211

211212
onDragStart(event) {
212-
event.dataTransfer.setData("element", event.target.id);
213+
//event.dataTransfer.setData("element", event.target.id);
214+
this.style.opacity = '0.4';
215+
this.style.color = "black";
216+
217+
// var id = lively.ensureID(this)
218+
// this.id = id
219+
220+
event.dataTransfer.effectAllowed = 'move';
221+
event.dataTransfer.setData('text/html', this.innerHTML);
222+
//event.dataTransfer.setData("application/lively4id", id);
213223
}
214224

215225
onDragEnd(event) {
216-
event.dataTransfer.setData("element", event.target.id);
226+
//event.dataTransfer.setData("element", event.target.id);
227+
this.style.opacity = '1.0';
217228
}
218229

219230
onDragOver(event) {
220-
event.dataTransfer.setData("element", event.target.id);
231+
//event.dataTransfer.setData("element", event.target.id);
232+
// the next line should not be neccessary with onDragEnter()...
233+
this.classList.add('over');
234+
//this.style.border = '3px dotted #666';
221235
}
222236

223237
onDrop(event) {
238+
//if (this.dragStart !== this) {
239+
//var id = event.dataTransfer.getData("application/lively4id")
240+
//var el = lively.query(this, "#"+id);
241+
//lively.notify("ELEMENT", el);
242+
this.innerHTML = event.dataTransfer.getData("text/html");
243+
this.classList.remove('over');
244+
//}
245+
}
246+
247+
onDragEnter(event) {
224248
event.preventDefault();
225-
var data = event.dataTransfer.getData("element");
226-
event.target.appendChild(lively.query(this, '#'+data))
249+
//if (!this.complexQuery) this.style.border = '3px dotted #666';
250+
//lively.notify("ENTERED THIS", this.classList)
251+
this.classList.add('over');
252+
}
253+
254+
onDragLeave(event) {
255+
event.preventDefault();
256+
this.classList.remove('over');
257+
258+
//if (!this.isComplex) this.style.border = '3px dotted #FFF';
227259
}
228260

229261

230262

231263

264+
async updateView() {
265+
var pane = this.get("#pane")
266+
pane.innerHTML = ""
267+
268+
if(this.ui) {
269+
this.ui.style.draggable = 'true'
270+
this.ui.style.userSelect = 'none'
271+
if (!this.isComplex) {
272+
this.ui.addEventListener('dragstart', this.onDragStart)
273+
this.ui.addEventListener('dragend', this.onDragEnd)
274+
this.ui.addEventListener('dragover', this.onDragOver)
275+
this.ui.addEventListener('dragenter', this.onDragEnter)
276+
this.ui.addEventListener('dragleave', this.onDragLeave)
277+
this.ui.addEventListener('drop', this.onDrop)
278+
}
279+
pane.appendChild(this.ui)
280+
}
281+
}
232282

233283
async setQuery(q) {
234284
this.textContent = q;
@@ -251,50 +301,54 @@ export default class AcademicSubquery extends Morph {
251301
this.updateView();
252302
}
253303

254-
async updateView() {
255-
var pane = this.get("#pane")
256-
pane.innerHTML = ""
257-
258-
if(this.ui) {
259-
this.ui.style.draggable = 'true'
260-
this.ui.style.userSelect = 'none'
261-
this.ui.addEventListener('dragstart', (evt) => this.onDragStart(evt))
262-
this.ui.addEventListener('dragend', (evt) => this.onDragEnd(evt))
263-
this.ui.addEventListener('dragover', (evt) => this.onDragOver(evt))
264-
this.ui.addEventListener('drop', (evt) => this.onDrop(evt))
265-
pane.appendChild(this.ui)
266-
}
267-
}
268-
269304
async viewToQuery() {
270305
var query = this.textContent;
271306

272307
if (this.isComplex) {
273308
// TODO: Why is this neccessary?
274309
if (await this.leftSubquery && await this.rightSubquery) {
275-
var left = await this.leftSubquery.viewToQuery()
276-
var right = await this.rightSubquery.viewToQuery()
277-
var conjunction = this.get('#conjunction').textContent
310+
var left = await this.leftSubquery.viewToQuery();
311+
var right = await this.rightSubquery.viewToQuery();
312+
var conjunction = this.get('#conjunction').textContent;
278313
query = conjunction + "(" + left + ", " + right + ")";
279314
}
280315
} else {
281316
var [attr, comp, val] = this.get('#inner')
282-
.querySelectorAll("span[name='sub']")
317+
.querySelectorAll("span[name='queryPart']")
283318
.map(e => e.textContent);
284-
query = attr + comp + "'" + val + "'";
319+
if (val)
320+
val = val.slice(0, val.length - 1); // remove last whitespace
321+
// TODO: keep the '' when parsing query so that we don't have
322+
// 3 spans here....
323+
// OOODER ich lass das mit dem Edit Mode, dafür gibt's ja schon
324+
// das input Feld
325+
//query = attr + comp + "'" + val + "'";
326+
query = attr + comp + val;
285327
}
286328

287329
return query
288330
}
289331

290-
enableEditing() {
291-
var queries = this.get("#inner").querySelectorAll("[name='sub']")
292-
queries.forEach(q => {
293-
q.setAttribute("contenteditable", true)
294-
q.style.cursor = "text";
295-
})
296-
//query.setAttribute("contenteditable", true)
297-
//query.style.cursor = "text;"
332+
toggleEditing() {
333+
var queries = this.get("#inner").querySelectorAll("[name='sub']");
334+
var edit = this.get('#edit');
335+
edit.innerHTML = "";
336+
337+
if (!this.editing) {
338+
this.editing = true;
339+
edit.appendChild(<i class="fa fa-hand-paper-o" aria-hidden="true"></i>);
340+
queries.forEach(q => {
341+
q.setAttribute("contenteditable", true);
342+
q.style.cursor = "text";
343+
});
344+
} else {
345+
this.editing = false;
346+
edit.appendChild(<i class="fa fa-pencil" aria-hidden="true"></i>);
347+
queries.forEach(q => {
348+
q.setAttribute("contenteditable", false);
349+
q.style.cursor = "grab";
350+
});
351+
}
298352
}
299353

300354
onMouseOver(event) {
@@ -350,19 +404,19 @@ export default class AcademicSubquery extends Morph {
350404

351405
subSpan = <span name="sub" draggable='true'></span>;
352406
[object.attribute, object.comparator, object.value].forEach(value => {
353-
subSpan.appendChild(<span>{value} </span>)
407+
subSpan.appendChild(<span class="queryPart" name="queryPart">{value} </span>)
354408
subSpan.addEventListener('mouseover', (evt) => this.onMouseOver(evt));
355409
subSpan.addEventListener('mouseout', (evt) => this.onMouseOut(evt));
356410
subSpan.style.cursor = "grab" // on drag: grabbing
357411
});
358412
span.appendChild(subSpan);
359-
var edit = <span id="edit" title="edit query" click={() => this.enableEditing()}><i class="fa fa-pencil" aria-hidden="true"></i></span>;
413+
var edit = <span id="edit" title="toggle edit mode" click={() => this.toggleEditing()}><i class="fa fa-pencil" aria-hidden="true"></i></span>;
360414
edit.style.cursor = "pointer";
361415
span.appendChild(edit);
362416
break;
363417
}
364418

365-
var queryElement = <div><b>{span}</b></div>;
419+
var queryElement = <div class="dropTarget"><b>{span}</b></div>;
366420

367421
return queryElement;
368422
}

0 commit comments

Comments
 (0)