I have function, which create popup similar as alert, confirm or prompt. Problem occurs when is called new popup (any type), then is destroyed callback in first call (prompt value)
PoppyPopup.prompt('Type your name', 'User control', {}, function(value) {
PoppyPopup.alert('Welcome ' + value); //<-- value is id of second popup
});
PoppyPopup.alert('Hi, this is a PopUp!', 'With title!');
DEMO: https://jsfiddle.net/yojz8sb3/
Edit: When is call one time, it's OK, I really dont know where is problem.
Well, the short answer is because PoppyPopup isn't designed to handle having more than one popup open at a time.
popupType is shared between all popups so when you open the alert popup it sets popupType to ALERT and so when the prompt popup's accept callback is called it's handled as if it's an ALERT type popup.
One (fairly hacky) solution is to remove var popupType = null; and instead pass popupType to the Popup constructor as a 4th argument. Then you can change
PoppyPopup.accept(basePopup.id, options);
to
PoppyPopup.accept(basePopup.id, options, popupType);
in Popup function.
And change
accept: function(popupId, options) {
to
accept: function(popupId, options, popupType) {
that way the popup type is associated with the popup instance instead of being shared among all popups.
Here is a working example: https://jsfiddle.net/0xpz7f9L/
However my answer above doesn't fix the issue that clicking the accept button appears to close a random popup (obviously not ideal). I'd recommend rewriting the whole thing to simplify it and make it easier to read/understand. Also this sort of thing traditionally uses promises instead of callbacks.
Here is how I would rewrite it:
const PoppyPopup = (function() {
let nextPopupId = 0;
return {
alert: function(message, title, options) {
const realOptions = buildOptionsFrom(options);
const popupElem = buildPopupElem(title, message, realOptions, false, false);
const promise = new Promise(resolve => {
popupElem.querySelector('.accept').onclick = resolve;
});
promise.finally(() => close(popupElem, realOptions.removeWhenClosed));
document.querySelector('body').appendChild(popupElem);
return promise;
},
confirm: function(message, title, options) {
const realOptions = buildOptionsFrom(options);
const popupElem = buildPopupElem(title, message, realOptions, false, true);
const promise = new Promise((resolve, reject) => {
popupElem.querySelector('.accept').onclick = resolve;
popupElem.querySelector('.cancel').onclick = reject;
});
promise.finally(() => close(popupElem, realOptions.removeWhenClosed));
document.querySelector('body').appendChild(popupElem);
return promise;
},
prompt: function(message, title, options) {
const realOptions = buildOptionsFrom(options);
const popupElem = buildPopupElem(title, message, realOptions, true, true);
const promise = new Promise((resolve, reject) => {
popupElem.querySelector('.accept').onclick = () => resolve(popupElem.querySelector('input').value);
popupElem.querySelector('.cancel').onclick = reject;
});
promise.finally(() => close(popupElem, realOptions.removeWhenClosed));
document.querySelector('body').appendChild(popupElem);
return promise;
}
};
function close(popupElem, removeWhenClosed) {
popupElem.classList.remove('show');
popupElem.addEventListener('transitionend', function(e) {
if (e.propertyName === 'opacity' && removeWhenClosed) {
popupElem.parentNode.removeChild(popupElem);
}
});
}
function buildOptionsFrom(options) {
return Object.assign({
showBackground: true,
removeWhenClosed: true,
width: '400px'
}, options || {});
}
function buildPopupElem(title, message, options, provideInput, provideCancel) {
const basePopupDiv = document.createElement("DIV");
basePopupDiv.className = "poppy-popup show";
basePopupDiv.id = nextPopupId++;
if (options.showBackground) {
const backgroundDiv = document.createElement("DIV");
backgroundDiv.className = "poppy-popup-background";
basePopupDiv.appendChild(backgroundDiv);
}
const containerDiv = document.createElement("DIV");
containerDiv.className = "poppy-popup-container";
containerDiv.style.width = options.width;
containerDiv.style.height = options.height;
if (title) {
const headerTitleDiv = document.createElement("DIV");
headerTitleDiv.className = "poppy-popup-title-text";
headerTitleDiv.innerHTML = title;
const headerDiv = document.createElement("DIV");
headerDiv.className = "poppy-popup-header";
headerDiv.appendChild(headerTitleDiv);
containerDiv.appendChild(headerDiv);
}
const contentDiv = document.createElement("DIV");
contentDiv.className = "poppy-popup-content";
contentDiv.innerHTML = message;
if (provideInput) {
const input = document.createElement("INPUT");
input.type = "text";
contentDiv.appendChild(input);
}
const acceptLink = document.createElement("A");
acceptLink.className = 'accept';
acceptLink.href = "#";
acceptLink.innerHTML = "<i class='material-icons'>done</i> OK";
const acceptSpan = document.createElement("SPAN");
acceptSpan.className = "poppy-popup-accept";
acceptSpan.appendChild(acceptLink);
const buttonsDiv = document.createElement("DIV");
buttonsDiv.className = "poppy-popup-buttons";
buttonsDiv.appendChild(acceptSpan);
if (provideCancel) {
const cancelLink = document.createElement("A");
cancelLink.className = "cancel";
cancelLink.href = "#";
cancelLink.innerHTML = "<i class='material-icons'>close</i> Cancel";
const cancelSpan = document.createElement("SPAN");
cancelSpan.className = "poppy-popup-cancel";
cancelSpan.appendChild(cancelLink);
buttonsDiv.appendChild(cancelSpan);
}
containerDiv.appendChild(contentDiv);
containerDiv.appendChild(buttonsDiv);
basePopupDiv.appendChild(containerDiv);
return basePopupDiv;
} //end of buildPopupElem()
})();
PoppyPopup.prompt('Type your name', 'User control').then(value => {
PoppyPopup.alert('Welcome ' + value).then(() => {
PoppyPopup.confirm('And just for completeness, confirm?')
.then(() => alert('accepted'), () => alert('rejected'));
});
});
PoppyPopup.alert('Hi, this is a PopUp!', 'With title!');
*, *:before, *:after {
box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
font-family: 'Roboto', sans-serif;
font-size: 16px;
background-color: #eeeeee; }
.poppy-popup {
position: fixed;
top: 0;
left: 0;
z-index: 1000;
width: 100vw;
height: 100vh;
display: -ms-flexbox;
display: flex;
-ms-flex-pack: center;
justify-content: center;
-ms-flex-align: center;
align-items: center;
font-size: 16px;
opacity: 0;
transition: opacity .3s; }
.poppy-popup.show {
opacity: 1; }
.poppy-popup > .poppy-popup-background {
position: fixed;
top: 0;
left: 0;
z-index: 1010;
background-color: rgba(0, 0, 0, 0.5);
width: 100%;
height: 100%; }
.poppy-popup > .poppy-popup-container {
max-width: 90%;
max-height: 90%;
width: 100%;
position: relative;
z-index: 1020;
border-radius: 3px;
box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.3); }
.poppy-popup > .poppy-popup-container > .poppy-popup-header {
background-color: #FFFFFF;
color: #222222;
height: 50px;
width: 100%;
position: relative;
border-top-left-radius: 3px;
border-top-right-radius: 3px; }
.poppy-popup > .poppy-popup-container > .poppy-popup-header > .poppy-popup-title-text {
width: 100%;
max-height: 50px;
font-size: 1.5em;
text-align: center;
line-height: 50px;
text-overflow: ellipsis;
font-weight: bold;
overflow: hidden;
white-space: nowrap; }
.poppy-popup > .poppy-popup-container > .poppy-popup-content {
background-color: #FFFFFF;
width: 100%;
padding: 10px 20px;
border-left: 1px solid #DDDDDD;
border-right: 1px solid #DDDDDD;
overflow: auto; }
.poppy-popup > .poppy-popup-container > .poppy-popup-content > input[type="text"] {
background-color: transparent;
border-width: 0;
border-bottom: 2px solid #CCCCCC;
outline: none;
font-size: 1.3em;
width: 100%;
margin-top: 20px;
padding: 5px;
box-shadow: none;
transition: border-bottom .2s; }
.poppy-popup > .poppy-popup-container > .poppy-popup-content > input[type="text"]:focus {
border-bottom: 2px solid #2088AD; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons {
width: 100%;
height: 50px;
padding: 0 10px;
background-color: #FFFFFF;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
overflow: hidden; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept, .poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel {
width: 120px;
display: block;
float: right;
color: #2088AD; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept > a, .poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel > a {
display: block;
color: inherit;
text-decoration: none;
text-align: center;
padding: 10px 0;
border-radius: 3px;
transition: background-color .2s, box-shadow .1s; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept > a:active, .poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel > a:active {
box-shadow: inset 0 0 5px 1px rgba(0, 0, 0, 0.3); }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept > a > i, .poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel > a > i {
vertical-align: middle;
margin-top: -3px; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept {
right: 0;
color: #2088AD; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-accept > a:hover {
background-color: rgba(0, 0, 0, 0.1); }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel {
left: 0;
color: #2088AD; }
.poppy-popup > .poppy-popup-container > .poppy-popup-buttons > .poppy-popup-cancel > a:hover {
background-color: rgba(0, 0, 0, 0.1); }
Note: The css is unchanged.
Related
I have a function that turns an array into modal window links as a template literal.
The code that creates the links works fine outside of the function
But once it gets rendered in the function it no longer works. I can't find any errors, but it does NOT work.
However, if I copy the HTML that the function renders and save that as actual HTML, that works fine on its own.
A good chunk of the JavaScript portion of the code is posted below. A full version is on Codepen.
There are two sections in the example on Codepen:
The first section has the code as it's rendered by the function.
The second section is copied from the Elements tab in Developer Tools and saved as actual HTML.
"use strict";
const modalBtns = document.querySelectorAll(".modal-button");
const modalWin = document.querySelector(".modal-window");
const closeBtn = document.querySelector(".close-modal");
const modal_iframe = document.getElementById("modal_iframe");
modalBtns.forEach((item) => {
item.addEventListener("click", function (e) {
let modal = e.currentTarget;
if (modal.dataset.target) {
let modalID = modal.dataset.target;
document.getElementById(modalID).style.display = "block";
}
if (modal.dataset.iframe) {
modal_iframe.src = modal.dataset.iframe;
document
.querySelector(".button-footer")
.addEventListener("click", function () {
window.open(modal.dataset.iframe, "_blank");
});
}
if (modal.dataset.header) {
document.querySelector(
".modal-header"
).innerHTML = `<h1>${modal.dataset.header}</h1>`;
}
if (modal.dataset.dimensions) {
document
.querySelector(".modal-window")
.setAttribute("style", modal.dataset.dimensions);
}
function loadIframe() {
let frame = document.getElementById("modal_window");
frame.style.height =
frame.contentWindow.document.body.scrollHeight + "px";
}
if (document.querySelector("#modal_window")) {
setTimeout(function () {
loadIframe;
}, 2000);
}
if (modal.dataset.reload && modal.dataset.reload === "1") {
document
.querySelector(".close-modal")
.addEventListener("click", function (e) {
console.log("parent.location.reload() pending...");
parent.location.reload();
});
}
/*======= All EventListeners Below Close Modal ================*/
closeBtn.addEventListener("click", function (e) {
document.querySelector(".modal-background").style.display = "none";
});
window.addEventListener("click", function (e) {
if (e.currentTarget === document.querySelector(".modal-background")) {
document.querySelector(".modal-background").style.display = "none";
}
});
document.body.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
document.querySelector(".modal-background").style.display = "none";
}
});
});
});
const main = document.querySelector("main");
const modal_links = [
{
link: "https://notation.netcentrx.net/staff/",
header: "Musical Staff",
thb: "notation",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
},
{
link: "https://wsl.netcentrx.net/",
header: "WSL Commands",
thb: "wsl",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
}
];
let modalLink = "";
function createModalLinks(
link,
modalID,
header,
img,
w_h = "width:90vw;height:600px",
reload = "0"
) {
modalLink = `
<a href="javascript:void(0)" class="modal-button" onclick="console.log('onclick handler:${link}');" data-header="${header}" data-target="${modalID}" data-iframe="${link}" data-dimensions="${w_h};margin-top:20px" data-reload="${reload}">
<img src="https://resume.netcentrx.net/examples/${img}.jpg" title="${img}" width="50">
</a>
`;
return modalLink;
}
let theLinks = "";
modal_links.forEach((item) => {
theLinks += createModalLinks(
item.link,
"modal_window",
item.header,
item.thb,
item.w_h,
item.reload
);
});
main.innerHTML = theLinks;
My apologies in advance for it not being stripped down to just the bare minimum. But in order to replicate the problem, it required more code than it probably should have had. I've been reworking this for the better part of a day without any insight as to what the real problem is. I've been creating functions using template literals just like this for years now, usually with a high success rate. Whatever the problem is, I need to know so I can get past it. The only anomaly that I spotted is that–in the version on Codepen–the only thing that doesn't work in that version is once the modal is displayed clicking on the background does not dismiss the modal like it does elsewhere. If that's significant as to what the problem may be, I'm not sure what the connection is.
Usually when I take the time to painstakingly write everything out like this I typically either spot the problem or figure out an alternative solution so there's no need to actually post a question, but this does not appear to be one of those times. As always, your help is very much appreciated!
The issue appears to just be timing. Your code is executed in order, and the first part gets all of the modal buttons on the page and sets the appropriate event listeners. Then the second part of your code adds 2 modal buttons, which were not present earlier.
By simply wrapping the first part of your code in a function and calling it later (or swapping the order of those two parts of code), everything works as expected.
"use strict";
const _InitModal = () => {
const modalBtns = document.querySelectorAll(".modal-button");
const modalWin = document.querySelector(".modal-window");
const closeBtn = document.querySelector(".close-modal");
const modal_iframe = document.getElementById("modal_iframe");
modalBtns.forEach((item) => {
item.addEventListener("click", function (e) {
console.log("e.currentTarget = " + e.currentTarget);
let modal = e.currentTarget;
console.log("modal = " + modal);
if (modal.dataset.target) {
let modalID = modal.dataset.target;
console.log("modal.dataset.target = " + modal.dataset.target);
document.getElementById(modalID).style.display = "block";
}
if (modal.dataset.iframe) {
modal_iframe.src = modal.dataset.iframe;
document
.querySelector(".button-footer")
.addEventListener("click", function () {
window.open(modal.dataset.iframe, "_blank");
});
}
if (modal.dataset.header) {
document.querySelector(
".modal-header"
).innerHTML = `<h1>${modal.dataset.header}</h1>`;
console.log(`modal.dataset.header = ${modal.dataset.header}`);
}
if (modal.dataset.dimensions) {
document
.querySelector(".modal-window")
.setAttribute("style", modal.dataset.dimensions);
}
function loadIframe() {
let frame = document.getElementById("modal_window");
frame.style.height =
frame.contentWindow.document.body.scrollHeight + "px";
}
if (document.querySelector("#modal_window")) {
setTimeout(function () {
loadIframe;
}, 2000);
}
// e.preventDefault();
if (modal.dataset.reload && modal.dataset.reload === "1") {
document
.querySelector(".close-modal")
.addEventListener("click", function (e) {
console.log("parent.location.reload() pending...");
parent.location.reload();
});
}
/*======= All EventListeners Below Close Modal ================*/
closeBtn.addEventListener("click", function (e) {
document.querySelector(".modal-background").style.display = "none";
});
window.addEventListener("click", function (e) {
console.log("e.currentTarget = " + e.currentTarget);
if (e.currentTarget === document.querySelector(".modal-background")) {
document.querySelector(".modal-background").style.display = "none";
}
});
document.body.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
console.log("e=" + e);
document.querySelector(".modal-background").style.display = "none";
}
});
});
});
}
const main = document.querySelector("main");
const modal_links = [
{
link: "https://notation.netcentrx.net/staff/",
header: "Musical Staff",
thb: "notation",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
},
{
link: "https://wsl.netcentrx.net/",
header: "WSL Commands",
thb: "wsl",
w_h: "min-width:60vw;max-width:600px;height:650px",
reload: 0
}
];
function createModalLinks(
link,
modalID,
header,
img,
w_h = "width:90vw;height:600px",
reload = "0"
) {
let modalLink = "";
modalLink = `
<a href="javascript:void(0)" class="modal-button" onclick="console.log('onclick handler:${link}');" data-header="${header}" data-target="${modalID}" data-iframe="${link}" data-dimensions="${w_h};margin-top:20px" data-reload="${reload}">
<img src="https://resume.netcentrx.net/examples/${img}.jpg" title="${img}" width="50">
</a>`;
return modalLink;
}
let theLinks = "";
modal_links.forEach((item) => {
theLinks += createModalLinks(
item.link,
"modal_window",
item.header,
item.thb,
item.w_h,
item.reload
);
});
main.innerHTML = theLinks;
_InitModal();
.modal-background {
font-family: sans-serif;
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: none;
overflow: auto;
background-color: rgba(0, 0, 0, 0.9);
z-index: 9999;
background: rgba(55, 55, 55, 0.6);
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
}
.modal-window {
position: relative;
background-color: #ffffff;
width: 50%;
margin: 10% auto;
border-radius: 0.5rem;
padding: 0.75rem;
border: 1px groove #ccc;
/* box-shadow: 1px 1px 1px #999, 2px 2px 2px #000; */
}
.close-modal:hover,
.close-modal:focus {
color: rgba(255, 255, 255, 1);
cursor: pointer;
background: red;
transition: 1s;
text-shadow: 1px 1px 1px #999, 2px 2px 2px #000;
}
button.close-modal {
position: absolute;
top: -0.75rem;
right: -0.75rem;
padding: 0.05rem 0.75rem;
background: #999;
color: #ccc;
border-radius: 50%;
border: none;
outline: none;
-webkit-transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);
-webkit-animation-name: animatebottom;
-webkit-animation-duration: 1.5s;
animation-name: animatebottom;
animation-duration: 1.5s;
}
button.close-modal::before {
content: "\D7";
font-size: 2rem;
}
.modal-window {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
-webkit-animation-name: animatetop;
-webkit-animation-duration: 0.5s;
animation-name: animatetop;
animation-duration: 0.5s;
}
.modal-header {
height: 30px;
text-align: center;
width: 100%;
background: #fff;
padding: 0.2rem;
}
.modal-header h1 {
font-size: 1.1rem;
}
.modal-footer {
height: 20px;
text-align: center;
width: 100%;
background: #fff;
padding: 0.2rem;
}
.modal-content {
background-color: #fff;
height: calc(100% - 70px);
border-radius: 0.5rem;
border: 0.1rem groove #ddd;
overflow: hidden;
}
.button-footer {
background: #fff;
border-radius: 0.5rem;
border: 1px outset #aaa;
padding: 0.2rem;
color: #999;
transition: 1s;
cursor: pointer;
}
.button-footer:hover {
background: #fdfdfd;
color: #555;
border: 1px inset #ddd;
text-shadow: 0.05rem 0.05rem 0.05rem #ccc, 0.055rem 0.055rem 0.055rem #999,
0.06rem 0.06rem 0.06rem #333;
transition: 1s;
}
.close-btn:hover {
color: white;
background: #f00;
cursor: pointer;
}
#modal_iframe {
width: 100%;
height: 100%;
}
button.modal-button {
border-radius: 0.5rem;
border: 0px solid #aaa;
padding: 0;
cursor: pointer;
}
.modal-button-img {
border-radius: 0.5rem;
border: 0.1rem groove #444;
cursor: pointer;
}
.sepia:hover {
filter: sepia(150%);
}
/*
.none {
display: none;
}
*/
#-webkit-keyframes animatetop {
from {
top: -300px;
opacity: 0;
}
to {
top: 0;
opacity: 1;
}
}
#keyframes animatetop {
from {
top: -300px;
opacity: 0;
}
to {
top: 0;
opacity: 1;
}
}
#-webkit-keyframes animatebottom {
from {
top: 0;
opacity: 1;
}
to {
bottom: -300px;
opacity: 0;
}
}
#keyframes animatebottom {
from {
top: 0;
opacity: 1;
}
to {
bottom: -300px;
opacity: 0;
}
}
.container {
border-radius: 0.5rem;
border: 1px solid #aaa;
max-width: 800px;
width: 500px;
margin: 0 auto;
text-align: center;
font-family: sans-serif;
}
main,
aside {
font-family: sans-serif;
max-width: 800px;
width: 500px;
margin: 0 auto;
text-align: center;
}
h2 {
text-align: center;
font-family: sans-serif;
font-weight: normal;
font-size: 1.2rem;
}
span {
font-size: 75%;
background: #ffff0055;
}
<div id="modal_window" class="modal-background">
<div class="modal-window">
<button class="close-modal" data-dismiss="modal"></button>
<div class="modal-header"></div>
<div class="modal-content">
<iframe src="#" id="modal_iframe" frameborder="0">If you'd have had a real browser, I wouldn't be boring you with this now...</iframe>
</div>
<div class="modal-footer"><button class="button-footer">Open In New Tab</button></div>
</div>
</div>
<div class="container">
<h2><code>main</code> Content Rendered By JavaScript</h2>
<main>
Main
</main>
<span>working now</span>
</div>
I need help to remove each note on dblclick and also remove from the notes array with filter method. We should use unique id with Math.random()
Here is my code
let notes = [];
const container = document.querySelector('.flex-cont')
const inputNote = document.getElementById('noteInput')
const addButton = document.getElementById('addNote')
let noteElement;
class Note {
constructor(description, id) {
this.description = description
this.id = id
}
}
addButton.addEventListener('click', postNote)
function postNote() {
let note = inputNote.value
let newNote = new Note(note, Math.random())
noteElement = document.createElement('div')
noteElement.classList.add('paper', 'pink')
noteElement.setAttribute('id', this.id)
let noteText = document.createElement('p')
noteText.textContent = note
noteElement.append(noteText)
let tape = document.createElement('div')
tape.classList.add('tape-section')
noteElement.append(tape)
noteElement.addEventListener('dblclick', () => {
// notes.filter(id => this.id != id )
// if (noteElement.id === this.id) {
const doDelete = confirm('Are you sure ?');
if (doDelete) {
noteElement.remove()
}
// }
})
container.appendChild(noteElement)
notes.push(newNote)
inputNote.value = '';
}
console.log(notes)
HTML and CSS are here
http://jsfiddle.net/30tjop4d/
let notes = [];
const container = document.querySelector('.flex-cont')
const inputNote = document.getElementById('noteInput')
const addButton = document.getElementById('addNote')
class Note {
constructor(description, id, element) {
this.description = description
this.id = id
this.element = element
}
}
addButton.addEventListener('click', postNote)
function postNote() {
let note = inputNote.value
noteElement = document.createElement('div')
noteElement.classList.add('paper', 'pink')
noteElement.setAttribute('id', this.id)
let noteText = document.createElement('p')
noteText.textContent = note
noteElement.append(noteText)
let tape = document.createElement('div')
tape.classList.add('tape-section')
noteElement.append(tape)
let newNote = new Note(note, Math.random(), noteElement)
notes.push(newNote)
noteElement.addEventListener('dblclick', () => {
// notes.filter(id => this.id != id )
// if (noteElement.id === this.id) {
const doDelete = confirm('Are you sure ?')
if (doDelete) {
const noteToRemove = notes.find(n => n.id === newNote.id)
noteToRemove.element.remove()
notes = notes.filter(n => n.id !== newNote.id)
console.log(notes.map(n => n.id))
}
// }
})
container.appendChild(noteElement)
inputNote.value = '';
}
console.log(notes)
:root {
--pink: #ecb2ba;
--pink-dark: #c6939a;
--tape-gray: #dbd8be;
--tape-edge-gray: #b7b49d;
--transparent: rgba(255, 255, 255, 0);
}
body {
text-align: center;
background-color: #1a2980;
font-family: sans-serif;
}
h1 {
text-align: center;
color: white;
}
.flex-cont {
padding: 30px;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-gap: 30px;
}
input,
button {
display: inline-block;
margin: 2em auto;
padding: 0.5em 0.7em;
border: none;
border-radius: 0.2em;
/* width: 15em; */
font-size: 1.5em;
text-align: center;
box-shadow: 0 0 1em 0.25em rgba(0, 0, 0, 0.2);
}
:root {
--pink: #ecb2ba;
--pink-dark: #c6939a;
--tape-gray: #dbd8be;
--tape-edge-gray: #b7b49d;
--transparent: rgba(255, 255, 255, 0);
}
.pink {
--paper-color: var(--pink);
--paper-dark: var(--pink-dark);
--shadow-size: 1px;
--transparent: rgba(236, 178, 186, 0);
}
.blue {
--paper-color: #d5e0f9;
--paper-dark: #c2d0ea;
--shadow-size: 3px;
--transparent: rgba(213, 224, 249, 0);
}
.paper {
position: relative;
background: linear-gradient(
to bottom right,
var(--paper-dark),
20%,
var(--transparent)
),
var(--paper-color);
min-width: 250px;
min-height: 130px;
display: flex;
align-items: center;
justify-content: center;
font-family: "Caveat", cursive;
font-size: 2rem;
box-shadow: var(--shadow-size) var(--shadow-size) 2px var(--paper-dark);
margin: auto;
margin-top: 50px;
}
.paper::after {
content: "";
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(
var(--transparent),
50%,
var(--paper-dark),
51%,
var(--transparent)
),
linear-gradient(
to right,
var(--transparent),
50%,
var(--paper-dark),
51%,
var(--transparent)
);
}
.tape-section {
position: absolute;
width: 100%;
}
.top-tape {
position: absolute;
height: 4vmin;
top: -5px;
width: 110%;
background-color: var(--tape-gray);
border-right: 1px dotted var(--tape-edge-gray);
border-left: 1px dotted var(--tape-edge-gray);
opacity: 0.5;
}
.tape-section:first-of-type {
top: 0;
}
.tape-section:last-of-type {
bottom: 0;
}
.tape-section::before,
.tape-section::after {
content: "";
width: 10vmin;
height: 4vmin;
position: absolute;
background-color: var(--tape-gray);
opacity: 0.5;
border-right: 1px dotted var(--tape-edge-gray);
border-left: 1px dotted var(--tape-edge-gray);
}
.tape-section:last-of-type::after {
transform: rotate(-45deg);
right: -4vmin;
top: -3vmin;
}
.tape-section:first-of-type::before {
transform: rotate(-45deg);
left: -4vmin;
}
.tape-section:first-of-type::after {
transform: rotate(45deg);
right: -4vmin;
top: 0;
}
.tape-section:last-of-type::before {
transform: rotate(45deg);
left: -4vmin;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Notes</title>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<h1>Notes</h1>
<input type="text" id="noteInput" placeholder="enter your note" />
<button id="addNote">Add Note</button>
<div class="flex-cont">
<!-- <div class="paper pink">
<p>drink more water</p>
<div class="tape-section"></div>
</div> -->
</div>
<!-- <script src="./countries-db.js"></script> -->
<script src="./index.js"></script>
</body>
</html>
im trying to make a search bar for my website to redirect pepole on other pages of my website by selecting values from autocomplete suggestions, but when i select a suggestion (example:"Home") and hit search nothing happends, instead when i write the value (example:"chat") it works just fine and it redirects me to another page, my question is: what im doing wrong and why my autocompleted values are not seen by the searchbar?
Here is the code example for values "chat, Home, youtube"
function ouvrirPage() {
var a = document.getElementById("search").value;
if (a === "chat") {
window.open("/index.html");
}
if (a === "Home") {
window.open("/customizedalert.html");
}
if (a === "youtube") {
window.open("https://www.youtube.com/");
}
}
And here is the entire thing:
https://codepen.io/galusk0149007/pen/LYeXvww
Try this in your IDE : Clicking the search icon will navigate to your urls.
// getting all required elements
const searchWrapper = document.querySelector(".search-input");
const inputBox = searchWrapper.querySelector("input");
const suggBox = searchWrapper.querySelector(".autocom-box");
const icon = searchWrapper.querySelector(".icon");
let linkTag = searchWrapper.querySelector("a");
let webLink;
let suggestions = ['chat','home', 'youtube']
// if user press any key and release
inputBox.onkeyup = (e)=>{
let userData = e.target.value; //user enetered data
let emptyArray = [];
if(userData){
icon.onclick = ()=>{
webLink = `https://www.google.com/search?q=${userData}`;
linkTag.setAttribute("href", webLink);
linkTag.click();
}
emptyArray = suggestions.filter((data)=>{
//filtering array value and user characters to lowercase and return only those words which are start with user enetered chars
return data.toLocaleLowerCase().startsWith(userData.toLocaleLowerCase());
});
emptyArray = emptyArray.map((data)=>{
// passing return data inside li tag
return data = `<li>${data}</li>`;
});
searchWrapper.classList.add("active"); //show autocomplete box
showSuggestions(emptyArray);
let allList = suggBox.querySelectorAll("li");
for (let i = 0; i < allList.length; i++) {
//adding onclick attribute in all li tag
allList[i].setAttribute("onclick", "select(this)");
}
}else{
searchWrapper.classList.remove("active"); //hide autocomplete box
}
}
function select(element){
let selectData = element.textContent;
inputBox.value = selectData;
icon.onclick = ()=>{
webLink = `https://www.google.com/search?q=${selectData}`;
linkTag.setAttribute("href", webLink);
linkTag.click();
}
searchWrapper.classList.remove("active");
}
function showSuggestions(list){
let listData;
if(!list.length){
userValue = inputBox.value;
listData = `<li>${userValue}</li>`;
}else{
listData = list.join('');
}
suggBox.innerHTML = listData;
}
function ouvrirPage() {
var a = document.getElementById("search").value;
if (a === "chat") {
window.open("/index.html");
}
if (a === "Home") {
window.open("/customizedalert.html");
}
if (a === "youtube") {
window.open("https://www.youtube.com/");
}
}
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#200;300;400;500;600;700&display=swap');
*{
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Poppins', sans-serif;
}
body{
background: #544b8b;
padding: 0 20px;
}
::selection{
color: #fff;
background: #7c71bd;
}
.wrapper{
max-width: 450px;
margin: 150px auto;
}
.wrapper .search-input{
background: #fff;
width: 100%;
border-radius: 5px;
position: relative;
box-shadow: 0px 1px 5px 3px rgba(0,0,0,0.12);
}
.search-input input{
height: 55px;
width: 100%;
outline: none;
border: none;
border-radius: 5px;
padding: 0 60px 0 20px;
font-size: 18px;
box-shadow: 0px 1px 5px rgba(0,0,0,0.1);
}
.search-input.active input{
border-radius: 5px 5px 0 0;
}
.search-input .autocom-box{
padding: 0;
opacity: 0;
pointer-events: none;
max-height: 280px;
overflow-y: auto;
}
.search-input.active .autocom-box{
padding: 10px 8px;
opacity: 1;
pointer-events: auto;
}
.autocom-box li{
list-style: none;
padding: 8px 12px;
display: none;
width: 100%;
cursor: default;
border-radius: 3px;
}
.search-input.active .autocom-box li{
display: block;
}
.autocom-box li:hover{
background: #efefef;
}
.search-input .icon{
position: absolute;
right: 0px;
top: 0px;
height: 55px;
width: 55px;
text-align: center;
line-height: 55px;
font-size: 20px;
color: #644bff;
cursor: pointer;
}
<head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/>
</head>
<body>
<div class="wrapper">
<div class="search-input">
<a href="" target="_blank" hidden></a>
<input type="text" placeholder="Type to search..">
<div class="autocom-box">
</div>
<div class="icon" onclick="ouvrirPage()"><i class="fas fa-search"></i></div>
</div>
</div>
</body>
I'm looking for advice/tips on how to fix a function that is supposed to remove items from localStorage. I'm following a tutorial by John Smilga that I found on Youtube. Although I've modeled my code on his, apparently, I have missed something.
This function works perfectly well if I run it manually from the console and pass in the id of the item that I want to remove from localStorage.
function removeFromLocalStorage(id) {
console.log(id);
let storageItems = getLocalStorage();
console.log(storageItems);
storageItems = storageItems.filter(function(singleItem) {
if (singleItem.id !== id) {
return singleItem;
}
})
console.log(storageItems);
localStorage.setItem("list", JSON.stringify(storageItems));
}
However, when this function is triggered by the deleteItem() function, it refuses to remove the item from localStorage. It still works, there are a bunch of console.logs in it that track its execution, and I can check that it receives the correct item id as the argument, but for some reason it doesn't filter out the item that needs to be removed. I am completely lost and have no idea how to identify the problem. I can't debug it with console.logs as I usually do. I will be very grateful if you help me find the problem. Any advice will be appreciated.
In case the entire code is needed, please find it below.
const form = document.querySelector(".app__form");
const alert = document.querySelector(".app__alert");
const input = document.querySelector(".app__input");
const submitBtn = document.querySelector(".app__submit-btn");
const itemsContainer = document.querySelector(".app__items-container");
const itemsList = document.querySelector(".app__items-list");
const clearBtn = document.querySelector(".app__clear-btn");
let editElement;
let editFlag = false;
let editId = "";
form.addEventListener("submit", addItem);
clearBtn.addEventListener("click", clearItems);
function addItem(e) {
e.preventDefault();
const id = Math.floor(Math.random() * 9999999999);
if (input.value && !editFlag) {
const item = document.createElement("div");
item.classList.add("app__item");
const attr = document.createAttribute("data-id");
attr.value = id;
item.setAttributeNode(attr);
item.innerHTML = `<p class='app__item-text'>${input.value}</p>
<div class='app__item-btn-cont'>
<button class='app__item-btn app__item-btn--edit'>edit</button>
<button class='app__item-btn app__item-btn--delete'>delete</button>
</div>`
const editBtn = item.querySelector(".app__item-btn--edit");
const deleteBtn = item.querySelector(".app__item-btn--delete");
editBtn.addEventListener("click", editItem);
deleteBtn.addEventListener("click", deleteItem);
itemsList.appendChild(item);
displayAlert("item added", "success");
addToLocalStorage(id, input.value);
setBackToDefault();
itemsContainer.classList.add("app__items-container--visible");
} else if (input.value && editFlag) {
editElement.textContent = input.value;
// edit local storage
editLocalStorage(editId, input.value);
setBackToDefault();
displayAlert("item edited", "success");
} else {
displayAlert("empty field", "warning");
}
}
function setBackToDefault() {
input.value = "";
editFlag = false;
editId = "";
submitBtn.textContent = "Submit";
submitBtn.className = "app__submit-btn";
}
function displayAlert(text, action) {
alert.textContent = text;
alert.classList.add(`app__alert--${action}`);
setTimeout(function() {
alert.textContent = "";
alert.classList.remove(`app__alert--${action}`);
}, 700)
}
function clearItems() {
const items = document.querySelectorAll(".app__item");
if (items.length > 0) {
items.forEach(function(singleItem) {
itemsList.removeChild(singleItem);
})
itemsContainer.classList.remove("app__items-container--visible");
displayAlert("items cleared", "cleared");
setBackToDefault();
}
}
function editItem(e) {
const item = e.currentTarget.parentElement.parentElement;
editElement = e.currentTarget.parentElement.previousElementSibling;
editId = item.dataset.id;
editFlag = true;
input.value = editElement.textContent;
submitBtn.textContent = "Edit";
submitBtn.classList.add("app__submit-btn--edit");
input.focus();
}
function deleteItem(e) {
const item = e.currentTarget.parentElement.parentElement;
const itemId = item.dataset.id;
removeFromLocalStorage(itemId);
displayAlert("item removed", "cleared");
setBackToDefault();
itemsList.removeChild(item);
if (itemsList.children.length === 0) {
itemsContainer.classList.remove("app__items-container--visible");
}
}
function addToLocalStorage(id, value) {
const itemsObj = {id: id, value: input.value};
let storageItems = getLocalStorage();
storageItems.push(itemsObj);
localStorage.setItem("list", JSON.stringify(storageItems));
}
function removeFromLocalStorage(id) {
console.log(id);
let storageItems = getLocalStorage();
console.log(storageItems);
storageItems = storageItems.filter(function(singleItem) {
if (singleItem.id !== id) {
return singleItem;
}
})
console.log(storageItems);
localStorage.setItem("list", JSON.stringify(storageItems));
}
function editLocalStorage(id, value) {
}
function getLocalStorage() {
return localStorage.getItem("list") ? JSON.parse(localStorage.getItem("list")) : [];
}
* {
margin: 0;
padding: 0;
}
.app {
width: 70%;
max-width: 600px;
margin: 75px auto 0;
}
.app__title {
text-align: center;
/* color: #1B5D81; */
margin-top: 20px;
color: #377FB4;
}
.app__alert {
width: 60%;
margin: 0 auto;
text-align: center;
font-size: 20px;
color: #215884;
border-radius: 7px;
height: 23px;
transition: 0.4s;
text-transform: capitalize;
}
.app__alert--warning {
background-color: rgba(243, 117, 66, 0.2);
color: #006699;
}
.app__alert--success {
background-color: rgba(165, 237, 92, 0.4);
color: #3333ff;
}
.app__alert--cleared {
background-color: #a978da;
color: white;
}
.app__input-btn-cont {
display: flex;
margin-top: 30px;
}
.app__input {
width: 80%;
box-sizing: border-box;
font-size: 20px;
padding: 3px 0 3px 10px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
border-right: none;
border: 1px solid #67B5E2;
background-color: #EDF9FF;
}
.app__input:focus {
outline: transparent;
}
.app__submit-btn {
display: block;
width: 20%;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
border-left: none;
background-color: #67B5E2;
border: 1px solid #67B5E2;
cursor: pointer;
font-size: 20px;
color: white;
transition: background-color 0.7s;
padding: 3px 0;
}
.app__submit-btn--edit {
background-color: #95CB5D;
}
.app__submit-btn:active {
width: 19.9%;
padding: 0 0;
}
.app__submit-btn:hover {
background-color: #377FB4;
}
.app__submit-btn--edit:hover {
background-color: #81AF51;
}
.app__items-container {
visibility: hidden;
/* transition: 0.7s; */
}
.app__items-container--visible {
visibility: visible;
}
.app__item {
display: flex;
justify-content: space-between;
margin: 20px 0;
}
.app__item:hover {
background-color: #b9e2fa;
border-radius: 10px;
}
.app__item-text {
padding-left: 10px;
font-size: 20px;
color: #1B5D81;
}
.app__item-btn-cont {
display: flex;
}
.app__item-btn-img {
width: 20px;
height: 20px;
}
.app__item-btn {
border: none;
background-color: transparent;
cursor: pointer;
display: block;
font-size: 18px;
}
.app__item-btn--edit {
margin-right: 45px;
color: #2c800f;
}
.app__item-btn--delete {
margin-right: 15px;
color: rgb(243, 117, 66);
}
.app__clear-btn {
display: block;
width: 150px;
margin: 20px auto;
border: none;
background-color: transparent;
font-size: 20px;
color: rgb(243, 117, 66);
letter-spacing: 2px;
cursor: pointer;
transition: border 0.3s;
border: 1px solid transparent;
}
.app__clear-btn:hover {
border: 1px solid rgb(243, 117, 66);
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8" name="viewport" content="width=device-width,
initial-scale=1">
<link rel="stylesheet" href="list.css">
<title>To Do List App</title>
</head>
<body>
<section class="app">
<form class="app__form">
<p class="app__alert"></p>
<h2 class="app__title">To Do List</h2>
<div class="app__input-btn-cont">
<input class="app__input" type="text" id="todo" placeholder="do stuff">
<button class="app__submit-btn">Submit</button>
</div>
</form>
<div class="app__items-container">
<div class="app__items-list">
</div>
<button class="app__clear-btn">Clear Items</button>
</div>
</section>
<script src="list.js"></script>
</body>
</html>
Your code is fine you just used the wrong comparison operator.
In your case you are comparing 2 IDs (operands) to see if they match up, so you should use normal operators such as (==, !=), but instead in your case, you have used strict operators which are used to compare the operand type and the operand itself.
You can learn more about Comparison Operators here.
Ultimatly,
In your function removeFromLocalStorage(id), you have an extra equal sign in your if function.
Instead of:
if (singleItem.id !== id) {
return singleItem;}
It should be:
if (singleItem.id != id) {
return singleItem;}
Hope this helps.
Here is the codepen: http://codepen.io/anon/pen/WbYjOW
When you add an interest in the right box (thus causing the right div to grow), the dropdown list moves with it, at least in Firefox and Chrome.
How can this unwanted movement be prevented?
Here is the code pasted (same as codepen):
HTML
/*Adder*/
$(document).ready(function() {
var i = 0;
for (i = 0; i < localStorage.length; i++) {
var taskID = "task-" + i;
$('#taskList').append("<li id='" + taskID + "'>" + localStorage.getItem(taskID) + "</li>");
}
$('#clear').click(function() {
localStorage.clear();
});
$('#taskEntryForm').submit(function() {
if ($('#taskInput').val() !== "") {
var taskID = "task-" + i;
var taskMessage = $('#taskInput').val();
localStorage.setItem(taskID, taskMessage);
$('#taskList').append("<li class='task' id='" + taskID + "'>" + taskMessage + "</li>");
var task = $('#' + taskID);
task.css('display', 'none');
task.slideDown();
$('#taskInput').val("");
i++;
}
return false;
});
$('#taskList').on("click", "li", function(event) {
self = $(this);
taskID = self.attr('id');
localStorage.removeItem(taskID);
self.slideUp('slow', function() {
self.remove();
});
});
});
/*EasyDropDown*/
/*
* EASYDROPDOWN - A Drop-down Builder for Styleable Inputs and Menus
* Version: 2.0.4
* License: Creative Commons Attribution 3.0 Unported - CC BY 3.0
* http://creativecommons.org/licenses/by/3.0/
* This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
* Author: Patrick Kunka
* Copyright 2013 Patrick Kunka, All Rights Reserved
*/
(function(d) {
function e() {
this.isField = !0;
this.keyboardMode = this.hasLabel = this.cutOff = this.inFocus = this.down = !1;
this.nativeTouch = !0;
this.wrapperClass = "dropdown";
this.onSelect = null
}
function f(a, c) {
var b = new e;
b.init(a, c);
b.instances.push(b)
}
e.prototype = {
constructor: e,
instances: [],
init: function(a, c) {
var b = this;
d.extend(b, c);
b.$select = d(a);
b.options = [];
b.$options = b.$select.find("option");
b.isTouch = "ontouchend" in document;
b.$select.removeClass(b.wrapperClass + " dropdown");
b.$options.length && (b.$options.each(function(a) {
var c =
d(this);
c.is(":selected") && (b.selected = {
index: a,
title: c.text()
}, b.focusIndex = a);
c.hasClass("label") && 0 == a ? (b.hasLabel = !0, b.label = c.text(), c.attr("value", "")) : b.options.push({
domNode: c[0],
title: c.text(),
value: c.val(),
selected: c.is(":selected")
})
}), b.selected || (b.selected = {
index: 0,
title: b.$options.eq(0).text()
}, b.focusIndex = 0), b.render())
},
render: function() {
var a = this;
a.$container = a.$select.wrap('<div class="' + a.wrapperClass + (a.isTouch && a.nativeTouch ? " touch" : "") + '"><span class="old"/></div>').parent().parent();
a.$active = d('<span class="selected">' + a.selected.title + "</span>").appendTo(a.$container);
a.$carat = d('<span class="carat"/>').appendTo(a.$container);
a.$scrollWrapper = d("<div><ul/></div>").appendTo(a.$container);
a.$dropDown = a.$scrollWrapper.find("ul");
a.$form = a.$container.closest("form");
d.each(a.options, function() {
a.$dropDown.append("<li" + (this.selected ? ' class="active"' : "") + ">" + this.title + "</li>")
});
a.$items = a.$dropDown.find("li");
a.maxHeight = 0;
a.cutOff && a.$items.length > a.cutOff && a.$container.addClass("scrollable");
for (i = 0; i < a.$items.length; i++) {
var c = a.$items.eq(i);
a.maxHeight += c.outerHeight();
if (a.cutOff == i + 1) break
}
a.isTouch && a.nativeTouch ? a.bindTouchHandlers() : a.bindHandlers()
},
bindTouchHandlers: function() {
var a = this;
a.$container.on("click", function() {
a.$select.focus()
});
a.$select.on({
change: function() {
var c = d(this).find("option:selected"),
b = c.text(),
c = c.val();
a.$active.text(b);
"function" == typeof a.onSelect && a.onSelect.call(a, {
title: b,
value: c
})
},
focus: function() {
a.$container.addClass("focus")
},
blur: function() {
a.$container.removeClass("focus")
}
})
},
bindHandlers: function() {
var a = this;
a.query = "";
a.$container.on({
click: function() {
a.down ? a.close() : a.open()
},
mousemove: function() {
a.keyboardMode && (a.keyboardMode = !1)
}
});
d("body").on("click", function(c) {
c = d(c.target);
var b = a.wrapperClass.split(" ").join(".");
!c.closest("." + b).length && a.down && a.close()
});
a.$items.on({
click: function() {
var c = d(this).index();
a.select(c);
a.$select.focus()
},
mouseover: function() {
if (!a.keyboardMode) {
var c = d(this);
c.addClass("focus").siblings().removeClass("focus");
a.focusIndex =
c.index()
}
},
mouseout: function() {
a.keyboardMode || d(this).removeClass("focus")
}
});
a.$select.on({
focus: function() {
a.$container.addClass("focus");
a.inFocus = !0
},
blur: function() {
a.$container.removeClass("focus");
a.inFocus = !1
}
});
a.$dropDown.on("scroll", function(c) {
a.$dropDown[0].scrollTop == a.$dropDown[0].scrollHeight - a.maxHeight ? a.$container.addClass("bottom") : a.$container.removeClass("bottom")
});
a.$select.on("keydown", function(c) {
if (a.inFocus) {
a.keyboardMode = !0;
var b = c.keyCode;
if (38 == b || 40 == b || 32 == b) c.preventDefault(),
38 == b ? (a.focusIndex--, a.focusIndex = 0 > a.focusIndex ? a.$items.length - 1 : a.focusIndex) : 40 == b && (a.focusIndex++, a.focusIndex = a.focusIndex > a.$items.length - 1 ? 0 : a.focusIndex), a.down || a.open(), a.$items.removeClass("focus").eq(a.focusIndex).addClass("focus"), a.cutOff && a.scrollToView(), a.query = "";
if (a.down)
if (9 == b || 27 == b) a.close();
else {
if (13 == b) return c.preventDefault(), a.select(a.focusIndex), a.close(), !1;
if (8 == b) return c.preventDefault(), a.query = a.query.slice(0, -1), a.search(), !1;
38 != b && 40 != b && (c = String.fromCharCode(b),
a.query += c, a.search())
}
}
});
if (a.$form.length) a.$form.on("reset", function() {
a.$active.text(a.hasLabel ? a.label : "")
})
},
open: function() {
var a = window.scrollY || document.documentElement.scrollTop,
c = window.scrollX || document.documentElement.scrollLeft,
b = this.notInViewport(a);
this.closeAll();
this.$select.focus();
window.scrollTo(c, a + b);
this.$container.addClass("open");
this.$scrollWrapper.css("height", this.maxHeight + "px");
this.down = !0
},
close: function() {
this.$container.removeClass("open");
this.$scrollWrapper.css("height",
"0px");
this.focusIndex = this.selected.index;
this.query = "";
this.down = !1
},
closeAll: function() {
var a = Object.getPrototypeOf(this).instances;
for (i = 0; i < a.length; i++) a[i].close()
},
select: function(a) {
var c = this.options[a],
b = this.hasLabel ? a + 1 : a;
this.$items.removeClass("active").eq(a).addClass("active");
this.$active.text(c.title);
this.$select.find("option").prop("selected", !1).eq(b).prop("selected", "selected");
this.selected = {
index: a,
title: c.title
};
this.focusIndex = i;
"function" == typeof this.onSelect && this.onSelect.call(this, {
title: c.title,
value: c.value
})
},
search: function() {
for (i = 0; i < this.options.length; i++)
if (-1 != this.options[i].title.toUpperCase().indexOf(this.query)) {
this.focusIndex = i;
this.$items.removeClass("focus").eq(this.focusIndex).addClass("focus");
this.scrollToView();
break
}
},
scrollToView: function() {
if (this.focusIndex >= this.cutOff) {
var a = this.$items.eq(this.focusIndex).outerHeight() * (this.focusIndex + 1) - this.maxHeight;
this.$dropDown.scrollTop(a)
}
},
notInViewport: function(a) {
var c = a + (window.innerHeight || document.documentElement.clientHeight),
b = this.$dropDown.offset().top + this.maxHeight;
return b >= a && b <= c ? 0 : b - c + 5
}
};
d.fn.easyDropDown = function(a) {
return this.each(function() {
f(this, a)
})
};
d(function() {
"function" !== typeof Object.getPrototypeOf && (Object.getPrototypeOf = "object" === typeof "test".__proto__ ? function(a) {
return a.__proto__
} : function(a) {
return a.constructor.prototype
});
d(".dropdown").each(function() {
var a = d(this).attr("data-settings");
settings = a ? d.parseJSON(a) : {};
f(this, settings)
})
})
})(jQuery);
/*adder*/
#import url(http://fonts.googleapis.com/css?family=Open+Sans:400, 300, 600);
* {
padding: 0;
margin: 0;
}
body {
background: url('');
background-color: #2a2a2a;
font-family: 'Open Sans', sans-serif;
}
.adder #container {
background-color: #111216;
color: #999999;
width: 350px;
/*margin: 50px auto auto auto;*/
padding-bottom: 12px;
}
.adder #formContainer {
padding-top: 12px;
}
.adder #taskIOSection {} .adder #taskInput {
font-size: 14px;
font-family: 'Open Sans', sans-serif;
height: 36px;
width: 311px;
border-radius: 100px;
background-color: #202023;
border: 0;
color: #fff;
display: block;
padding-left: 15px;
-webkit-transition: all 0.30s ease-in-out;
-moz-transition: all 0.30s ease-in-out;
-ms-transition: all 0.30s ease-in-out;
-o-transition: all 0.30s ease-in-out;
}
.adder #taskInput:focus {
box-shadow: 0px 0px 1pt 1pt #999999;
background-color: #111216;
outline: none;
}
.adder::-webkit-input-placeholder {
color: #333333;
font-style: italic;
/* padding-left:10px; */
}
.adder:-moz-placeholder {
/* Firefox 18- */
color: #333333;
font-style: italic;
}
.adder::-moz-placeholder {
/* Firefox 19+ */
color: #333333;
font-style: italic;
}
.adder:-ms-input-placeholder {
color: #333333;
font-style: italic;
}
.adder header {
margin-top: 0;
background-color: #F94D50;
width: 338px;
height: 48px;
padding-left: 12px;
}
.adder header h1 {
font-size: 25px;
font-weight: 300;
color: #fff;
line-height: 48px;
width: 50%;
display: inline;
}
.adder header a {
width: 40%;
display: inline;
line-height: 48px;
}
.adder #taskEntryForm {
background-color: #111216;
width: 326px;
height: 48px;
border-width: 0px;
padding: 0px 12px 0px 12px;
font-size: 0px;
}
.adder #taskList {
width: 350px;
margin: auto;
font-size: 16px;
font-weight: 600;
text-align: left;
}
.adder ul li {
background-color: #17181D;
height: 48px;
width: 314px;
padding-left: 12px;
margin: 0 auto 10px auto;
line-height: 48px;
list-style: none;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
/*now this*/
/* reset */
ul {
margin: 0;
padding: 0;
}
/* --- EASYDROPDOWN DEFAULT THEME --- */
/* PREFIXED CSS */
.dropdown,
.dropdown div,
.dropdown li,
.dropdown div::after {
-webkit-transition: all 150ms ease-in-out;
-moz-transition: all 150ms ease-in-out;
-ms-transition: all 150ms ease-in-out;
transition: all 150ms ease-in-out;
}
.dropdown .selected::after,
.dropdown.scrollable div::after {
-webkit-pointer-events: none;
-moz-pointer-events: none;
-ms-pointer-events: none;
pointer-events: none;
}
/* WRAPPER */
.dropdown {
/*margin: 50px auto auto auto;*/
position: relative;
width: 160px;
border: 1px solid #ccc;
cursor: pointer;
background: #fff;
border-radius: 3px;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.dropdown.open {
z-index: 2;
}
.dropdown:hover {
box-shadow: 0 0 5px rgba(0, 0, 0, .15);
}
.dropdown.focus {
box-shadow: 0 0 5px rgba(51, 102, 248, .4);
}
/* CARAT */
.dropdown .carat {
position: absolute;
right: 12px;
top: 50%;
margin-top: -4px;
border: 6px solid transparent;
border-top: 8px solid #000;
}
.dropdown.open .carat {
margin-top: -10px;
border-top: 6px solid transparent;
border-bottom: 8px solid #000;
}
/* OLD SELECT (HIDDEN) */
.dropdown .old {
position: absolute;
left: 0;
top: 0;
height: 0;
width: 0;
overflow: hidden;
}
.dropdown select {
position: absolute;
left: 0px;
top: 0px;
}
.dropdown.touch .old {
width: 100%;
height: 100%;
}
.dropdown.touch select {
width: 100%;
height: 100%;
opacity: 0;
}
/* SELECTED FEEDBACK ITEM */
.dropdown .selected,
.dropdown li {
display: block;
font-size: 18px;
line-height: 1;
color: #000;
padding: 9px 12px;
overflow: hidden;
white-space: nowrap;
}
.dropdown .selected::after {
content: '';
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 60px;
border-radius: 0 2px 2px 0;
box-shadow: inset -55px 0 25px -20px #fff;
}
/* DROP DOWN WRAPPER */
.dropdown div {
position: absolute;
height: 0;
left: -1px;
right: -1px;
top: 100%;
margin-top: -1px;
background: #fff;
border: 1px solid #ccc;
border-top: 1px solid #eee;
border-radius: 0 0 3px 3px;
overflow: hidden;
opacity: 0;
}
/* Height is adjusted by JS on open */
.dropdown.open div {
opacity: 1;
z-index: 2;
}
/* FADE OVERLAY FOR SCROLLING LISTS */
.dropdown.scrollable div::after {
content: '';
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 50px;
box-shadow: inset 0 -50px 30px -35px #fff;
}
.dropdown.scrollable.bottom div::after {
opacity: 0;
}
/* DROP DOWN LIST */
.dropdown ul {
/*position: absolute;
left: 0;
top: 0;*/
height: 100%;
width: 100%;
list-style: none;
overflow: hidden;
}
.dropdown.scrollable.open ul {
overflow-y: auto;
}
/* DROP DOWN LIST ITEMS */
.dropdown li {
list-style: none;
padding: 8px 12px;
}
/* .focus class is also added on hover */
.dropdown li.focus {
background: #d24a67;
position: relative;
z-index: 3;
color: #fff;
}
.dropdown li.active {
font-weight: 700;
}
/*Vertical*/
.wrap {
text-align: center;
position: absolute;
margin: auto;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 100%;
height: 100px;
display: block;
}
div div {
display: inline-block;
}
<!DOCTYPE html>
<!--
-->
<html lang="en">
<head>
<link type="text/css" rel="stylesheet" href="css/styletime.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/init.js"></script>
</head>
<body>
Hello?
<div class="wrap">
<div>
<select name="" id="" class="dropdown" style="display:inline-block;">
<option class="label">Label</option>
<option value="1">option 1</option>
<option value="1">option 2</option>
<option value="1">option 3</option>
<option value="1">option 4</option>
<option value="1">option 5</option>
<option value="1">option 6</option>
<option value="1">option 7</option>
<option value="1">option 8</option>
<option value="1">option 9</option>
</select>
</div>
<div class="adder" style="display:inline-block;">
<div id="container">
<section id="taskIOSection">
<div id="formContainer">
<form id="taskEntryForm">
<input id="taskInput" placeholder="Add your interests here..." />
</form>
</div>
<ul id="taskList"></ul>
</section>
</div>
</div>
</div>
</body>
</html>
set vertical-align to top to .dropdown wrapper, like here