Overview

This shows the progression of the note-edit template.

note-edit v1.1

Description

The title and h1 elements are modified to display the date of the note.

Code


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:dcterms="http://purl.org/dc/terms/">
<head>
    <title resource="?this">{dcterms:date}</title>
</head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
    <div class="container">
        <div class="page-header">
            <h1><time datetime="{dcterms:date}" /></h1>
            <script type="text/javascript">
                $('h1 time[datetime]').text(calli.parseDateTime("{dcterms:date}").toLocaleString());
            </script>
        </div>
        <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" class="row"
                onsubmit="calli.submitUpdate(comparison,event)">
            <fieldset class="col-sm-4">
                <div class="form-group">
                    <label for="label">Label</label>
                    <input type="text" class="form-control" id="label" value="{rdfs:label}" required="required"
                        onchange="calli.updateProperty(event, 'rdfs:label')" />
                </div>
                <div class="form-group">
                    <label for="comment">Comment</label>
                    <textarea id="comment" class="form-control"
                        onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Save</button>
                    <button type="button" class="btn btn-default" onclick="location.replace('?view')">Cancel</button>
            		<button type="button" class="btn btn-danger" onclick="calli.deleteResource(event)">Delete</button>
                </div>
            </fieldset>
        </form>
    </div>
</body>
</html>

note-edit v1.2

Description

The input field is removed since the date should not be changed.

Code


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:dcterms="http://purl.org/dc/terms/">
<head>
    <title resource="?this">{dcterms:date}</title>
</head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
    <div class="container">
        <div class="page-header">
            <h1><time datetime="{dcterms:date}" /></h1>
            <script type="text/javascript">
                $('h1 time[datetime]').text(calli.parseDateTime("{dcterms:date}").toLocaleString());
            </script>
        </div>
        <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" class="row"
                onsubmit="calli.submitUpdate(comparison,event)">
            <fieldset class="col-sm-6">
                <div class="form-group">
                    <label for="comment">Comment</label>
                    <textarea id="comment" class="form-control"
                        onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Save</button>
                    <button type="button" class="btn btn-default" onclick="location.replace('?view')">Cancel</button>
            		<button type="button" class="btn btn-danger" onclick="calli.deleteResource(event)">Delete</button>
                </div>
            </fieldset>
        </form>
    </div>
</body>
</html>

Topic Search Query

A Named RDF Query is required to to implement the autocomplete feature of the topic field.


# topic-search.rq
#
# @Cache-Control: no-store
#
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX meeting: <http://localhost:8080/schema/>

SELECT ?resource ?label {
    ?resource a <Topic>; rdfs:label ?label
    {
        ?resource meeting:state <topic-state/new>
    } UNION {
        ?resource meeting:state <topic-state/open>
    }
    FILTER regex(?label, "$q")
} ORDER BY ?label LIMIT 10

Topic Field Script v1

The autocomplete topic field will used selectize.js to render the suggestions using the results from the above query. Selectize.js is included in every Callimachus page (by default) and including it explicitly is not necessary. Rather then using an embedded URL for the query, which are resolved against the current page URL, the query URL is read from the template (and relative to the template URL and not the note page).


// note.js

jQuery(function($){
    $('#topics').selectize({
        load: function(query, callback) {
            var url = $('#topic-search').prop('href').replace('{q}', encodeURIComponent(query));
            calli.getJSON(url).then(function(json){
                return json.results.bindings.map(function(bindings){
                    return {
                        value: bindings.resource.value,
                        text: bindings.label.value
                    };
                });
            }).then(callback, function(error){
                callback();
                return calli.error(error);
            });
        }
    });
});

note-edit v1.3

Description

The above script is included and the URL for the query is placed in the template header. The query URL is placed in the template using a relative URL. Callimachus will rewrite this @href to be absolute, so the URI of the node will not effect the location.

A select field is created for topics that includes the existing values, already selected.

Code


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:dcterms="http://purl.org/dc/terms/">
<head>
    <title resource="?this">{dcterms:date}</title>
    <link id="topic-search" href="topic-search.rq?results&amp;tqx=out:sparql-json&amp;q={q}" />
    <script type="text/javascript" src="note.js"></script>
</head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
    <div class="container">
        <div class="page-header">
            <h1><time datetime="{dcterms:date}" /></h1>
            <script type="text/javascript">
                $('h1 time[datetime]').text(calli.parseDateTime("{dcterms:date}").toLocaleString());
            </script>
        </div>
        <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" class="row"
                onsubmit="calli.submitUpdate(comparison,event)">
            <fieldset class="col-sm-6">
                <div class="form-group">
                    <label for="comment">Comment</label>
                    <textarea id="comment" class="form-control"
                        onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
                </div>
                <div class="form-group">
                    <label for="topics">Topics</label>
                    <select id="topics" class="form-control" multiple="multiple"
                            onchange="calli.updateResource(event,'dcterms:hasPart')">
                        <option selected="selected" rel="dcterms:hasPart" resource="?topic" value="{?topic}">{rdfs:label}</option>
                    </select>
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Save</button>
                    <button type="button" class="btn btn-default" onclick="location.replace('?view')">Cancel</button>
            		<button type="button" class="btn btn-danger" onclick="calli.deleteResource(event)">Delete</button>
                </div>
            </fieldset>
        </form>
    </div>
</body>
</html>

note-edit v1.4

Description

Include the URL to create a new topic in the header, for use by the script below. This is placed in the template, so that it is resolved relative to the template and not the note edit page location.

Code


<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xi="http://www.w3.org/2001/XInclude"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:dcterms="http://purl.org/dc/terms/">
<head>
    <title resource="?this">{dcterms:date}</title>
    <link id="topic" href="Topic" />
    <link id="topic-search" href="topic-search.rq?results&amp;tqx=out:sparql-json&amp;q={q}" />
    <script type="text/javascript" src="note.js"></script>
</head>
<body resource="?this" onload="comparison=calli.copyResourceData('#form')">
    <div class="container">
        <div class="page-header">
            <h1><time datetime="{dcterms:date}" /></h1>
            <script type="text/javascript">
                $('h1 time[datetime]').text(calli.parseDateTime("{dcterms:date}").toLocaleString());
            </script>
        </div>
        <form id="form" method="POST" action="" enctype="application/sparql-update" resource="?this" class="row"
                onsubmit="calli.submitUpdate(comparison,event)">
            <fieldset class="col-sm-6">
                <div class="form-group">
                    <label for="comment">Comment</label>
                    <textarea id="comment" class="form-control"
                        onchange="calli.updateProperty(event, 'rdfs:comment')">{rdfs:comment}</textarea>
                </div>
                <div class="form-group">
                    <label for="topics">Topics</label>
                    <select id="topics" class="form-control" multiple="multiple"
                            onchange="calli.updateResource(event,'dcterms:hasPart')">
                        <option selected="selected" rel="dcterms:hasPart" resource="?topic" value="{?topic}">{rdfs:label}</option>
                    </select>
                </div>
                <div class="form-group">
                    <button type="submit" class="btn btn-primary">Save</button>
                    <button type="button" class="btn btn-default" onclick="location.replace('?view')">Cancel</button>
            		<button type="button" class="btn btn-danger" onclick="calli.deleteResource(event)">Delete</button>
                </div>
            </fieldset>
        </form>
    </div>
</body>
</html>

Topic Field Script v2

By including a create function option in selectize.js initializer, one can call calli.createResource to bring up the create form in a dialogue.


// note.js

jQuery(function($){
    $('#topics').selectize({
        load: function(query, callback) {
            var url = $('#topic-search').prop('href').replace('{q}', encodeURIComponent(query));
            calli.getJSON(url).then(function(json){
                return json.results.bindings.map(function(bindings){
                    return {
                        value: bindings.resource.value,
                        text: bindings.label.value
                    };
                });
            }).then(callback, function(error){
                callback();
                return calli.error(error);
            });
        },
        create: function(label, callback) {
            var url = window.location.pathname + '/' + calli.slugify(label);
            calli.headText(url).then(function(){
                return url; // already exists
            }, function(xhr) {
                if (xhr.status != 404) return calli.reject(xhr);
                return calli.createResource('#topics', '?create=' + encodeURIComponent($('#topic').prop('href')) + '#' + encodeURIComponent(label));
            }).then(function(resource){
                return resource && {
                    value: resource,
                    text: resource.replace(/.*\//,'')
                };
            }).then(callback, function(error){
                callback();
                return calli.error(error);
            });
        }
    });
});