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

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

@ -193,7 +193,7 @@ body {
.feedbackdropdown .dropdown-menu {
background-color: map-get($theme-colors, menudropdownfill);
font-size: 15px;
margin-bottom: 9 px;
margin-bottom: 9px;
color: map-get($theme-colors, activetextaccordion);
box-shadow: -1 1 3 1 #cccccc;
}
@ -287,3 +287,8 @@ hr {
border: 0;
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,
"helpmenudropdowntexthover": #a8a8a8,
"helpmenudropdownbghover": #5c5c66,
"highlight-text-color": #000,
"highlight-background": #ece665,
);
.theme-button{

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

@ -2,8 +2,8 @@
<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-body d-flex flex-column text-center">
<h6 class="card-text text-header" style="text-align:center">{{title}}</h6>
<p class="card-text text-paragraph text-align-left">{{description}} </p>
<h6 class="card-text text-header" style="text-align:center">{{{title}}}</h6>
<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">
<img id="collapse-image" class="rounded-circle mx-auto d-block img-fluid"
src="{{{imgPath}}}" alt="{{{altText}}}"

@ -108,12 +108,12 @@ export class DocumentDirectory {
root: DirectoryNode;
getCards(): Map<String, object[]> {
getCards(): Map<string, object[]> {
return DocumentDirectory.walkCards(this.root);
}
private static walkCards(d: DirectoryNode): Map<String, object[]> {
let cardsByCategory = new Map<String, object[]>();
private static walkCards(d: DirectoryNode): Map<string, object[]> {
let cardsByCategory = new Map<string, object[]>();
for (let i = 0, l = d.children.length; i < l; i++) {
let child = d.children[i];
if (child instanceof DirectoryNode) {
@ -151,7 +151,7 @@ export class DocumentDirectory {
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);
for (let z in keys) {
let key = keys[z];
@ -180,7 +180,7 @@ export class FileNode {
this.parent = parent;
}
static loadAltProps(path: String): object {
static loadAltProps(path: string): object {
let props = {};
let jsonPath = path + ".json"
if (fs.existsSync(jsonPath)) {
@ -225,7 +225,7 @@ export class FileNode {
return cardObj
}
getTitle(): String {
getTitle(): string {
let name = path.basename(this.filePath);
let ext = path.extname(name);
let cName = name.replace(ext, "");
@ -289,7 +289,7 @@ export class DirectoryNode extends FileNode {
return false
}
getCategory(): String {
getCategory(): string {
let rawName = path.basename(this.filePath);
let parts = rawName.split("-");
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 $ = require('jquery')
let containers = Object.keys(elementConfig);
let directoryPath = path.join(__dirname, "../assets/resources");
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 containerObject = elementConfig[containerName];
let containerElem = $(`#${containerName}`);
containerElem.html("")
let containerCategories = Object.keys(containerObject);
for (let j = 0, m = containerCategories.length; j < m; j++) {
@ -86,25 +90,7 @@ export function buildWebCardsFromConfig(configName: string) {
let view = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
let collapseImg = $(`#${categoryKey}-img`);
if ("none" === collapsable.css('display')) {
collapsable.css("display", "");
collapseButton.addClass("active");
} else {
collapsable.css("display", "none");
collapseButton.removeClass("active");
}
let srcImg = collapseImg.attr("src");
let groups = imageMatchRegex.exec(srcImg);
let direction = groups[1];
let theme = groups[2];
let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
});
setCollapseOnElement(collapseButton, categoryKey);
for (let j in files) {
let file = files[j];
@ -115,13 +101,32 @@ export function buildWebCardsFromConfig(configName: string) {
let content = contentList[j];
buildWebCard(view, content, true, $);
}
}
}
}
function setCollapseOnElement(collapseButton: JQuery<HTMLElement>, categoryKey: string){
collapseButton.on("click", () => {
let imageMatchRegex = /\.\.\/images\/chevron-(\w+)-(\w+)\.svg$/ig;
let collapsable = $(`#${categoryKey}-container`);
let collapseButton = $(`#${categoryKey}-collapser`);
let collapseImg = $(`#${categoryKey}-img`);
if ("none" === collapsable.css('display')) {
collapsable.css("display", "");
collapseButton.addClass("active");
} else {
collapsable.css("display", "none");
collapseButton.removeClass("active");
}
let srcImg = collapseImg.attr("src");
let groups = imageMatchRegex.exec(srcImg);
let direction = groups[1];
let theme = groups[2];
let newDirection = direction === "up"? "down": "up";
collapseImg.attr("src", `../images/chevron-${newDirection}-${theme}.svg`);
});
}
export function buildWebCard(elem: JQuery<HTMLElement>, obj, append: boolean = false, $: any = require('jquery')) {
let model = new CardModel(
obj["title"],

Loading…
Cancel
Save