Skip to content

Instantly share code, notes, and snippets.

@andrewgremlich
Created November 7, 2018 22:29
Show Gist options
  • Save andrewgremlich/83ec9d2cdf51e8e66212b443e2936e71 to your computer and use it in GitHub Desktop.
Save andrewgremlich/83ec9d2cdf51e8e66212b443e2936e71 to your computer and use it in GitHub Desktop.
Advanced Search Modal for detailed data
class AdvancedSearchModalStyles {
constructor() {
this.themeLightGreen = '#4ff7a8';
this.themeGreen = '#42ce8d';
this.themeDarkGreen = '#309b69';
this.modalItemStyles = {
input: modalContent =>
(modalContent.style.cssText = this.inputComponentStyle`border: 1px solid ${
this.themeDarkGreen
}; cursor: pointer; display: inline;`),
h2: modalContent => modalContent
};
this.inputComponentStyle = (strings, borderColor) =>
`padding: 10px;
display: block;
font-size: 20px;
height: 40px;
width: 200px;
border-radius: 10px;
outline: none;
margin: 10px;
${strings[0]} ${borderColor} ${strings[1]}`;
}
setStyles() {
this.modalInputElement.style.cssText = this.inputComponentStyle`border: 1px solid ${this.themeGreen};`;
this.modalActivateButton.style.cssText = this.inputComponentStyle`border: 1px solid ${
this.themeDarkGreen
}; cursor: pointer;`;
this.modal.style.cssText = `
padding: 25px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
width: ${window.innerWidth * 0.9}px;
height: ${window.innerHeight * 0.9}px;
border: 5px solid ${this.themeGreen};
border-radius: 50px;
background: ${this.themeLightGreen};`;
this.modalShade.style.cssText = `
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.75)`;
}
}
export default class AdvancedSearchModal extends AdvancedSearchModalStyles {
constructor(modalInputId, modalContents, fetchSrc) {
super();
this.modalInputElement = document.getElementById(modalInputId);
this.modalActivateButton = document.createElement('input');
this.modal = document.createElement('div');
this.modalShade = document.createElement('div');
this.modalContents = modalContents;
this.madeContents = [];
this.fetchSrc = fetchSrc;
this.advancedModalTitle = this.createModalTitle();
this.closeModal = this.createCloseModalButton();
this.submitModal = this.createSubmitModalButton();
this.resultTable = this.createResultTable();
this.initComponent();
}
initComponent() {
this.setStyles();
this.modalContentsFunction();
this.insertModalContents();
this.modalActivateButton.addEventListener('click', this.showModal(this.modal, this.modalShade));
this.modalActivateButton.type = 'button';
this.modalActivateButton.value = 'Advanced Search';
this.modalInputElement.parentNode.insertBefore(this.modalActivateButton, this.modalInputElement.nextSibling);
}
modalContentsFunction() {
for (let content of this.modalContents) {
const input = document.createElement(content.type);
input.placeholder = content.placeholder;
input.setAttribute('data-form-id', content.formId);
if (content.tip) {
input.title = content.tip;
}
this.madeContents.push(input);
}
}
createResultTable() {
const table = document.createElement('div');
table.id = 'resultsTable';
return table;
}
removeModal() {
return () => {
this.modal.remove();
this.modalShade.remove();
};
}
populateResultsTable(resultNames) {
const hot = new Tabulator(this.resultTable, {
height: 400,
data: resultNames,
layout: "fitColumns",
// pagination: "local",
columns: [
{formatter: 'rownum', align: "center", width: 40},
{title: "Name", field:"name", width: 150},
{title: "Birth Date", field:"birthDate", align: "center"},
{title: "Death Date", field:"deathDate", align: "center"},
],
rowClick: (e, row) => {
console.log(e, row);
window.alert('Selected row for form!')
}
})
this.modal.appendChild(this.resultTable);
}
handleModalSubmit() {
return async () => {
const requestBody = {};
for (let content of this.madeContents) {
if (content.localName === 'input') {
requestBody[content.getAttribute('data-form-id')] = content.value;
}
}
const data = await fetch(this.fetchSrc.getPersonBasedOnCriteria, {
method: 'POST',
body: JSON.stringify(requestBody),
headers: {
'Content-type': 'application/json'
}
});
const resultNames = await data.json();
this.populateResultsTable(resultNames);
};
}
insertModalContents() {
this.modal.appendChild(this.advancedModalTitle);
for (let modalContent of this.madeContents) {
const styleElement = this.modalItemStyles[modalContent.localName];
typeof styleElement === 'function'
? styleElement(modalContent)
: console.error('No case styles to handle element!');
this.modal.appendChild(modalContent);
}
this.modal.appendChild(this.closeModal);
this.modal.appendChild(this.submitModal);
}
createModalTitle() {
const advancedModalTitle = document.createElement('h2');
advancedModalTitle.appendChild(document.createTextNode('Advanced Search'));
return advancedModalTitle;
}
createCloseModalButton() {
const closeModal = document.createElement('input');
closeModal.type = 'button';
closeModal.value = 'Close';
closeModal.style.cssText = this.inputComponentStyle`border: 1px solid ${this.themeDarkGreen}; cursor: pointer;`;
closeModal.addEventListener('click', this.removeModal());
return closeModal;
}
createSubmitModalButton() {
const submitModal = document.createElement('input');
submitModal.type = 'button';
submitModal.value = 'Submit';
submitModal.style.cssText = this.inputComponentStyle`border: 1px solid ${
this.themeDarkGreen
}; cursor: pointer;`;
submitModal.addEventListener('click', this.handleModalSubmit());
return submitModal;
}
showModal() {
const modalInputElementParentNode = this.modalInputElement.parentNode;
const modalInputElementNextSibling = this.modalInputElement.nextSibling;
return () => {
modalInputElementParentNode.insertBefore(this.modalShade, modalInputElementNextSibling);
modalInputElementParentNode.insertBefore(this.modal, modalInputElementNextSibling);
};
}
}
/**
* Params
*
* 1. Id selector for input box.
* 2. Contents of modal box.
* - modalContents - what to be shown in modal.
* 3. fetch source of data.
*/
const individualModal = new AdvancedSearchModal('modalSearch', [
{
type: 'input',
placeholder: 'First Name',
formId: 'firstName'
},
{
type: 'input',
placeholder: 'Last Name',
formId: 'lastName'
},
{
type: 'input',
placeholder: 'Alternative Names',
formId: 'alternateNames',
tip: 'Separate by commas.'
},
{
type: 'input',
placeholder: 'Birth Date',
formId: 'birthDate'
},
{
type: 'input',
placeholder: 'Death Date',
formId: 'deathDate'
}
], {
getPersonBasedOnCriteria: 'http://localhost:3000/api/get/personBasedOnCriteria'
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment