I use for a project Font Awesome for icons and because they do not show in IE8 when I use it like:
<i class="fa fa-bars fa-2x"></i>
I am forced to use the cheat sheet icons as this:
<i class="mobile-search-icon fa fa-lg"></i>
This way, the icons show OK in IE8 as well.
Now, the problem... Using the cheat sheet icons, how can I replace the value with another on toggle? Please check the example below where you see initially the search icon and on click I should see a close icon and on another click, show again the search icon.
The example below is the closest way I have found so far, and I need some help if possible. Thanks
$(".mobile-search-icon").on('click', function(e) {
$(this).siblings(".search-container").fadeToggle(500);
if ($.trim($(this).text()) === '') {
$(this).text('');
} else {
$(this).text('');
}
return false;
});
.search-bar {
display: table-cell;
vertical-align: middle;
}
.mobile-search-icon {
color: #fff;
display: block;
line-height: 50px;
width: 150px;
z-index: 1;
background-color: black;
text-align: center;
padding: 20px;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<div class="search-bar">
<i class="mobile-search-icon fa fa-lg"></i>
</div>
Not sure exactly what you want, but it looks neat. I made a demo that uses FA's Unicode on Snippet 1.
I re-read your question, I think I understand ... You just want to toggle the button between 2 icons. If so look at Snippet 2. Your problem is that you are using .text() method which will add non-parsed plain text. .html() will take text and parse it to HTML so it's rendered as what the text represents, and not what it is literally.
SNIPPET 1
var tgt = document.querySelector('.search-bar');
var btn = document.querySelector('.search-btn');
btn.addEventListener('click', function(e) {
var res = document.getElementById('result');
var txt = document.getElementById('inputText').value;
var mom = res.parentNode;
if (res) {
mom.removeChild(res);
}
genFA(txt);
}, false);
function genFA(x) {
var baseUni = "";
var iEle = document.createElement('i');
iEle.id = 'result';
iEle.classList.add('fa');
iEle.classList.add('fa-lg');
iEle.innerHTML = baseUni + x;
return tgt.appendChild(iEle);
}
*,
*:before,
*:after {
box-sizing: border-box;
}
html,
body {
width: 100%;
height: 100%;
font: 400 16px/1.45'Verdana';
}
.search-bar {
display: table;
position: relative;
height: 80px;
padding: 5px 15px;
width: 500px;
}
.search-btn {
color: #fff;
display: table-cell;
line-height: 50px;
width: 35%;
background-color: black;
text-align: center;
padding: 10px 20px;
}
#inputText {
display: table-cell;
width: 25%;
padding: 0 5px;
font: 400 20px/30px'Consolas';
text-align: center;
vertical-align: middle;
}
#result {
color: #000;
line-height: 33px;
width: 35%;
background-color: #fff;
text-align: center;
vertical-align: middle;
border: 1px solid black;
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
<fieldset class="search-bar">
<legend>Font-Awesome Unicode</legend>
<input id="inputText">
<i class="search-btn fa fa-lg"></i>
<i id="result" class="fa fa-lg"> </i>
</fieldset>
<p>Enter: 3 digit hexidecimal number.</p>
<p>Range: 000 - 2b1</p>
<p>Font-Awesome v.4.6.3</p>
SNIPPET 2
$(function() {
$(".mobile-search-icon").on('click', function(e) {
if ($(this).hasClass('on')) {
$(this).html('').toggleClass('on');
} else {
$(this).html('').toggleClass('on');
}
});
});
.search-bar {
color: #fff;
display: table-cell;
vertical-align: middle;
line-height: 30px;
width: 150px;
background-color: black;
text-align: center;
padding: 10px;
cursor: pointer;
}
.mobile-search-icon {
width: 100%;
}
.on {
opacity: 1;
transition: opacity 1s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div class="search-bar">
<i class="mobile-search-icon fa fa-lg on"></i>
</div>
Related
I am making a todo page and want to count the number of todos and display them.
<div class='numtodos'>3</div>
I want to display them here in the text content of numtodos.
Trying to count the number of todo lis using jQuery (I could also use a non-jQuery answer).
I know I would need the length of <li> elements, but how should I save it to update when a new todo is added.
Here is my code pen. trying to make the large number on the right be the number of todos.
$('ul').on('click', 'li', function() {
$(this).toggleClass('completed');
})
$('ul').on('click', 'span', function(event) {
$(this).parent().fadeOut(500, function() {
$(this).remove();
})
event.stopPropagation();
});
$("input[type='text']").keypress(function(event) {
if (event.which === 13) {
//get the new todo text from inut
var todoText = $(this).val();
$(this).val('');
//create a new li and add it ul
$('ul').append('<li><i class="far fa-circle"></i> ' + todoText + ' <span>X</span></li>')
}
});
$(".fa-plus-circle").click(function() {
$("input[type='text']").fadeToggle();
});
// let lis = document.querySelectorAll('li');
// let input = document.querySelector('input');
// let numtodos = document.querySelector('.numtodos')
// input.addEventListener('change', function(){
// let howmany = lis.length;
// numtodos.textContent= howmany;
// })
$('input').change(function() {
console.log($('.numtodos'));
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(67, 0, 192);
font-family: 'Roboto', sans-serif;
}
.container {
background-color: whitesmoke;
width: 480px;
height: 100%;
padding: 35px 40px;
}
/* NAV */
#nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.tinyburger {
cursor: pointer;
}
.line {
height: 3px;
width: 21px;
background: black;
margin: 3px;
border-radius: 1px;
}
/* header */
.header {
display: flex;
margin: 40px 0px 30px;
font-family: 'Roboto Condensed', sans-serif;
}
h1 {
margin-right: 8px;
font-size: 3em;
}
h2 {
font-size: 1.4em;
margin-top: 26px;
color: rgb(153, 153, 153);
}
/* Input */
input {
width: 100%;
padding: 10px 5px;
border: none;
font-size: 17px;
}
ul {
list-style: none;
}
li {
line-height: 1.2;
border-bottom: 1px rgb(202, 202, 202) solid;
margin: 20px 5px;
padding: 0px 0 20px 0;
font-weight: bold;
cursor: pointer;
}
li span {
float: right;
}
.fa-plus-circle {
color: rgb(67, 0, 192);
font-size: 40px;
text-align: center;
width: 100%;
margin-top: 30px;
}
.numtodos {
font-size: 12em;
position: absolute;
top: 0%;
left: 75%;
line-height: 0.7;
color: rgba(153, 153, 153, 0.2);
font-family: 'Roboto Condensed', sans-serif;
}
.fa-circle {
color: rgba(153, 153, 153, 0.4);
font-size: 20px;
}
.completed {
text-decoration: line-through;
color: grey;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:ital,wght#0,400;1,700&family=Roboto:wght#400;500;700;900&display=swap" rel="stylesheet">
</head>
<body>
<div class="container">
<div id='nav'>
<div class='tinyburger'>
<div class='line'></div>
<div class='line'></div>
<div class='line'></div>
</div>
<i class="fas fa-search"></i>
</div>
<div class="header">
<h1>TO-DO</h1>
<h2 class="date">NOV 23</h2>
</div>
<input type="text" name='newtodo' id='newtodo' placeholder="Write a new to-do">
<ul class='todos'>
<li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span> </li>
<li><i class="far fa-circle"></i> Evening Workout<span>X</span></li>
<li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span></li>
</ul>
<i class="fas fa-plus-circle"></i>
<div class='numtodos'>3</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
https://codepen.io/laurynatlanta/pen/QWNxYeN
I think this should be fine:
// Get todos number container div element.
var numTodosContainer = document.getElementsByClassName('numtodos')[0];
// Get all todos available.
var todos = document.getElementsByClassName(todosclassname);
// Get todos length to add it to the container.
var lastTodosNum = todos.length;
// Add it to the container.
numTodosContainer.innerHTML = lastTodosNum;
// Loop to check every 10ms if the number of todos is changed.
setInterval(function(){
// This variable will change every 10ms to get the new todos number.
var newTodosNum = document.getElementsByClassName(todosclassname).length;
// Check if the new number isn't equals the old num.
if (newTodosNum != lastTodosNum) {
numTodosContainer.innerHTML = newTodosNum;
}
// Make lastTodosNum equals newTodosNum to stop the if statement above from execute the code block inside it.
lastTodosNum = newTodosNum;
}, 10);
you have todo something like that:
const numtodos = document.querySelector('div.numtodos')
numtodos.setCount =_=> {
numtodos.textContent = document.querySelectorAll('ul.todos>li:not(.completed)').length
}
then just add numtodos.setCount(); on rights places.
so, you JS become:
const numtodos = document.querySelector('div.numtodos')
numtodos.setCount =_=> {
numtodos.textContent = document.querySelectorAll('ul.todos>li:not(.completed)').length
}
$('ul').on('click', 'li', function () {
$(this).toggleClass('completed');
numtodos.setCount();
});
$('ul').on('click', 'span', function (event) {
$(this).parent().fadeOut(500, function () {
$(this).remove();
numtodos.setCount();
});
event.stopPropagation();
});
$("input[type='text']").keypress(function (event) {
if (event.which === 13) {
//get the new todo text from inut
var todoText = $(this).val();
$(this).val('');
//create a new li and add it ul
$('ul').append(`<li><i class="far fa-circle"></i>${todoText}<span>X</span></li>`);
numtodos.setCount();
}
});
$(".fa-plus-circle").click(function () {
$("input[type='text']").fadeToggle();
});
Based on your current code, I'd suggest creating the following named function, and then calling that function in the areas of your code where you're updating the the to-do list (whether adding to, or removing from, it):
// we're not planning to change the function within the code, so we
// declare using 'const' (though 'let' would be perfectly okay, but would
// potentially allow for the variable to be overwritten); we also use
// Arrow function syntax since - within the function - we have no need
// to use 'this':
const todosLength = () => {
// here we find the number of <li> elements that do not have
// the class of 'completed' that are the children of a parent
// with the class of 'todos'; and then we retrieve the length
// of the resulting jQuery collection:
const num = $('.todos > li:not(.completed)').length;
// here we set the text of the element(s) with the
// class of 'numtodos':
$('.numtodos').text(num);
// here we return the number to the calling context
// (just in case it's ever of use):
return num;
};
When the above is merged with your code it yields the following:
const todosLength = () => {
const num = $('.todos li:not(.completed)').length;
$('.numtodos').text(num);
return num;
}
$('ul').on('click', 'li', function() {
$(this).toggleClass('completed');
})
$('ul').on('click', 'span', function(event) {
$(this).parent().fadeOut(500, function() {
$(this).remove();
todosLength();
});
event.stopPropagation();
});
$("input[type='text']").keypress(function(event) {
if (event.which === 13) {
//get the new todo text from inut
var todoText = $(this).val();
$(this).val('');
//create a new li and add it ul
$('ul').append('<li><i class="far fa-circle"></i> ' + todoText + ' <span>X</span></li>');
todosLength();
}
});
$(".fa-plus-circle").click(function() {
$("input[type='text']").fadeToggle();
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: rgb(67, 0, 192);
font-family: 'Roboto', sans-serif;
}
.container {
background-color: whitesmoke;
width: 480px;
height: 100%;
padding: 35px 40px;
}
/* NAV */
#nav {
display: flex;
justify-content: space-between;
align-items: center;
}
.tinyburger {
cursor: pointer;
}
.line {
height: 3px;
width: 21px;
background: black;
margin: 3px;
border-radius: 1px;
}
/* header */
.header {
display: flex;
margin: 40px 0px 30px;
font-family: 'Roboto Condensed', sans-serif;
}
h1 {
margin-right: 8px;
font-size: 3em;
}
h2 {
font-size: 1.4em;
margin-top: 26px;
color: rgb(153, 153, 153);
}
/* Input */
input {
width: 100%;
padding: 10px 5px;
border: none;
font-size: 17px;
}
ul {
list-style: none;
}
li {
line-height: 1.2;
border-bottom: 1px rgb(202, 202, 202) solid;
margin: 20px 5px;
padding: 0px 0 20px 0;
font-weight: bold;
cursor: pointer;
}
li span {
float: right;
}
.fa-plus-circle {
color: rgb(67, 0, 192);
font-size: 40px;
text-align: center;
width: 100%;
margin-top: 30px;
}
.numtodos {
font-size: 12em;
position: absolute;
top: 0%;
left: 75%;
line-height: 0.7;
color: rgba(153, 153, 153, 0.2);
font-family: 'Roboto Condensed', sans-serif;
}
.fa-circle {
color: rgba(153, 153, 153, 0.4);
font-size: 20px;
}
.completed {
text-decoration: line-through;
color: grey;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" integrity="sha512-1PKOgIY59xJ8Co8+NE6FZ+LOAZKjy+KY8iq0G4B3CyeY6wYHN3yt9PW0XpSriVlkMXe40PTKnXrLnZ9+fkDaog==" crossorigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:ital,wght#0,400;1,700&family=Roboto:wght#400;500;700;900&display=swap" rel="stylesheet">
<div class="container">
<div id='nav'>
<div class='tinyburger'>
<div class='line'></div>
<div class='line'></div>
<div class='line'></div>
</div>
<i class="fas fa-search"></i>
</div>
<div class="header">
<h1>TO-DO</h1>
<h2 class="date">NOV 23</h2>
</div>
<input type="text" name='newtodo' id='newtodo' placeholder="Write a new to-do">
<ul class='todos'>
<li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span> </li>
<li><i class="far fa-circle"></i> Evening Workout<span>X</span></li>
<li><i class="far fa-circle"></i> Lunch with Helena Barnes <span>X</span></li>
</ul>
<i class="fas fa-plus-circle"></i>
<div class='numtodos'>3</div>
</div>
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
JS Fiddle demo.
References:
CSS:
Negation (:not()) pseudo-class.
jQuery:
text().
I have a button of fixed size and various chunks of text. The length of the texts is different. How can I make the size of the text font change dynamically according to its length in order to fit the button boundaries properly? Thank you.
Well, depends. Is the height fix as well? If both height and width are fixed, you will have to calculate the fontsize via javascript.
In most of the cases two or three if conditions should be absolutely sufficient for the specific usecase.
function font_size_adjust () {
// Grab the string
var string = $('#button_text').text()
// Get the length in characters of the string
var string_size = string.length
// Build variable to change attribute
var font_size = 0
// Define logic for resizing, adapt this to your personal needs
if (string_size < 60) {
fontsize = '2vw';
} else if (string_size > 60) {
fontsize = '4vw';
} else {}
// Change fontsize
$('#button_text').css('font-size', fontsize)
}
// Call the function where- and whenever needed:
font_size_adjust();
// Example stuff
$('#toggle_small').click(function () {
$('#button_text').text('Now I am small again!')
font_size_adjust();
})
$('#toggle_big').click(function () {
$('#button_text').text('Now I am large again! Lets get this rollin! rollin! rollin! rollin!')
font_size_adjust();
})
#ctn {
display: flex;
float: left;
}
#button {
width: 45vw;
background-color: lightblue;
padding: 10px;
border-radius: 25px;
margin-right: 1vw;
font-family: Varela Round;
color: #FFF;
background: linear-gradient(126deg, rgba(143,61,217,1) 12%, rgba(109,35,177,1) 43%, rgba(101,34,162,1) 72%);
}
#ctn_toggle {
display: flex;
float: left;
}
.toggle {
background-color: lightblue;
font-size: 3vw;
padding: 10px;
border-radius: 25px;
width: 11vw;
text-align: center;
margin-right: 2vw;
font-family: Varela Round;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/css2?family=Varela+Round&display=swap" rel="stylesheet">
<html>
<body>
<div id="ctn">
<div id="button">
<p id="button_text">Make me small and big all day long this is so exciting! Let's go broooh!</p>
</div>
</div>
<div id="ctn_toggle">
<div id="toggle_small" class="toggle">
<p id="button_small">Click me to shrink!</p>
</div>
<div id="toggle_big" class="toggle">
<p id="button_big">Click me to expand!</p>
</div>
</div>
</body>
</html>
Otherwise, these are the options... :
#ctn {
display: flex;
float: left;
}
#button {
width: 20vw;
background-color: lightblue;
padding: 10px;
border-radius: 25px;
margin-right: 1vw;
}
#button_text {
font-size: 4vw;
}
#button2 {
width: 20vw;
background-color: lightblue;
padding: 10px;
border-radius: 25px;
margin-right: 1vw;
}
#button_text2 {
}
#button3 {
width: 20vw;
height: 10vh;
background-color: lightblue;
padding: 10px;
border-radius: 25px;
margin-right: 1vw;
}
#button_text3 {
font-size: 4vw;
}
#button4 {
width: 20vw;
height: 10vh;
background-color: lightblue;
padding: 10px;
border-radius: 25px;
}
#button_text4 {
}
<html>
<body>
<div id="ctn">
<div id="button">
<p id="button_text">Fix button width and fix font-size</p>
</div>
<div id="button2">
<p id="button_text2">Fix button width and no specific font-size</p>
</div>
<div id="button3">
<p id="button_text3">Fix button width, fix button height and fix font-size</p>
</div>
<div id="button4">
<p id="button_text4">Fix button width, fix button height and no font-size</p>
</div>
</div>
</body>
</html>
I'm trying to create a custom drop down menu, using HTML, CSS and Vanilla Javascript.
I've managed to get the menu to appear when the user clicks on the the "from" input field, however when I try and click on an option, it wont let you add the value stored in the "code" dataset.
I did get it to work by using setTimeout method, however it is a bit hit and miss sometimes and doesn't seem like a good solution.
Is there an alternative way to get it to work?
function app() {
var messages = document.querySelector(".messages");
var inputFrom = document.querySelector(".input-from");
var inputTo = document.querySelector(".input-to");
var nearestContainer = document.querySelector(".nearest-container");
inputFrom.addEventListener("focus", inputToFocusIn, false);
function inputToFocusIn(e) {
messages.innerHTML = "focusin event triggered on input-from";
// add class
inputFrom.classList.add("input-from--focusin");
nearestContainer.classList.add("nearest-container--active");
// remove class
inputFrom.classList.remove("input-from--focusout");
nearestContainer.classList.remove("nearest-container--hidden");
}
inputFrom.addEventListener("focusout", inputToFocusOut, false);
function inputToFocusOut(e) {
messages.innerHTML = "focusout event triggered on input-from";
// add class
inputFrom.classList.remove("input-from--focusin");
nearestContainer.classList.remove("nearest-container--active");
// remove class
inputFrom.classList.add("input-from--focusout");
nearestContainer.classList.add("nearest-container--hidden");
}
var nearestStations = document.querySelectorAll(".nearest-station");
// add event listener to buttons
for(var nearestStation of nearestStations) {
nearestStation.addEventListener("click", addToInputFrom, false);
}
function addToInputFrom(e) {
inputFrom.classList.add("input-from--focusout");
nearestContainer.classList.add("nearest-container--hidden");
inputFrom.classList.remove("input-from--focusin")
nearestContainer.classList.remove("nearest-container--active")
var targetDataset = e.currentTarget.dataset.code;
messages.innerHTML = "station added to input from field"
inputFrom.value = "";
inputFrom.value = targetDataset;
}
var switchButton = document.querySelector(".button-switch");
switchButton.addEventListener("click", clickSwitch, false);
function clickSwitch(e) {
var inputFromValue = inputFrom.value;
var inputToValue = inputTo.value;
inputFrom.value = inputToValue;
inputTo.value = inputFromValue;
}
}
window.onload = app();
/* stylesheet */
body {
font-family: "GRAPHIK";
font-style: normal;
font-weight: 400;
font-size: 16px;
color: #242424;
}
* {
box-sizing: border-box;
outline: none;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100vw;
height: 100vh;
background-color: #FF4136;
}
.search-container {
display: flex;
flex-direction: column;
flex-shrink: 0;
width: 300px;
padding: 10px;
background-color: #FFF;
border-radius: 10px;
}
.form-container {
display: flex;
flex-direction: row;
width: 100%;
}
.input-container {
width: 100%;
}
.input {
width: 100%;
border: none;
border-radius: 10px;
background-color: #f1f1f1;
padding: 10px;
}
.input-from {
margin-bottom: 5px;
}
.input-from--focusout {
border-radius: 10px;
}
.input-from--focusin {
border-radius: 10px 10px 0 0;
}
.input-to {
margin-bottom: 5px;
}
.switch-container {
margin-bottom: 5px;
}
.button {
border: none;
background-color: transparent;
}
.button-switch {
height: 100%;
width: 38px;
margin-left: 5px;
background-color: #f1f1f1;
border-radius: 10px;
background-image: url(../assets/images/switch.svg);
background-position: center;
background-size: 20px;
background-repeat: no-repeat;
}
.button-switch:hover {
background-image: url(../assets/images/switch-hover.svg);
}
.button-search {
padding: 10px;
background-color: #2ECC40;
color: #FFF;
border-radius: 10px;
width: 100%;
transition: background-color 0.5s ease;
}
.button-search:hover {
background-color: #33e147;
}
.input-container-to {
position: relative;
}
.nearest-container {
position: absolute;
top: 38px;
background-color: #f1f1f1;
padding: 5px;
border-radius: 0 0 10px 10px;
width: 100%;
z-index: 100;
}
.messages {
width: 300px;
background-color: #FFF;
padding: 5px;
border-radius: 10px;
text-align: center;
margin-bottom: 5px;
font-size: 10px;
}
.finding, .show-more {
width: 100%;
font-size: 10px;
font-style: italic;
margin: 0;
padding: 5px;
}
.show-more {
text-align: center;
}
.nearest-station {
font-size: 10px;
padding: 5px;
border-radius: 10px;
}
.nearest-container--hidden {
display: none;
}
.nearest-station--active {
display: flex;
}
.nearest-station:hover {
background-color: #FFF;
cursor: pointer;
}
.logo {
margin-right: 5px;
}
.nr-logo {
width: 15px;
}
.station-distance {
font-style: italic;
float: right;
}
<div class="container">
<div class="messages">messages here</div>
<div class="search-container">
<div class="form-container">
<div class="input-container">
<div class="input-container-to">
<input type="text" class="input input-from" placeholder="From">
<div class="nearest-container nearest-container--hidden">
<div class="stations-container">
<p class="finding">Finding stations closest to you...</p>
<!-- stations here-->
<div class="nearest-station" data-code="Leigh-on-Sea">
<span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span>
<span class="station-name">Leigh-on-Sea</span>
<span class="station-distance">0.6km</span>
</div>
<div class="nearest-station" data-code="Chalkwell">
<span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span>
<span class="station-name">Chalkwell</span>
<span class="station-distance">1.5km</span>
</div>
<div class="nearest-station" data-code="Westcliff">
<span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span>
<span class="station-name">Westcliff</span>
<span class="station-distance">2.7km</span>
</div>
<div class="nearest-station" data-code="Southend Central">
<span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span>
<span class="station-name">Southend Central</span>
<span class="station-distance">3.6km</span>
</div>
<div class="nearest-station" data-code="Southend Victoria">
<span class="logo"><img class="nr-logo" src="assets/images/nr-logo.svg"></span>
<span class="station-name">Southend Victoria</span>
<span class="station-distance">3.8km</span>
</div>
</div>
<div class="stations-show-more">
<!--
<p class="show-more">Show more stations</p> -->
</div>
</div>
</div>
<div class="input-container-to">
<input type="text" class="input input-to" placeholder="To">
</div>
</div>
<div class="switch-container">
<input type="button" class="button button-switch">
</div>
</div>
<div class="button-search-container">
<input type="button" class="button button-search" value="Search">
</div>
</div>
</div>
Using setTimeout in the inputToFocusOut() function is indeed the correct way to obtain the desired effect: hiding of the menu must be delayed so that a click on a menu item will register and its callback will fire. There should be nothing hit and miss about it, just set the delay at a reasonable value, say 300ms, and remove the hiding of the menu from the addToInputFrom() callback. Actually, you can remove all of the latter function's class-toggling calls, as they are redundant there and may interfere. The menu will be shown/hidden by virtue of inputFrom gaining/losing focus.
BTW, why are you using focusout and not blur?
Using focusout event here
inputFrom.addEventListener("focusout", inputToFocusOut, false);
is not right. Because it will be triggered before click event.
When the function inputToFocusOut is executed the .nearest-container becomes hidden:
nearestContainer.classList.add("nearest-container--hidden");
and that's why click event for it and all of its child nodes (we are interested in .nearest-station elements) won't be triggered. Instead of focusout, use mousedown event. With blur event it won't work.
I wrote some code with three things in mind:
Highlighting a selection's border using 'on click'.
Selecting one item will remove the highlight from the other item.
The ability to deselect each item on click.
I've managed to get everything working for the most part, but I don't particularly like how complex the code is for the radial dot that appears when one item is selected.
Below is an example of what I'm talking about, particularly I'm looking for ways to refactor the code below into something a little more legible (shorter).
$(this).children('.radial').children().toggleClass('checked').parents('.itembox')
.siblings().children('.radial').children().removeClass('checked');
Here's a working example for more context (line 10):
var raceInternet = false;
var racePhone = false;
var raceTv = false;
$(function() {
var $targetDiv = $('#race-internet > .itembox');
var $radialDot = $('.radial > .center-dot');
$targetDiv.on('click', function() {
$(this).toggleClass('user-selected').siblings().removeClass('user-selected');
//Is it possible to refactor Line 10?
$(this).children('.radial').children().toggleClass('checked').parents('.itembox').siblings().children('.radial').children().removeClass('checked');
if ($targetDiv.is('.user-selected')) {
raceInternet = true;
} else {
raceInternet = false;
}
})
})
.itembox-container {
display: flex;
}
.boxes-2 {
width: calc((100% - 25px)/2);
margin: 10px;
padding: 10px;
}
.itembox {
position: relative;
display: inline-block;
border: 5px solid #e8e8e8;
border-radius: 10px;
cursor: pointer;
}
.user-selected {
border: 5px solid #E16E5B;
}
.itembox h4 {
color: #22ddc0;
font-weight: 700;
}
span.price {
display: inline-block;
font-weight: 400;
float: right;
color: #22ddc0;
}
.itembox > ul {
list-style: none;
}
.itembox > ul > li {
line-height: 3;
}
.radial {
position: absolute;
float: right;
height: 35px;
width: 35px;
padding: 2px;
border: 5px solid #e8e8e8;
border-radius: 50%;
top: 43%;
right: 10px;
}
.center-dot {
display: none;
position: relative;
height: 21px;
width: 21px;
background-color: #E16E5B;
border-radius: 50%;
}
.checked {
display: block;
}
.prime-aux:first-of-type {
top: 150px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="container">
<!-- Primary Content Container -->
<div class="prime-aux">
<div id="race-internet" class="itembox-container">
<div class="itembox boxes-2">
<h4>Gigabit Internet <span class="price">$60/mo</span></h4>
<ul>
<li>1,000 Mbps</li>
<li>No data caps</li>
</ul>
<div class="radial">
<div class="center-dot"></div>
</div>
</div>
<div class="itembox boxes-2">
<h4>Basic Internet <span class="price">$25/mo</span></h4>
<ul>
<li>25 Mbps</li>
<li>No data caps</li>
</ul>
<div class="radial">
<div class="center-dot"></div>
</div>
</div>
</div>
</div>
</section>
<!-- Primary Content Container End -->
View on JS Fiddle
You can eliminate a lot of your jQuery by just leveraging CSS. Typically, if I want to toggle a feature, I have it either display: block; or display: none; based upon a CSS selector. Then, I just use jQuery to toggle the parent element's class name. So for example:
.item.selected .checkmark {
display: block;
}
.item .checkmark {
display: none;
}
$('.item').click(function(){ $(this).toggleClass('selected') });
JSFiddle
I am trying to make a tooltip, but I need it to stay hovering when user unhovers.
Also, I am trying to add a close button to that tooltip, that will stay with the "hover state" and when user clicks on it, I want to make it to remember cookies so it will not open again for that cookie.
I am a novice at javascript and jQuery and have been breaking my mind on this for several days now.
Here is my code:
#charset "utf-8";
/* Tooltip CSS Created By Deni*/
.tooltip-container {
width: 400px;
height: 300px;
background: #DBDBDB;
border: 1px solid black;
margin: 10% auto;
}
/* Start the tooltip css */
.tooltip {
position: relative;
z-index: 9998;
cursor: help;
}
.tooltip > span {
display: none;
}
.tooltip:hover {
z-index: 9999;
}
.tooltip:hover .tooltip-data {
display: block;
width: 150px;
padding: 5px;
color: #dadada;
background-color: #A35FA1;
font-size: 11px;
border-radius: 5px;
text-decoration: none;
font-family: century gothic;
position: absolute;
bottom: 20px;
left: -10px;
text-align: center;
}
.tooltip-container > a {
margin-right: 10px;
}
.permhover {
display: block;
opacity: 1;
}
**HTML:**
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Tooltip</title>
<link href="tooltip.css" rel="stylesheet" type="text/css" />
<script src="jquery-1.11.3.min.js" type="text/javascript"></script>
</head>
<body>
<div class="tooltip-container">
This is the information<span class="tooltip-data"> This is one Tooltip!</span>
This is the information <span class="tooltip-data"> This another one Tooltip!</span>
</div>
</body>
</html>
I know that is not much but all the help is appreciated. Thank you very much.
First of all you need to change all lines in css from ".tooltip:hover" to ".tooltip.hover".
Next you need to add <button class="btn-close"></button> to your tooltip (this button will close this tooltip)
Then you need to add jquery code, that will add class hover to tooltip when you hover it.
(function(){
$('.tooltip').each(function(){
var tooltip = $(this);
var tooltipId = tooltip.attr('id');
if( !getCookie(tooltipId) ) {
tooltip.on('mouseenter.tooltip', function(){
tooltip.addClass('hover');
tooltip.find('.btn-close').on('click', function(){
var date = new Date();
date.setDate(date.getDate() + 1);
tooltip.removeClass('hover').off('mouseenter.tooltip');
document.cookie = tooltipId + "=true; path=/; expires=" + date.toUTCString();
});
});
}
});
function getCookie(name) {
var matches = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
})();
A possible solution of this would be to register the onmouseout event on the links and display your tooltip.
You could add a x by adding a span to the .tooltip-data.
Then use jQuery to active the tooltip on mousehover and remove it by a click on the x span.
$(function() {
$('.tooltip').on('mouseover', function() {
$(this).find('span').show().append('');
});
$('.tooltip-data span').on('click', function() {
$(this).parent().hide();
});
});
#charset "utf-8";
/* Tooltip CSS Created By Deni*/
.tooltip-container {
width: 400px;
height: 300px;
background: #DBDBDB;
border: 1px solid black;
margin: 10% auto;
}
/* Start the tooltip css */
.tooltip {
position: relative;
z-index: 9998;
cursor: help;
}
.tooltip > span {
display: none;
}
.tooltip:hover {
z-index: 9999;
}
.tooltip-data {
display: block;
width: 150px;
padding: 5px;
color: #dadada;
background-color: #A35FA1;
font-size: 11px;
border-radius: 5px;
text-decoration: none;
font-family: century gothic;
position: absolute;
bottom: 20px;
left: -10px;
text-align: center;
}
.tooltip-data span {
float: right;
}
.tooltip-container > a {
margin-right: 10px;
}
.permhover {
display: block;
opacity: 1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="tooltip-container">
<a href="javascript:;" class="tooltip">
This is the information
<span class="tooltip-data"> This is one Tooltip! <span> x </span></span>
</a>
<a href="javascript:;" class="tooltip">
This is the information
<span class="tooltip-data"> This another one Tooltip!<span> x </span></span>
</a>
</div>