initial draft of searching is finished

pull/3/head
David Tookey 5 years ago
parent be6f265a89
commit b884fa88a7

@ -128,8 +128,8 @@
<div class="sb-example-1"> <div class="sb-example-1">
<div class="search"> <div class="search">
<input type="text" class="searchTerm" placeholder="Search"> <input id="searchfield" type="text" class="searchTerm" placeholder="Search">
<button type="submit" class="searchbutton"> <button id="searchbutton" type="submit" class="searchbutton">
<svg width="100%" height="auto" viewBox="-1 -3 22 22" class="bi bi-search" fill="info" <svg width="100%" height="auto" viewBox="-1 -3 22 22" class="bi bi-search" fill="info"
xmlns="http://www.w3.org/2000/svg"> xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" <path fill-rule="evenodd"
@ -168,6 +168,7 @@
<script src="scripts/tsUtil.js"></script> <script src="scripts/tsUtil.js"></script>
<script>loadTSTarget("themes.js");</script> <script>loadTSTarget("themes.js");</script>
<script>let help = loadTSTarget("help.js");</script> <script>let help = loadTSTarget("help.js");</script>
<script>loadTSTarget("search.js");</script>
<script src="scripts/index_app.js"></script> <script src="scripts/index_app.js"></script>
</html> </html>

@ -2,7 +2,7 @@ const path = require('path');
const factory = require(path.join(appDir, 'viewFactory')) const factory = require(path.join(appDir, 'viewFactory'))
function loadDocuments() { function loadDocuments() {
factory.buildWebCardsFromConfig("resources-landing-page.json"); factory.buildUiFromConfig("resources-landing-page.json");
} }
loadDocuments(); loadDocuments();

@ -287,3 +287,8 @@ hr {
border: 0; border: 0;
border-top: 1px solid rgba(0, 0, 0, 0.1); border-top: 1px solid rgba(0, 0, 0, 0.1);
} }
.highlight {
color: map-get($theme-colors, highlight-text-color);
background-color: map-get($theme-colors, highlight-background);
}

@ -52,6 +52,8 @@ $theme-colors: (
"helpmenudropdowntext": #9d9d9d, "helpmenudropdowntext": #9d9d9d,
"helpmenudropdowntexthover": #a8a8a8, "helpmenudropdowntexthover": #a8a8a8,
"helpmenudropdownbghover": #5c5c66, "helpmenudropdownbghover": #5c5c66,
"highlight-text-color": #000,
"highlight-background": #ece665,
); );
.theme-button{ .theme-button{

@ -53,6 +53,8 @@ $theme-colors: (
"helpmenudropdowntext": #3f4a5a, "helpmenudropdowntext": #3f4a5a,
"helpmenudropdowntexthover": #080404, "helpmenudropdowntexthover": #080404,
"helpmenudropdownbghover": #f2f2f2, "helpmenudropdownbghover": #f2f2f2,
"highlight-text-color": #000,
"highlight-background": #ece665,
); );
.theme-button{ .theme-button{

@ -2,8 +2,8 @@
<div class="col-md-4 mb-4 web-card" id="{{{id}}}"> <div class="col-md-4 mb-4 web-card" id="{{{id}}}">
<div class="card mb-4 h-100 shadow-sm web-card-background"> <div class="card mb-4 h-100 shadow-sm web-card-background">
<div class="card-body d-flex flex-column text-center"> <div class="card-body d-flex flex-column text-center">
<h6 class="card-text text-header" style="text-align:center">{{title}}</h6> <h6 class="card-text text-header" style="text-align:center">{{{title}}}</h6>
<p class="card-text text-paragraph text-align-left">{{description}} </p> <p class="card-text text-paragraph text-align-left">{{{description}}} </p>
<div class="d-inline-block mt-auto mx-auto justify-content-between align-items-center web-card-image-background"> <div class="d-inline-block mt-auto mx-auto justify-content-between align-items-center web-card-image-background">
<img id="collapse-image" class="rounded-circle mx-auto d-block img-fluid" <img id="collapse-image" class="rounded-circle mx-auto d-block img-fluid"
src="{{{imgPath}}}" alt="{{{altText}}}" src="{{{imgPath}}}" alt="{{{altText}}}"

@ -108,12 +108,12 @@ export class DocumentDirectory {
root: DirectoryNode; root: DirectoryNode;
getCards(): Map<String, object[]> { getCards(): Map<string, object[]> {
return DocumentDirectory.walkCards(this.root); return DocumentDirectory.walkCards(this.root);
} }
private static walkCards(d: DirectoryNode): Map<String, object[]> { private static walkCards(d: DirectoryNode): Map<string, object[]> {
let cardsByCategory = new Map<String, object[]>(); let cardsByCategory = new Map<string, object[]>();
for (let i = 0, l = d.children.length; i < l; i++) { for (let i = 0, l = d.children.length; i < l; i++) {
let child = d.children[i]; let child = d.children[i];
if (child instanceof DirectoryNode) { if (child instanceof DirectoryNode) {
@ -151,7 +151,7 @@ export class DocumentDirectory {
return cardsByCategory; return cardsByCategory;
} }
private static mergeMaps(a: Map<String, Object[]>, b: Map<String, Object[]>) { private static mergeMaps(a: Map<string, Object[]>, b: Map<string, Object[]>) {
let keys = Object.keys(b); let keys = Object.keys(b);
for (let z in keys) { for (let z in keys) {
let key = keys[z]; let key = keys[z];
@ -180,7 +180,7 @@ export class FileNode {
this.parent = parent; this.parent = parent;
} }
static loadAltProps(path: String): object { static loadAltProps(path: string): object {
let props = {}; let props = {};
let jsonPath = path + ".json" let jsonPath = path + ".json"
if (fs.existsSync(jsonPath)) { if (fs.existsSync(jsonPath)) {
@ -225,7 +225,7 @@ export class FileNode {
return cardObj return cardObj
} }
getTitle(): String { getTitle(): string {
let name = path.basename(this.filePath); let name = path.basename(this.filePath);
let ext = path.extname(name); let ext = path.extname(name);
let cName = name.replace(ext, ""); let cName = name.replace(ext, "");
@ -289,7 +289,7 @@ export class DirectoryNode extends FileNode {
return false return false
} }
getCategory(): String { getCategory(): string {
let rawName = path.basename(this.filePath); let rawName = path.basename(this.filePath);
let parts = rawName.split("-"); let parts = rawName.split("-");
for (let i = 0, l = parts.length; i < l; i++) { for (let i = 0, l = parts.length; i < l; i++) {

@ -0,0 +1,129 @@
import {Configurator, DocumentDirectory} from "./fileutils";
import * as path from "path";
import {buildCardsFromConfig, buildUiFromConfig} from "./viewFactory";
function register() {
let searchBar = $("#searchfield");
let searchButton = $("#searchbutton");
searchBar.on("keyup", (evt) => {
if ("Enter" === evt.code) {
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
} else {
search(term);
}
}else{
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
}
}
});
searchButton.on("click", ()=>{
let term = searchBar.val().toString();
if (!term || 0 === term.length) {
reset()
} else {
search(term);
}
})
}
function reset(){
buildUiFromConfig("resources-landing-page.json");
}
function search(term: string) {
let webcards = getWebCardsWithSearchTerm(term);
let fileCards = getFileCardsWithSearchTerm(term);
buildCardsFromConfig(webcards, fileCards);
}
function getFileCardsWithSearchTerm(term): Map<string, object> {
let map = new Map<string, object>()
let directoryPath = path.join(__dirname, "../assets/resources");
let fileCards = new DocumentDirectory(directoryPath).getCards();
console.log(fileCards);
for (let [key, value] of fileCards) {
for (let card of value) {
if (cardContainsTerm(term, card)) {
addToFileMap(map, key, highlightCardTerm(term, card));
}
}
}
return map;
}
function getWebCardsWithSearchTerm(term): object {
let map = {};
let elementConfig = Configurator.loadAppConfig("resources-landing-page.json");
console.log(elementConfig);
let containerKeys = Object.keys(elementConfig);
for (let i = 0, l = containerKeys.length; i < l; i++) {
let containerKey = containerKeys[i];
let container = elementConfig[containerKey];
let categoryKeys = Object.keys(container);
console.log()
for (let categoryIdx in categoryKeys) {
let categoryKey = categoryKeys[categoryIdx]
let category = container[categoryKey];
let cards = category.cards;
for (let j = 0, k = cards.length; j < k; j++) {
let card = cards[j];
if (cardContainsTerm(term, card)) {
addToWebMap(map, containerKey, categoryKey, category["description"], highlightCardTerm(term, card));
}
}
}
}
return map;
}
function addToWebMap(map: object, containerKey: string, categoryKey: string, categoryDescription: string, card: object) {
let container = map[containerKey];
if (!container) {
container = {};
}
let category = container[categoryKey];
if (!category) {
category = {"description": categoryDescription, "cards": []}
}
category["cards"].push(card);
container[categoryKey] = category;
map[containerKey] = container;
}
function addToFileMap(map: Map<string, object>, categoryKey: string, card) {
if (!map.get(categoryKey)) {
map.set(categoryKey, []);
}
let cards = map.get(categoryKey) as Array<object>;
cards.push(card);
map.set(categoryKey, cards);
}
function cardContainsTerm(term: string, card: object): boolean {
let titleContains = card["title"].toLowerCase().includes(term.toLowerCase())
let descriptionContains = card["description"].toLowerCase().includes(term.toLowerCase())
return titleContains || descriptionContains;
}
function highlightCardTerm(term: string, card: object): object {
let regexTerm = escapeRegExp(term);
let pattern = new RegExp(regexTerm, 'ig');
card["title"] = card["title"].replace(pattern, `<span class="highlight">$&</span>`);
card["description"] = card["description"].replace(pattern, `<span class="highlight">$&</span>`);
return card;
}
function escapeRegExp(term: string): string {
return term.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
register()

@ -49,18 +49,22 @@ export function buildFileCard(elem: JQuery<HTMLElement>, obj, append: boolean =
}); });
} }
export function buildWebCardsFromConfig(configName: string) { export function buildUiFromConfig(configName: string){
let elementConfig = Configurator.loadAppConfig(configName); let elementConfig = Configurator.loadAppConfig(configName);
let $ = require('jquery')
let containers = Object.keys(elementConfig);
let directoryPath = path.join(__dirname, "../assets/resources"); let directoryPath = path.join(__dirname, "../assets/resources");
let fileCards = new DocumentDirectory(directoryPath).getCards(); let fileCards = new DocumentDirectory(directoryPath).getCards();
for (let i = 0, l = containers.length; i < l; i++) { buildCardsFromConfig(elementConfig, fileCards);
}
export function buildCardsFromConfig(elementConfig: object, fileCards: Map<string, object>) {
let $ = require('jquery')
let containers = Object.keys(elementConfig);
for (let i = 0, l = containers.length; i < l; i++) {
let containerName = containers[i]; let containerName = containers[i];
let containerObject = elementConfig[containerName]; let containerObject = elementConfig[containerName];
let containerElem = $(`#${containerName}`); let containerElem = $(`#${containerName}`);
containerElem.html("")
let containerCategories = Object.keys(containerObject); let containerCategories = Object.keys(containerObject);
for (let j = 0, m = containerCategories.length; j < m; j++) { for (let j = 0, m = containerCategories.length; j < m; j++) {
@ -86,6 +90,22 @@ export function buildWebCardsFromConfig(configName: string) {
let view = $(`#${categoryKey}-container`); let view = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`); let collapseButton = $(`#${categoryKey}-collapser`);
setCollapseOnElement(collapseButton, categoryKey);
for (let j in files) {
let file = files[j];
buildFileCard(view, file, true, $)
}
for (let j = 0, m = contentList.length; j < m; j++) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
}
function setCollapseOnElement(collapseButton: JQuery<HTMLElement>, categoryKey: string){
collapseButton.on("click", () => { collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig; let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`); let collapsable = $(`#${categoryKey}-container`);
@ -105,21 +125,6 @@ export function buildWebCardsFromConfig(configName: string) {
let newDirection = direction === "up"? "down": "up"; let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`); collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
}); });
for (let j in files) {
let file = files[j];
buildFileCard(view, file, true, $)
}
for (let j = 0, m = contentList.length; j < m; j++) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
} }
export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) { export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {

Loading…
Cancel
Save