Showing
3 changed files
with
252 additions
and
9 deletions
... | @@ -580,9 +580,34 @@ app:ClassTreeDataProvider | ... | @@ -580,9 +580,34 @@ app:ClassTreeDataProvider |
580 | rdfs:label "Class tree data provider"^^xsd:string ; | 580 | rdfs:label "Class tree data provider"^^xsd:string ; |
581 | arg:treeChildrenTemplate | 581 | arg:treeChildrenTemplate |
582 | app:ClassTreeChildren ; | 582 | app:ClassTreeChildren ; |
583 | + arg:treePathTemplate | ||
584 | + app:ClassTreePath ; | ||
583 | arg:treeRootsTemplate | 585 | arg:treeRootsTemplate |
584 | app:ClassTreeRoots . | 586 | app:ClassTreeRoots . |
585 | 587 | ||
588 | +app:ClassTreePath | ||
589 | + rdf:type spin:SelectTemplate ; | ||
590 | + rdfs:label "Class tree path"^^xsd:string ; | ||
591 | + rdfs:subClassOf app:TreePathTemplates ; | ||
592 | + spin:body | ||
593 | + [ rdf:type sp:Select ; | ||
594 | + sp:resultVariables ([ sp:varName "path"^^xsd:string | ||
595 | + ]) ; | ||
596 | + sp:where ([ rdf:type sp:Bind ; | ||
597 | + sp:expression | ||
598 | + [ rdf:type spif:shortestObjectsPath ; | ||
599 | + sp:arg1 [ sp:varName "node"^^xsd:string | ||
600 | + ] ; | ||
601 | + sp:arg2 rdfs:subClassOf ; | ||
602 | + sp:arg3 [ sp:varName "root"^^xsd:string | ||
603 | + ] | ||
604 | + ] ; | ||
605 | + sp:variable | ||
606 | + [ sp:varName "path"^^xsd:string | ||
607 | + ] | ||
608 | + ]) | ||
609 | + ] . | ||
610 | + | ||
586 | app:ClassTreeRoots | 611 | app:ClassTreeRoots |
587 | rdf:type spin:SelectTemplate ; | 612 | rdf:type spin:SelectTemplate ; |
588 | rdfs:label "Class tree roots"^^xsd:string ; | 613 | rdfs:label "Class tree roots"^^xsd:string ; |
... | @@ -860,6 +885,7 @@ app:CustomEditForm | ... | @@ -860,6 +885,7 @@ app:CustomEditForm |
860 | ] ; | 885 | ] ; |
861 | ui:child | 886 | ui:child |
862 | [ rdf:type html:Form ; | 887 | [ rdf:type html:Form ; |
888 | + html:autocomplete "off"^^xsd:string ; | ||
863 | html:class "appForm ui-layout-content"^^xsd:string ; | 889 | html:class "appForm ui-layout-content"^^xsd:string ; |
864 | html:id [ sp:varName "fid"^^xsd:string | 890 | html:id [ sp:varName "fid"^^xsd:string |
865 | ] ; | 891 | ] ; |
... | @@ -3973,6 +3999,7 @@ app:SearchForm | ... | @@ -3973,6 +3999,7 @@ app:SearchForm |
3973 | ] ; | 3999 | ] ; |
3974 | ui:child | 4000 | ui:child |
3975 | [ rdf:type html:Form ; | 4001 | [ rdf:type html:Form ; |
4002 | + html:autocomplete "off"^^xsd:string ; | ||
3976 | html:class | 4003 | html:class |
3977 | [ rdf:type ui:concat ; | 4004 | [ rdf:type ui:concat ; |
3978 | sp:arg1 "appForm ui-layout-content "^^xsd:string ; | 4005 | sp:arg1 "appForm ui-layout-content "^^xsd:string ; |
... | @@ -5481,7 +5508,9 @@ app:TreeDataProvider | ... | @@ -5481,7 +5508,9 @@ app:TreeDataProvider |
5481 | rdf:type ui:NodeClass ; | 5508 | rdf:type ui:NodeClass ; |
5482 | rdfs:comment """Instances of this class are used as server callbacks to drive an app:Tree. | 5509 | rdfs:comment """Instances of this class are used as server callbacks to drive an app:Tree. |
5483 | 5510 | ||
5484 | -A TreeDataProvider is backed by two SELECT queries - one to get the roots, and one to get the children of a given node. Optionally, a root resource can be supplied to overload the default root(s)."""^^xsd:string ; | 5511 | +A TreeDataProvider is backed by two SELECT queries - one to get the roots, and one to get the children of a given node. Optionally, a root resource can be supplied to overload the default root(s). |
5512 | + | ||
5513 | +Another operation that trees must support is finding an expansion path from a root to a given node. To support this, each TreeDataProvider points to a SPIN template that delivers a path. This typically uses the spif:shortestObjectsPath function."""^^xsd:string ; | ||
5485 | rdfs:label "Tree data provider"^^xsd:string ; | 5514 | rdfs:label "Tree data provider"^^xsd:string ; |
5486 | rdfs:subClassOf app:TreeElements ; | 5515 | rdfs:subClassOf app:TreeElements ; |
5487 | spin:constraint | 5516 | spin:constraint |
... | @@ -5492,6 +5521,12 @@ A TreeDataProvider is backed by two SELECT queries - one to get the roots, and o | ... | @@ -5492,6 +5521,12 @@ A TreeDataProvider is backed by two SELECT queries - one to get the roots, and o |
5492 | ] ; | 5521 | ] ; |
5493 | spin:constraint | 5522 | spin:constraint |
5494 | [ rdf:type spl:Argument ; | 5523 | [ rdf:type spl:Argument ; |
5524 | + rdfs:comment "This SPIN template is called with the variable ?node pre-bound to a node in the tree and ?root possibly pointing to a root resource. The template must return a single result variable containing a path from a root to that node. See spif:shortestObjectsPath for a default implementation. The path must be a space-separated string concatenation of URIs."^^xsd:string ; | ||
5525 | + spl:predicate arg:treePathTemplate ; | ||
5526 | + spl:valueType spin:Template | ||
5527 | + ] ; | ||
5528 | + spin:constraint | ||
5529 | + [ rdf:type spl:Argument ; | ||
5495 | rdfs:comment "A subclass of app:TreeRootsTemplates that delivers the roots of the tree. Will be bypassed if the tree itself defined an arg:rootResource."^^xsd:string ; | 5530 | rdfs:comment "A subclass of app:TreeRootsTemplates that delivers the roots of the tree. Will be bypassed if the tree itself defined an arg:rootResource."^^xsd:string ; |
5496 | spl:optional "true"^^xsd:boolean ; | 5531 | spl:optional "true"^^xsd:boolean ; |
5497 | spl:predicate arg:treeRootsTemplate ; | 5532 | spl:predicate arg:treeRootsTemplate ; |
... | @@ -5583,6 +5618,25 @@ app:TreeElements | ... | @@ -5583,6 +5618,25 @@ app:TreeElements |
5583 | rdfs:label "Tree elements"^^xsd:string ; | 5618 | rdfs:label "Tree elements"^^xsd:string ; |
5584 | rdfs:subClassOf app:Elements . | 5619 | rdfs:subClassOf app:Elements . |
5585 | 5620 | ||
5621 | +app:TreePathTemplates | ||
5622 | + rdf:type spin:SelectTemplate ; | ||
5623 | + rdfs:comment "An abstract superclass for SPIN templates used by TreeDataProviders to find a path from a node to a root."^^xsd:string ; | ||
5624 | + rdfs:label "Tree path templates"^^xsd:string ; | ||
5625 | + rdfs:subClassOf spin:SelectTemplates ; | ||
5626 | + spin:constraint | ||
5627 | + [ rdf:type spl:Argument ; | ||
5628 | + rdfs:comment "The node to start traversal at."^^xsd:string ; | ||
5629 | + spl:predicate arg:node ; | ||
5630 | + spl:valueType rdfs:Resource | ||
5631 | + ] ; | ||
5632 | + spin:constraint | ||
5633 | + [ rdf:type spl:Argument ; | ||
5634 | + rdfs:comment "An optional root resource to stop traversal at."^^xsd:string ; | ||
5635 | + spl:optional "true"^^xsd:boolean ; | ||
5636 | + spl:predicate arg:root ; | ||
5637 | + spl:valueType rdfs:Resource | ||
5638 | + ] . | ||
5639 | + | ||
5586 | app:TreeRootsTemplates | 5640 | app:TreeRootsTemplates |
5587 | rdf:type spin:SelectTemplate ; | 5641 | rdf:type spin:SelectTemplate ; |
5588 | rdfs:comment "Abstract superclass for queries that can deliver the roots of a tree."^^xsd:string ; | 5642 | rdfs:comment "Abstract superclass for queries that can deliver the roots of a tree."^^xsd:string ; |
... | @@ -5596,6 +5650,115 @@ app:TreeRootsTemplates | ... | @@ -5596,6 +5650,115 @@ app:TreeRootsTemplates |
5596 | spl:valueType rdfs:Resource | 5650 | spl:valueType rdfs:Resource |
5597 | ] . | 5651 | ] . |
5598 | 5652 | ||
5653 | +app:TreeShortestPathCallback | ||
5654 | + rdf:type ui:NodeClass ; | ||
5655 | + rdfs:comment "An element building a JSON array with URIs based on spif:shortestObjectsPath. Called using uispin?_viewClass=app:TreeShortestPathCallback&_format=json&subject=...&dataProvider=..."^^xsd:string ; | ||
5656 | + rdfs:label "Tree shortest path callback"^^xsd:string ; | ||
5657 | + rdfs:subClassOf app:TreeElements ; | ||
5658 | + spin:constraint | ||
5659 | + [ rdf:type spl:Argument ; | ||
5660 | + rdfs:comment "The TreeDataProvider that contains the pathExpression needed to walk to the root."^^xsd:string ; | ||
5661 | + spl:predicate arg:dataProvider ; | ||
5662 | + spl:valueType app:TreeDataProvider | ||
5663 | + ] ; | ||
5664 | + spin:constraint | ||
5665 | + [ rdf:type spl:Argument ; | ||
5666 | + rdfs:comment "The node resource to start traversal at."^^xsd:string ; | ||
5667 | + spl:predicate arg:node ; | ||
5668 | + spl:valueType rdfs:Resource | ||
5669 | + ] ; | ||
5670 | + spin:constraint | ||
5671 | + [ rdf:type spl:Argument ; | ||
5672 | + rdfs:comment "The root resource to stop at."^^xsd:string ; | ||
5673 | + spl:optional "true"^^xsd:boolean ; | ||
5674 | + spl:predicate arg:root ; | ||
5675 | + spl:valueType rdfs:Resource | ||
5676 | + ] ; | ||
5677 | + ui:prototype | ||
5678 | + [ rdf:type ui:group ; | ||
5679 | + let:template | ||
5680 | + [ rdf:type sp:Select ; | ||
5681 | + sp:resultVariables ([ sp:varName "template"^^xsd:string | ||
5682 | + ]) ; | ||
5683 | + sp:where ([ rdf:type sp:NamedGraph ; | ||
5684 | + sp:elements ([ sp:object | ||
5685 | + [ sp:varName "template"^^xsd:string | ||
5686 | + ] ; | ||
5687 | + sp:predicate arg:treePathTemplate ; | ||
5688 | + sp:subject | ||
5689 | + [ sp:varName "dataProvider"^^xsd:string | ||
5690 | + ] | ||
5691 | + ]) ; | ||
5692 | + sp:graphNameNode ui:graph | ||
5693 | + ]) | ||
5694 | + ] ; | ||
5695 | + ui:child | ||
5696 | + [ rdf:type ui:call ; | ||
5697 | + arg:node | ||
5698 | + [ sp:varName "node"^^xsd:string | ||
5699 | + ] ; | ||
5700 | + arg:root | ||
5701 | + [ sp:varName "root"^^xsd:string | ||
5702 | + ] ; | ||
5703 | + ui:child | ||
5704 | + [ rdf:type ui:group ; | ||
5705 | + let:path | ||
5706 | + [ rdf:type spr:cell ; | ||
5707 | + sp:arg1 [ sp:varName "rs"^^xsd:string | ||
5708 | + ] ; | ||
5709 | + sp:arg2 0 ; | ||
5710 | + sp:arg3 0 | ||
5711 | + ] ; | ||
5712 | + ui:child | ||
5713 | + [ rdf:type swon:RSArray ; | ||
5714 | + arg:resultSet | ||
5715 | + [ rdf:type sp:Select ; | ||
5716 | + sp:resultVariables ([ sp:varName "value"^^xsd:string | ||
5717 | + ]) ; | ||
5718 | + sp:where ([ sp:object | ||
5719 | + [ sp:varName "?0"^^xsd:string | ||
5720 | + ] ; | ||
5721 | + sp:predicate spif:split ; | ||
5722 | + sp:subject | ||
5723 | + [ sp:varName "value"^^xsd:string | ||
5724 | + ] | ||
5725 | + ] [ sp:object | ||
5726 | + [ sp:varName "path"^^xsd:string | ||
5727 | + ] ; | ||
5728 | + sp:predicate rdf:first ; | ||
5729 | + sp:subject | ||
5730 | + [ sp:varName "?0"^^xsd:string | ||
5731 | + ] | ||
5732 | + ] [ sp:object | ||
5733 | + [ sp:varName "?1"^^xsd:string | ||
5734 | + ] ; | ||
5735 | + sp:predicate rdf:rest ; | ||
5736 | + sp:subject | ||
5737 | + [ sp:varName "?0"^^xsd:string | ||
5738 | + ] | ||
5739 | + ] [ sp:object " " ; | ||
5740 | + sp:predicate rdf:first ; | ||
5741 | + sp:subject | ||
5742 | + [ sp:varName "?1"^^xsd:string | ||
5743 | + ] | ||
5744 | + ] [ sp:object () ; | ||
5745 | + sp:predicate rdf:rest ; | ||
5746 | + sp:subject | ||
5747 | + [ sp:varName "?1"^^xsd:string | ||
5748 | + ] | ||
5749 | + ]) | ||
5750 | + ] ; | ||
5751 | + ui:childIndex 0 | ||
5752 | + ] ; | ||
5753 | + ui:childIndex 0 | ||
5754 | + ] ; | ||
5755 | + ui:childIndex 0 ; | ||
5756 | + ui:template | ||
5757 | + [ sp:varName "template"^^xsd:string | ||
5758 | + ] | ||
5759 | + ] | ||
5760 | + ] . | ||
5761 | + | ||
5599 | app:TreeTemplates | 5762 | app:TreeTemplates |
5600 | rdf:type spin:SelectTemplate ; | 5763 | rdf:type spin:SelectTemplate ; |
5601 | rdfs:comment """Base class for SELECT templates that are used to populate trees. There are two kinds of queries: | 5764 | rdfs:comment """Base class for SELECT templates that are used to populate trees. There are two kinds of queries: |
... | @@ -7354,6 +7517,11 @@ arg:treeChildrenTemplate | ... | @@ -7354,6 +7517,11 @@ arg:treeChildrenTemplate |
7354 | rdfs:label "tree children template"^^xsd:string ; | 7517 | rdfs:label "tree children template"^^xsd:string ; |
7355 | rdfs:subPropertyOf sp:arg . | 7518 | rdfs:subPropertyOf sp:arg . |
7356 | 7519 | ||
7520 | +arg:treePathTemplate | ||
7521 | + rdf:type rdf:Property ; | ||
7522 | + rdfs:label "tree path template"^^xsd:string ; | ||
7523 | + rdfs:subPropertyOf sp:arg . | ||
7524 | + | ||
7357 | arg:treeRootsTemplate | 7525 | arg:treeRootsTemplate |
7358 | rdf:type rdf:Property ; | 7526 | rdf:type rdf:Property ; |
7359 | rdfs:label "tree roots template"^^xsd:string ; | 7527 | rdfs:label "tree roots template"^^xsd:string ; |
... | @@ -7379,6 +7547,16 @@ arg:width | ... | @@ -7379,6 +7547,16 @@ arg:width |
7379 | rdfs:label "width"^^xsd:string ; | 7547 | rdfs:label "width"^^xsd:string ; |
7380 | rdfs:subPropertyOf sp:arg . | 7548 | rdfs:subPropertyOf sp:arg . |
7381 | 7549 | ||
7550 | +html:treedataprovider | ||
7551 | + rdf:type html:Attribute ; | ||
7552 | + rdfs:label "tree data provider"^^xsd:string ; | ||
7553 | + rdfs:subPropertyOf html:attributes . | ||
7554 | + | ||
7555 | +html:treeroot | ||
7556 | + rdf:type html:Attribute ; | ||
7557 | + rdfs:label "tree root"^^xsd:string ; | ||
7558 | + rdfs:subPropertyOf html:attributes . | ||
7559 | + | ||
7382 | ui:SubjectWidgetRowClass | 7560 | ui:SubjectWidgetRowClass |
7383 | rdf:type rdfs:Class ; | 7561 | rdf:type rdfs:Class ; |
7384 | rdfs:label "Subject widget row class"^^xsd:string ; | 7562 | rdfs:label "Subject widget row class"^^xsd:string ; | ... | ... |
... | @@ -339,6 +339,73 @@ function appReloadForm(resourceURI, queryGraphURI, linkElementId) { | ... | @@ -339,6 +339,73 @@ function appReloadForm(resourceURI, queryGraphURI, linkElementId) { |
339 | 339 | ||
340 | 340 | ||
341 | /** | 341 | /** |
342 | + * Selects a given node in a given tree. | ||
343 | + * Will expand if necessary, using a server-side shortest path algorithm. | ||
344 | + * @param treeId the id of the tree | ||
345 | + * @param nodeURI the URI of the resource to select | ||
346 | + */ | ||
347 | +function appSelectTreeNode(treeId, nodeURI) { | ||
348 | + | ||
349 | + // TODO: Currently this only works on the Tree that was created last | ||
350 | + // but not if multiple trees are on a page | ||
351 | + | ||
352 | + var tree = $('#' + treeId); | ||
353 | + var dataProviderURI = tree.attr('treedataprovider'); | ||
354 | + if(!dataProviderURI) { | ||
355 | + alert('Error: Element with id ' + treeId + ' does not have treedataprovider attribute'); | ||
356 | + return; | ||
357 | + } | ||
358 | + | ||
359 | + var rootURI = tree.attr('treeroot'); | ||
360 | + | ||
361 | + // Do nothing if it's already selected | ||
362 | + var sel = tree.jstree('get_selected'); | ||
363 | + if(sel) { | ||
364 | + if(sel.attr('resource') == nodeURI) { | ||
365 | + return; | ||
366 | + } | ||
367 | + } | ||
368 | + | ||
369 | + // Load path to root from the server and then call helper function | ||
370 | + var data = { | ||
371 | + _format: 'json', | ||
372 | + _viewClass: 'app:TreeShortestPathCallback', | ||
373 | + dataProvider: '<' + dataProviderURI + '>', | ||
374 | + node: '<' + nodeURI + '>' | ||
375 | + }; | ||
376 | + if(rootURI) { | ||
377 | + data.root = '<' + rootURI + '>'; | ||
378 | + } | ||
379 | + $.get(uispinServlet, data, function(path) { | ||
380 | + appSelectTreeNodeHelper(tree, tree, path, 0); | ||
381 | + }); | ||
382 | +} | ||
383 | + | ||
384 | + | ||
385 | +// Private helper function - walks an array, expanding nodes along the way | ||
386 | +function appSelectTreeNodeHelper(tree, node, path, index) { | ||
387 | + | ||
388 | + var next = path[index]; | ||
389 | + | ||
390 | + node.children("ul").children("li").each(function(i, o) { | ||
391 | + var child = $(o); | ||
392 | + if(child.attr('resource') == next) { | ||
393 | + if(index == path.length - 1) { | ||
394 | + // End reached: select this node | ||
395 | + tree.jstree('select_node', child, true); | ||
396 | + child[0].scrollIntoView(); | ||
397 | + } | ||
398 | + else { | ||
399 | + tree.jstree('open_node', child, function() { | ||
400 | + appSelectTreeNodeHelper(tree, child, path, index + 1); | ||
401 | + }); | ||
402 | + } | ||
403 | + } | ||
404 | + }); | ||
405 | +} | ||
406 | + | ||
407 | + | ||
408 | +/** | ||
342 | * Submits a form and switches it to viewing mode when done. | 409 | * Submits a form and switches it to viewing mode when done. |
343 | * @param form the id of the form | 410 | * @param form the id of the form |
344 | * @param servlet the optional name of the servlet | 411 | * @param servlet the optional name of the servlet | ... | ... |
... | @@ -5,8 +5,7 @@ | ... | @@ -5,8 +5,7 @@ |
5 | ui:view="{= ?dataProvider }" | 5 | ui:view="{= ?dataProvider }" |
6 | arg:root="{= ?root }"> | 6 | arg:root="{= ?root }"> |
7 | 7 | ||
8 | - <!-- The div that will be turned into a jsTree below --> | 8 | + <div id="{= ?id }" treedataprovider="{= ?dataProvider }" treeroot="{= ?root }"/> |
9 | - <div id="{= ?id }" /> | ||
10 | 9 | ||
11 | <script type="text/javascript"> | 10 | <script type="text/javascript"> |
12 | $(function () { | 11 | $(function () { |
... | @@ -15,12 +14,7 @@ | ... | @@ -15,12 +14,7 @@ |
15 | "plugins" : [ | 14 | "plugins" : [ |
16 | "themes", | 15 | "themes", |
17 | "json_data", | 16 | "json_data", |
18 | - "ui", | 17 | + "ui" ], |
19 | - "crrm", | ||
20 | - "cookies", | ||
21 | - "search", | ||
22 | - "types", | ||
23 | - "hotkeys" ], | ||
24 | 18 | ||
25 | "json_data" : { | 19 | "json_data" : { |
26 | "ajax" : { | 20 | "ajax" : { |
... | @@ -40,6 +34,10 @@ | ... | @@ -40,6 +34,10 @@ |
40 | 34 | ||
41 | "themes" : { | 35 | "themes" : { |
42 | "theme" : "classic" | 36 | "theme" : "classic" |
37 | + }, | ||
38 | + | ||
39 | + "ui": { | ||
40 | + "select_limit": 1 | ||
43 | } | 41 | } |
44 | }); | 42 | }); |
45 | }); | 43 | }); | ... | ... |
-
Please register or login to post a comment