Created
November 7, 2018 22:29
-
-
Save andrewgremlich/83ec9d2cdf51e8e66212b443e2936e71 to your computer and use it in GitHub Desktop.
Advanced Search Modal for detailed data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
}; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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