Add content sections selection to search page
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
index 512ef90..f3b6758 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/apps/samples/common/GQLschema.jsp
@@ -54,6 +54,7 @@
   title: String
   tags: [String]
   text: String
+  section: String
 
   # List of "See Also" articles
   seeAlso: [Article] @fetcher(name:"samples/seeAlso")
diff --git a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
index d4a6062..9e9afb9 100644
--- a/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
+++ b/org.apache.sling.graphql.samples.website/src/main/resources/SLING-INF/initial-content/content/search.html
@@ -22,10 +22,24 @@
         ~ 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="
@@ -41,13 +55,45 @@
         <script src="./js/graphql.js"></script>
 
         <script>
-            var templates = {
-                navigation: {},
-                results: {}
+            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) {
-                var query = `{
+                const query = `{
                     navigation {
                         search
                         sections {
@@ -58,27 +104,40 @@
                     article(withText: "${searchText}") {
                         path
                         title
-                        seeAlso {
-                        path
-                        title
-                        tags
-                        }
+                        section
                     }
                 }`;
-                console.log(`Querying:\n${query}`);
                 graphQL.query(query, { searchText: searchText}, function(data) {
+                    // Render navigation
                     $("#navigation").html(templates.navigation({navigation:data.result.navigation}));
-                    $("#results").html(templates.results({data:data}));
+
+                    // 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());
             });
@@ -93,11 +152,15 @@
         <hr/>
 
         <form id="search">
-            <input id="searchText" type="text" width="40"/>
+            <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>
 
@@ -114,7 +177,11 @@
             </div>
             <div id="resultsTemplate">
                 {{#if data.result.article}}
-                    <h2>Found {{data.result.article.length}} articles containing "{{data.info.searchText}}"</h2>
+                    <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">
@@ -126,6 +193,13 @@
                 <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>
\ No newline at end of file