blob: 9e9afb995fdb27a44d9907161642c07f916140e9 [file] [log] [blame]
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ Licensed to the Apache Software Foundation (ASF) under one
~ or more contributor license agreements. See the NOTICE file
~ distributed with this work for additional information
~ regarding copyright ownership. The ASF licenses this file
~ to you under the Apache License, Version 2.0 (the
~ "License"); you may not use this file except in compliance
~ with the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing,
~ software distributed under the License is distributed on an
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
<!--
Example (basic) single-page app to search for articles, gets its initial
content using a GraphQL query and manipulates it locally, to filter found
articles by content section.
-->
<title>Search Articles</title>
<link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css">
<style type="text/css">
.activefalse {
text-decoration: line-through;
}
.sectionButton {
text-decoration: none;
}
</style>
<script
src="https://code.jquery.com/jquery-3.5.1.js"
integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
crossorigin="anonymous">
</script>
<script
src="https://cdn.jsdelivr.net/npm/handlebars@4.7.6/dist/handlebars.js"
integrity="sha256-ZafrO8ZXERYO794Tx1hPaAcdcXNZUNmXufXOSe0Hxj8="
crossorigin="anonymous">
</script>
<script src="./js/graphql.js"></script>
<script>
var templates = {};
var searchResult = {};
var sections = {};
// Filter articles locally based on selection content sections
// and render the result.
function renderArticles() {
var filtered = {
info: searchResult.info,
result: { article: []}
};
if(sections) {
for(const article of searchResult.result.article) {
if(sections[article.section].active) {
filtered.result.article.push(article);
}
}
} else {
filtered.result.article = searchResult.result.article;
}
$("#results").html(templates.results({data:filtered}));
}
// Render the content sections names of the result set and setup
// their selection links
function renderSections() {
$("#sections").html(templates.sections({data:sections}));
$(".sectionButton").click(function() {
const section = $(this).text();
sections[section].active = !sections[section].active;
renderSections();
renderArticles();
return false;
});
}
// GraphQL query and results rendering
function queryAndRender(searchText) {
const query = `{
navigation {
search
sections {
path
name
}
}
article(withText: "${searchText}") {
path
title
section
}
}`;
graphQL.query(query, { searchText: searchText}, function(data) {
// Render navigation
$("#navigation").html(templates.navigation({navigation:data.result.navigation}));
// Setup section selection buttons
sections = {};
for(const article of data.result.article) {
sections[article.section] = { name: article.section, active:true };
}
// Render articles
searchResult = data;
renderSections();
renderArticles();
});
}
// Initial setup
$(document).ready(function() {
// Compile templates
templates.results = Handlebars.compile($("#resultsTemplate").html());
templates.navigation = Handlebars.compile($("#navigationTemplate").html());
templates.sections = Handlebars.compile($("#sectionsTemplate").html());
// Setup search form
$("#search").submit(function() {
queryAndRender($("#searchText").val());
return false;
});
// Init page state
$("#searchText").focus();
queryAndRender($("#searchText").val());
});
</script>
</head>
<body>
<div>
<div id="navigation"/>
</div>
<h1>Search in articles</h1>
<hr/>
<form id="search">
<input id="searchText" type="text" width="40" value="virtual"/>
<input type="submit" value="Search"/>
</form>
<div>
<div id="sections"/>
</div>
<div>
<div id="results"/>
</div>
<div id="templates" style="display:none">
<div id="navigationTemplate">
{{#each navigation.sections}}
<span class="section">
<a href="{{this.path}}.html">{{this.name}}</a>
</span>
{{/each}}
<br/>
<a href="{{navigation.search}}.html">Search</a>
<hr/>
</div>
<div id="resultsTemplate">
{{#if data.result.article}}
<h2>
Found {{data.result.article.length}} articles
containing "{{data.info.searchText}}"
in the selected content sections
</h2>
<ul>
{{#each data.result.article}}
<li class="articleLink">
<a href="{{this.path}}.html">{{this.title}}</a>
</li>
{{/each}}
</ul>
{{else}}
<div class="message">No articles found.</div>
{{/if}}
</div>
<div id="sectionsTemplate">
{{#each data}}
<span class="active{{this.active}}"><a href="unused" class="sectionButton">{{this.name}}</a></span>
{{/each}}
<em>&lt;-- Click to select/deselect content sections</em>
<hr/>
</div>
</div>
</body>
</html>