/**
* The X button that closes the Modal
*/
class DialogCancel extends Autowire {
get popup(){return this.getAny('ModalPopup')}
onclick(event){
// console.log("Cancel Dialog");
// console.log(this);
// console.log("Popup:",this.popup);
if (event.target==this.node)this.popup.hide();
}
}
DialogCancel.autowire('.ModalPopup .DialogX');
/**
* The full popup, this part includes the translucent overlay
*
*/
class ModalPopup extends DialogCancel {
/**
* Get an array of forms currently in the modal.
*/
get forms(){ return this.qa('form'); }
/**
* set the content to an html string before calling `show()`
*/
set content(content){
// console.log(this.node);
this.content_node.innerHTML = content;
}
get content_node(){
return this.node.querySelector('.ModalContent');
}
/**
* Simply fetch text from url
* @param url a url
*/
async get(url){
const request = new Request(url);
const response = await fetch(request);
const text = await response.text();
return text;
}
/**
* Simply fetch json from url
* @param url a url
*/
async getJson(url){
const request = new Request(url);
const response = await fetch(request);
const json= await response.json();
return json;
}
/**
* Setup a form to submit through javscript and provide a callback for the response of the submission
* @param formNode a `<form>` node
* @param handlerFunc a callable function that accepts `(ModalPopup, string ResponseText)`. ResponseText will be the response from submitting the form.
*/
handleForm(formNode, handlerFunc){
formNode.addEventListener('submit', this.formSubmitted.bind(this, handlerFunc));
}
/**
* submit the form via a `Request()` object & call the handler function
*
* @param handlerFunc a callable that accepts `(this modal object, response_text)`
* @param event the javascript event for a 'submit' event
*/
async formSubmitted(handlerFunc, event){
event.preventDefault();
const form = event.target;
const inputs = form.querySelectorAll('[name]');
const params = {};
for (const input of inputs){
if (input.type=='file'){
params[input.name] = input.files[0];
} else {
params[input.name] = input.value;
}
}
// console.log(params);
const response = await this.fetch(form.action, params, form.method);
const text = await response.text();
handlerFunc(this,text);
// console.log(await response.text());
// console.log(form);
}
__attach(){
// used for [tab] navigation
this.firstButton = this.node.querySelector('button:first-of-type');
// used for [tab] navigation
this.lastButton = this.node.querySelector('a:last-of-type');
// I think this just focuses the first button in a modal when the dialog is clicked on??
this.node.querySelector('.ModalDialog').addEventListener('click',
function(event){
if (event.target.tagName!='BUTTON'&&event.target.tagName!='A'){
this.querySelector('button').focus();
}
}
);
}
show(){
this.node.style.display = 'flex';
this.node.querySelector('button').focus();
}
/**
* Hide the modal & empty the content node.
*/
hide(){
this.node.style.display = 'none';
// this.branchSelector.node.focus();
this.node.querySelector('.ModalContent').innerHTML = '';
}
/**
* improves accessibility for keyboard-based navigation via [tab] & [space]
*/
onkeydown(event){
// close if escape key
if (event.keyCode===27){
this.hide();
}
const curButton = document.activeElement;
const isTab = (event.key === 'Tab');
const isSpace = (event.code === 'Space' || event.code === 32);
const isShift = event.shiftKey
if (isTab && isShift && curButton == this.firstButton){
this.lastButton.focus();
event.preventDefault();
event.stopPropagation();
} else if (isTab && !isShift && curButton == this.lastButton){
this.firstButton.focus();
event.preventDefault();
event.stopPropagation();
} else if (isSpace && (curButton.tagName.toUpperCase()=='A'||curButton.tagName.toUpperCase()=='BUTTON')){
// curButton.click();
event.preventDefault();
event.stopPropagation();
}
}
/**
* make spacebar work for clicking buttons
*/
onkeyup(event){
const isSpace = (event.code === 'Space' || event.code === 32);
const curButton = document.activeElement;
if (isSpace && (curButton.tagName.toUpperCase()=='A'||curButton.tagName.toUpperCase()=='BUTTON')){
curButton.click();
event.preventDefault();
event.stopPropagation();
}
}
}