<script>
const css = `
#favDialog {
position: relative;
padding-top: 2em;
}
#close {
position: absolute;
font-weight: 700;
right: 0;
top: 0;
padding: .5em;
cursor: pointer;
}
#close:hover {
background-color: #e3e3e3;
}
`;
const html = `
<dialog id="favDialog" open>
<span id="close">╳</span>
<slot name="my-content">Defaut Content</slot>
</dialog>
`;
customElements.define('my-popup', class extends HTMLElement {
constructor() {
super();
}
#myTemplate = document.createElement('template');
#shadow = this.attachShadow({ mode : 'open'});
#slot = null;
#render() {
const myTemplate = document.createElement('template');
myTemplate.innerHTML = `<style>${css}</style>${html}`
this.#shadow.appendChild(myTemplate.content.cloneNode(true));
this.#slot = this.#shadow.querySelector('slot[name=my-content]');
}
// part 3
#handleClose() {
this.parentNode.removeAttribute('open');
this.dispatchEvent(new Event('onPopupClose', { bubbles: true, composed: true }));
}
#handleCancel() {
this.dispatchEvent(new Event('onPopupCancel', { bubbles: true }));
}
#handleSubmit() {
const data = document.getElementById('favAnimal').value;
this.dispatchEvent(
new CustomEvent('onPopupSubmit', {
bubbles: true,
detail: {
selectedValue: data,
},
})
);
}
#addEvents() {
this.#shadow.getElementById('close').addEventListener('click', this.#handleClose);
this.#slot.addEventListener('slotchange', (e) => {
let form = this.#slot.assignedNodes()[0];
form.querySelector('#cancel').addEventListener('click', this.#handleCancel);
form.querySelector('#submit').addEventListener('click', this.#handleSubmit);
});
}
#removeEvents() {
this.#shadow.getElementById('close').removeEventListener('click', this.#handleClose);
this.#slot.addEventListener('slotchange', (e) => {
let form = this.#slot.assignedNodes()[0];
form.querySelector('#cancel').removeEventListener('click', this.#handleCancel);
form.querySelector('#submit').removeEventListener('click', this.#handleSubmit);
});
}
// EO: part 3
connectedCallback() {
this.#render();
this.#addEvents();
}
// part 3
disconnectedCallback() {
this.#removeEvents();
}
// EO: part 3
});
</script>
<body>
<my-popup>
<style>
my-popup .menu {
margin-top: 2em;
display: flex;
justify-content: space-between;
align-items: center;
}
.events-monitor {
margin: 1em auto;
width: 300px;
height: 200px;
max-height: 200px;
overflow-y: auto;
border: 1px solid red;
}
</style>
<form method="dialog" slot="my-content" onSubmit="return customSubmit(event);">
<section>
<p><label for="favAnimal">Favorite animal:</label>
<select id="favAnimal" name="favAnimal">
<option></option>
<option>Brine shrimp</option>
<option>Red panda</option>
<option>Spider monkey</option>
</select></p>
</section>
<div class="menu">
<button id="cancel">Cancel</button>
<button id="submit">Confirm</button>
</div>
</form>
</my-popup>
<div class="events-monitor">
<ul class="event-list"></ul>
</div>
<script>
function customSubmit(e) {
e.preventDefault();
return false;
}
function addEventToList(data) {
console.log('data', JSON.stringify(data));
document.querySelector('.event-list').innerHTML += `<li>${JSON.stringify(data)}</li>`;
}
const myPopup = document.querySelector('my-popup');
myPopup.addEventListener('onPopupCancel', (e) => addEventToList('cancel clicked'));
myPopup.addEventListener('onPopupClose', (e) => addEventToList('close clicked'));
myPopup.addEventListener('onPopupSubmit', (e) => addEventToList(e.detail));
</script>
</body>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.