I would like to add a similar drop-down input field (picture below), to my website. I want it to appear when a link/image/button is clicked on. Can this be done with JavaScript? Also, I don't want it to affect the flow of the page.
Can this be done with JavaScript?
Yes. The JavaScript/CSS equivalent would be a button which (when clicked) displayed an element with position: fixed or position: absolute.
Here is a simple example using jQuery: http://jsfiddle.net/Byujd/1/
This is a bit complex.
HTML & Default Styles
You need an element which is displayed above the content:
<div class="modal">
<!-- Some content like textarea and stuff -->
</div>
Now you can style this box with the position-property and other things:
.modal {
position: absolute;
z-index: 999;
}
This now displays above the rest of the content.
Some jQuery-Goodness
The button just needs a listener. With jQuery this looks something like this:
$('.the-buttons-class').click( function (e) {
e.preventDefault();
$('.modal').toggle();
});
A better way
Instead of toggling the state of the modal with jQuery's toggle()-function you could toggle a class on it and manipulate the state accordingly:
CSS:
.modal {
...
display: none;
}
.modal.shown {
display: block;
}
JS:
$('.the-buttons-class').click( function (e) {
e.preventDefault();
$('.modal').toggleClass('shown');
});
Moar
I've done something pretty similar at my page. Make sure to check the search box.
The code for it is on GitHub.
Related
I'm making a scrolling menu that has a list of cards, Each card has a button that shows more information.
the problem is that the overflow-y property hides the (toggled info) that should appear at the left side of the menu.
enter image description here
as you can see in the picture, I wanna get the (overflow-x visible) for the card-list but making it overflow-y: auto/scroll simply hide it
code Sandbox if you wanna take a look at the code:
https://codesandbox.io/s/github/Machfar-Souhayel/TestingOverflowBehavior
You could have the expanded version outside of the original list and just alter it to fit the item and then make it visible.
It also is not nessesary to create a class that make it visible/invisible and add and remove that with toggledElement.classList.add("show");
Instead just use element.style.display = 'block'; // 'none';
That way you do not need to use the target.children property but can call the function with an argument.
<button onclick="toggleClass('Title','Content');">Expand</button>
<script>
function toggleClass(header, content){
document.getElementsByClassName('expanded')[0].innerHtml = `<h1>${header}</h1><br><p>${content}</p>`;
document.getElementsByClassName('expanded')[0].style.display = 'block';
}
</script>
<style>
.expanded{
position: abolute;
top: 50vh;
left: 50vw;
transform: translate(-50%,-50);//just for some styling
display: none;
}
</style>
<div class="expanded"></div>
I hope I could help you.
am editing a web app (not my code) , and has alot of modals show up when some message or notification come
so i want to add a sound for that modal
the problem that this modal is in all over the app , and alot of jquery .show methods i should track and add that sound
$('#ajax_alert').show();
i tried to listen to a change, like changing in css attributes but didn't work
$('#ajax_alert').on("change",function(){
//make sound
})
how can i overwrite the show method ? i can trigger the sound inside it by checking if triggered id is ajax_alert, play that sound !
I agree with the comments that it's probably not the best idea and it seems a bit hacky, but it can be done.
So what the JQuery .show() method does is just change an element's CSS to display: block; right? So you can overwrite the .show method, but tell it to keep doing that and then also add some additional functionality:
jQuery.fn.show = function() {
this.css('display', 'block');
setTimeout(() => alert('My very own added functionality'), 0); // Newly added functionality
return this;
};
$('a').click(function() {
$('div').show()
})
div {margin-top: 20px; background-color: blue; height: 60px; width: 60px; display: none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click to show div
<div></div>
Working JSFiddle here:
I try to make a select box whose entries are opened after clicking into the input box. After selecting one of the items, the dropdown should be closed again.
I want to achieve the open/close part of the dropdown without the use of javascript.
The html looks like this:
<div id="outer">
<input type="text" id="input">
<div id="results">
<div>Test 1 </div>
<div>Test 2 </div>
<div>Test 3 </div>
<div>Test 4 </div>
</div>
</div>
<div id="label">
</div>
After clicking onto an item, the selected value should appear below the #outer div (just for demonstration purposes).
The Javascript for assigning click events to the dropdown values:
document.querySelectorAll("#results div").forEach(setClick);
function setClick(node) {
node.addEventListener("click", setText.bind(null, node.innerHTML))
}
function setText(t) {
document.getElementById("label").innerHTML = t;
}
Now I will show you my first draft of css code:
#outer {
width: 200px;
position: relative;
}
#input {
width: 100%;
}
#results {
position: absolute;
width: 100%;
display: block;
visibility: hidden;
background-color: white;
}
#results > div:hover {
background-color: lightblue;
cursor: pointer;
}
#outer:focus-within #results, #results:hover {
visibility: visible;
}
This works like a charm but fails in one point:
After clicking an item, the dropdown is not closed. This is because of the #results:hover selector which is needed to keep the dropdown open after clicking onto an item. The click takes the focus out of the input field, thus the focus-within selector is not applied anymore. As the focus is removed from the input before the click occurs, the dropdown is hidden when the final click arrives in the document (this is my understanding of the problem).
Thus I use the hover selector which forces the div to keep open as long as the mouse is above the div.
You can test this here:
https://jsfiddle.net/hcetz1og/3/
My solution for this was a transition that hides the dropdown after the focus has been taken away:
#outer:not(:focus-within) #results:hover {
visibility: hidden;
transition-property: visibility;
/*use 10 ms and the clicked value in the drop down won't be shown */
transition-delay: 100ms;
transition-timing-function: step-end;
}
This works on my machine when I use 100ms as a delay. If I use 10ms, I have the same problem again. It seems that the click event is triggered "very" late.
Feel free to test it here:
https://jsfiddle.net/hcetz1og/2
Question:
How long will it take until the click event arrives at the document? Is there a fixed time span I have to wait or can the delay depend on every machine?
If so, I am forced to not use plain CSS but must use javascript for this I think.
Edit:
Feel free to post an alternative solution using plain css. But please be aware that I mainly want to focus on getting an answer to this question, not alternative solutions.
As #Mark Baijens said in the comments, using timeouts is a bad practice, so here is a pretty clean solution.
I used JavaScript to render the dropdown, not the CSS, because the CSS is where Your issue is coming from.
I don't know why would You want to set the innerHTML, but not some other property, like style.visibility for example. It just doesn't make sense to me, so with that in mind, let's get our hands on this :)
Working demo >> HERE <<.
Step 1 - remove the #outer...:hover parts of CSS
So, You are left with this:
#outer {
width: 200px;
position: relative;
}
#input {
width: 100%;
}
#results {
position: absolute;
width: 100%;
display: block;
visibility: hidden;
background-color: white;
}
#results > div:hover {
background-color: lightblue;
cursor: pointer;
}
Step 2 - add the onfocus event to the input field
Just assign a function call to the onfocus attribute of the input. Everything else in the HTML stays the same.
<div id="outer">
<input type="text" id="input" onfocus="showElements()">
<div id="results">
<div>Test 1 </div>
<div>Test 2 </div>
<div>Test 3 </div>
<div>Test 4 </div>
</div>
</div>
<div id="label">
</div>
Step 3 - create the showElements and hideElements function:
function showElements() {
document.getElementById("results").style.visibility = 'visible';
}
function hideElements() {
document.getElementById("results").style.visibility = 'hidden';
}
Step 4 - call the hideElements() when clicked outside the input element
There are two cases for the click outside the input element:
Case 1 - we clicked on one of the divs inside the #results wrapper
Case 2 - clicking outside the input field, but not on one of the divs inside the #results wrapper
In the first case, we will modify the assignment of the onclick handler like this:
document.querySelectorAll("#results div").forEach(setClick);
function setClick(node) {
node.addEventListener("click", setTextAndHideElements.bind(null, node.innerHTML));
}
So, the setText function now becomes setTextAndHideElements and looks like this:
function setTextAndHideElements(t) {
document.getElementById("label").innerHTML = t;
hideElements();
}
For the second case (clicking outside the input field, but not on one of the divs inside the #results wrapper), we must watch for the click on the whole page (document element), and respond to the action like this:
document.onclick = function(e) {
if (e.target.id !== 'input'){
hideElements();
}
}
Note: this will override any previously assigned onclick events assigned to the document element.
As mentioned in the beginning, working demo is >> HERE (codepen.io) <<.
I tried another solution which requires no setting of additional JS events.
See: https://jsfiddle.net/hcetz1og/4/
I gave every result item a tabindex of "0" to ensure, those items can be focusable.
Then i removed the #outer:not() part from the css and replaced the hover selector with this: #results:focus-within. Additional I called node.blur() on the node after clicking onto them.
Summary:
Change in HTML:
<div tabindex="0">Test 1 </div>
Change in JS:
function setText(t, node) {
document.getElementById("label").innerHTML = t;
node.blur();
}
Change in CSS:
#outer:focus-within #results, #results:focus-within {
visibility: visible;
}
What do you think about this one? Should be stable I think because the focus onto the #results div is set before the click event is triggered onto the result item.
Event order should be (based on my observation):
input focus -> input blur -> item focus -> item click
Not sure if the step between blur and focus can lead to a visible problem. Theoretically, the results div must be hidden and shown again in a very small amount of time.
But I investigated this with chrome's performance timeline and did not recognize a new render between both events. One can see, that the result item is focused (outline is set onto it) and then it disappears as expected.
I have no idea what goes wrong with my code but it gives me errors every time I click the blue Chat Here button. The button's supposed to be shorter when the iframe is hidden then when the iframe slides up, the blue button should take up the whole space the same as the iframe as well.
View Demo
Here's the JS I have so far
function showChat() {
jQuery("#blk-collaboration .chatbox").slideToggle("slow",function(){
jQuery("#blk-collaboration #toggle").css("background","#45A1F1");
});
jQuery('#btn-chat').click(function() {
$(this)//this is a button DOM element. wrapping in jQuery object.
.toggleClass('wide'); // removing wide class so button became smaller.
});
}
$(document).ready(function(){
$('.chatbox').hide();
});
I'd greatly appreciate if you could provide me a demo as well. Been working on this code for two days now and I haven't found the right solution yet.
First of all, you forget to put ; on your height property. Another important thing is that you need to change your class position like this:
.button {
background: #45A1F1;
height: 40px;
width: 620px; /*Width of regular button */
}
.wide {
background: #45A1F1;
height: 40px;
width: 300px; !important; /* Width of wide button */
}
You can simplify your code by using this jQuery:
$(document).ready(function(){
$('.chatbox').hide();
$('#btn-chat').click(function() {
$("#blk-collaboration .chatbox").slideToggle("slow",function(){
$("#blk-collaboration #toggle").css("background","#45A1F1");
});
$(this)//this is a button DOM element. wrapping in jQuery object.
.toggleClass('wide'); // removing wide class so button became smaller.
});
});
Check out this Fiddle..
I'd like to display a little tooltip similar to this:
That little black box appears when I put my mouse over it. How can I achieve this? Is it using jQuery or MooTools or what?
Thanks from this beginnig web designer!
I think you can do it with CSS, no need for Javascript.
The black box (the tooltip) can be an absolutely positioned child with display: none by default, and on :hover you can show it.
Here is a little demo.
Example CSS:
.tooltipped { position: relative; }
.tooltip { display: none; position: absolute; width: 100%; left: 0; top: 35px; }
.tooltipped:hover .tooltip { display: block; }
for the HTML (which remains readable without CSS!):
<div class="tooltipped">3 <span class="tooltip">acorns remaining</span></div>
This method will work in every modern browser and IE >= 7. IE6 only supports the :hover selector on links, so you need to use an a element if you want to support it (or find a different workaround).
This is done through JavaScript. I would recommend using the jQuery framework, as there are a load of different jQuery Tool Tip plug-ins ready for you to use.
For example.
Definitely looks like Tipsy, a jQuery plugin I used.
With jQuery, assuming you had a div properly formatted like thus: (notice this is an extremely simple example. I'm not defining the classes to properly format the elements or anything like that)
3
and
<div class="onmouseoverpopup parent">
<div class="onmouesoverpopup arrowontopmiddle"></div>
<div class="onmouesoverpopup text">Acorns remaining</div>
</div>
You might do something like this
$(document).ready( function() {
$(".acornsremaining").hover( function() {
$(".onmouseoverpopup.parent").show();
}, function() {
$(".onmouseoverpopup.parent").hide();
});
});