I show a search field on some text click, and hide it on search input blur.
But if I click on the search button I don’t want to hide the input field, and prevent it from being hidden (because of the blur). I tried to stopImmediatePropagation() without any luck.
Here’s some code:
// Not working. when search button is pressed, disable hiding the search input
$('.search-contacts-container > button').on('click touchstart', function(e) {
alert('xxx');
e.stopImmediatePropagation();
})
// when search input is blurred, hide it
$('#search-contacts').on('blur', function() {
$('.search-contacts-container').addClass('visuallyhidden');
$('#search-contacts').attr('required', 'false').blur();
})
// when search input is focused, show it
$('#search-contacts').on('focus', function() {
$('.search-contacts-container').removeClass('visuallyhidden');
$('#search-contacts').attr('required', 'true');
})
// on search text click, show the search input
$('.js-show-search').on('click touchstart', function() {
if ($('.search-contacts-container').is('.visuallyhidden')) {
$('.search-contacts-container').removeClass('visuallyhidden');
$('#search-contacts').attr('required', 'true').focus();
} else {
$('.search-contacts-container').addClass('visuallyhidden');
$('#search-contacts').attr('required', 'false').blur();
}
})
HTML:
<span class="js-show-search" title="Search for contacts">Search</span>
<form action="search" method="post" class="form-search search-contacts-container visuallyhidden">
<input type="text" id="search-contacts" placeholder="Search" required="false" />
<button type="submit" class="form-search__button" title="Search"></button>
</form>
Demo: http://jsfiddle.net/un775/
Any ideas?
Check out my new JsFiddle. I use this method on day to day tasks. I hope it helps you.
Basically what you are doing is adding a background that masks everything behind it, and then adding a click even listener to it that hides everything. The form/input is in front of the background allowing you to interact with it.
HTML
<div id="js-show-search">...</div>
<form id="search-contacts" class="hide">...</form>
<div id="background" class="hide"></div>
JavaScript
var searchContact, background;
searchContact = $('#search-contacts');
background = $('#background');
$('#js-show-search').on('click', function(){
//remove .hide to show elements
});
$('#background.close').on('click', function(){
//add .hide to hide elements
});
CSS
html, body {
height: 100%;
}
#background {
height: 100%;
width: 100%;
position: absolute;
top:0;
left: 0;
z-index: 0;
}
#search-contacts {
position: relative;
z-index: 1;
display: inline-block;
}
.hide {
display: none!important;
}
http://jsfiddle.net/un775/7/
Related
I have a code where I am showing a infobox when user clicks on an input field. This works fine but to make the UX better I would like the infobox to remain open when user clicks on a show button. It shouldn't close and open again
<div class="text-field">
<input type="text" class="username" name="username" placeholder="username" />
<button class="show-pwd">show</button>
</div>
<div class="info" style="display: none;">
<p>hello world</p>
</div>
$(function() {
const username = $('.username');
const showPwd = $('.show-pwd');
showPwd.click(()=>{
username.get(0).type = 'password';
$('.info').show();
});
$('.username').on("focus",(e)=>{
$('.info').show();
});
$('.username').on("blur",(e)=>{
$('.info').hide();
});
});
.text-field input {
border: none;
background-color: transparent;
}
.text-field {
background-color: lightblue;
width: 200px;
height: 25px;
}
.info {
background-color: lightgreen;
width: 200px;
height: auto;
}
heres the codepen
I tried to add the show method in click handler but that just adds a glitch
The blinking is happening because input blurring is triggered first, and then the button click.
You can avoid the blinking with a slight delay when blurring / moving out of the input, like in the following example.
const username = $('.username');
const showPwd = $('.show-pwd');
var btnClicked = false; // this is new
showPwd.click(()=>{
btnClicked = true; // this is new
username.get(0).type = 'password';
$('.info').show();
});
$('.username').on("focus",(e)=>{
$('.info').show();
});
$('.username').on("blur",(e)=>{
setTimeout(function() {
if(!btnClicked) {
$('.info').hide();
}
},100);
});
.text-field input {
border: none;
background-color: transparent;
}
.text-field {
background-color: lightblue;
width: 200px;
height: 25px;
}
.info {
background-color: lightgreen;
width: 200px;
height: auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="text-field">
<input type="text" class="username" name="username" placeholder="username" />
<button class="show-pwd">show</button>
</div>
<div class="info" style="display: none;">
<p>hello world</p>
</div>
One suggestion - since the current setup (and the original one) have no way of hiding the .info div once the button has been clicked, consider making your .show-pwd button a toggle button - one click to show the info div (if it's not visible), and another to hide it (if it's visible).
If you decide to do that, you would have to change my initial suggestion a bit, in order to avoid hiding the info div when moving from your input to your button.
And if you're up for some UX suggestions, you could change the show button - for example, you could use the open / closed eye icon to reflect what would happen on button click (similar to show / hide password in various online services, like Gmail, and the like).
I have a piece of html/javascript code that shows a loading gif when I click a submit button for my form. The problem is, when one of the form fields is empty when I click the submit button, there is a message "please fill in this field" shown and the form is not actually submitted, but the gif shows up anyways. In such situation, I don't want my gif to show up, but I don't know how to prevent that.
Do you have any tips on how to make it work?
EDIT: here is a relevant piece of my code - HTML:
<label for="username">username</label>
<input type="text" id="username" name="username" class="form-control"
placeholder="sampleusername" required>
<div class="overlay">
<div id="loading-img"></div>
</div>
<script>
$("#submit").click(function () {
$(".overlay").show();
});
</script>
And CSS:
#loading-img {
background: url('loading.gif') center center no-repeat;
height: 100%;
z-index: 20;
}
.overlay {
background: #e9e9e9;
display: none;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
opacity: 0.9;
}
I use a Bootstrap template that checks if the username field is empty and says to fill it if it is. I also use JQuery as you can see from the code.
You can use like below and hide the overlay whenever you require using $(".overlay").hide();
$("#submit").click(function () {
var isValid=$("#myform").valid();//using jquery validation
if(isValid)
{
$(".overlay").show();
event.preventDefault();
}
//submit the form
);
I have a menu which I want to display when the input is focused, so I used the focus and blur event of the input to trigger the function that either shows or hide the menu.
The problem is when I want to add events inside the menu (for example a click event), the blur event of the input is always triggered first so the click event of the menu is never triggered
Here's a sample code to illustrate my problem: https://jsfiddle.net/f7xvg1L9/27/
function hide () {
document.getElementById('box').style.display = 'none';
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>
(the select() function is never called)
Thanks in advance
You can do a lot of things in CSS instead of Javascript for this.
Here, setup a CSS rule for the selector input:focus + #box, #box:active, which displays the box.
#box:active is there to register the click on the box before it disappears, it won't work without it.
document.getElementById('box').addEventListener('click',() => {
document.getElementById('select').innerHTML = 'selected';
});
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
input:focus + #box, #box:active{
display: block;
}
<input type='text' id='input'/>
<div id='box'>
Test
</div>
<p id='select'></p>
That's an unfortunate side effect.
But it can be solved quite easily by using different events.
Instead of using a focus/blur handler, you can just use click events for all 3 of these, since focussing the input is the same as clicking inside it. And Blurring the input is the same as clicking outside of the input.
So if we show the box onclick of the input, we can then add a different click event to the rest of the document. Inside that click event, we can check if the current click is inside the box or not and act accordingly.
var box = document.getElementById('box');
var input = document.getElementById('input');
var change_text = function() {
box.innerHTML = 'selected';
};
var outside_click = function( event ) {
if ( !box.contains(event.target) ) {
box.style.display = 'none';
document.removeEventListener('click', outside_click);
}
};
var show_box = function( event ) {
event.stopPropagation();
box.style.display = 'block';
document.addEventListener('click', outside_click);
};
box.addEventListener('click', change_text);
input.addEventListener('click', show_box);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
Edit: But the CSS solution posted above is a way better and easier solution.
Two things you can use:
event.relatedTarget - This is only valid for focus and blur events on only contains a value if the relatedTarget has tabindex=1 or greater.
the useCapture phase of addEventListener which allows you to get at events before most things get to them.
In the example below I use them both, though I really only needed to use the event.relatedTarget since that let me see that the user was clicking on the #box and prevent from closing the box.
function hide (evt) {
if (evt.relatedTarget && evt.relatedTarget.id === 'box') {
document.getElementById('box').style.display = 'none';
document.getElementById('input').focus();
}
else {
document.getElementById('box').style.display = 'none';
}
}
function show (evt) {
document.getElementById('box').style.display = 'block';
}
function select (evt) {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide);
document.getElementById('input').addEventListener('focus', show);
document.getElementById('box').addEventListener('click', select, true);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type="text" id="input"/>
<div id="box" tabindex="1">
Test
</div>
<p id="select"></p>
I think the most quick and simple way would be to use setTimeout in the hide function.
function hide () {
setTimeout(function(){
document.getElementById('box').style.display = 'none';
}, 300)
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>
Following is my fiddle in which i made a div with class overlay and i am trying to do that when user clicks on submit button then that overlay class div appears on the div of contact form and on clicking close button that div hides and it shows the reset form again. Kindly let me know how can I make such kind of overlay on the contact form on submit button
http://jsfiddle.net/VqDKS/
.overlay
{
background-color: yellow;
height:200px;
width: 300px;
}
See this, edited with jQuery and CSS. Set the overlay to position: absolute and hide it before the form is submitted. Then remove it when the 'Close'-button is clicked.
http://jsfiddle.net/VqDKS/3/
CSS:
.overlay
{
background-color: yellow;
height:200px;
width: 300px;
position: absolute;
top: 0px;
z-index: 99;
display: none;
}
Jquery code:
function js()
{
alert('clicked submit: get typed name');
var name = $("#FN3").val();
$("#name").html( name );
$(".overlay").fadeIn()
return false;
}
$(document).ready(function(){
$(".close").click(function(){
$(".overlay").fadeOut();
$('#contact_form3 input[type="text"]').val('');
});
});
Make following change in HTML:
<input type="button" value="close" class="close">
You need to hide your overlay at the beginning just show the form. When clicked submit, show overlay and hide the form. Then when close is clicked hide the overlay and show the form.
It can be as :
function js()
{ alert('clicked submit: get typed name');
var name = $("#FN3").val();
$("#name").html( name );
$("#form-div").hide();
$(".overlay").show();
return false;
}
function closeOverlay(){
$("div.overlay").hide();
$("div#form-div").show();
}
please have a look here :
http://jsfiddle.net/injulkarnilesh/VqDKS/7/
Basically you need to set the contact form wrapper position property to relative and then just set position of your overlay to absolute, something like this:
.contact_wrapper { position: relative; }
.overlay { position: absolute; top: 0; left: 0; }
This way you will be sure that your overlay will be absolute positioned on the top of your contact form.
When page is loaded, we don't need the overlay, so you can add the following property:
.overlay { display: none; }
In your code, when you submit the form you are using onclick event to execute your handler.
Here you need to make overlay visible again, you can use .show() of jQuery:
$('.overlay').show();
And now you need to add event handler to deal with close button, you can simply add unique idintifier (e.g. class) to the element, then with jQuery you can trigger click event for this element and here you can hide your overlay.
$('.closeBtn').click( function() {
$('.overlay').hide();
});
By the way, you can read about .submit() and .ajax() methods in jQuery.
Here is a working jsFiddle.
I updated your fiddle a bit: http://jsfiddle.net/nweevers/VqDKS/8/
This is a way to do this. But then your form isn't still submitted.
The best way is to show the overlay after the post. And then you can hide the overlay with the button.
$overlay.on('click', 'input[type=button]', function() {
$overlay.hide();
});
I have this markup one of my web pages,
<div class="radio-spoof">
<input type="radio" name="enquiry" value="General enquiry" class="radio"/>
<div class="checked"></div>
</div>
<label for="general_enquiry">General enquiry</label>
<div class="radio-spoof">
<input type="radio" name="enquiry" value="Request a brochure" class="radio" checked="true"/>
<div class="checked"></div>
</div>
<label for="request_a_brochure">Request a brochure</label>
Basically what I am doing is trying to spoof some radio buttons, so I can have good looking ones, when a radio is checked I want to display .checked which is set to display:none by default. I need to check for a checked radio button on DOMReady and when ever a radio is clicked, currently I have this page, but it does not seem to be making the selection of the .checked div correctly.
if($('input[type=radio]:checked')) {
console.log("!");
$(this).parent().children('div').show();
}
I would expect the code above the select the radio buttons parent, and then look for a child div (.checked) and show it. Am I mistaken?
`
$(function(){
$(':radio').change(function(){
var $this = $(this);
console.log($this);
$(':radio[name='+this.name+']').next().hide();
if($this.is(':checked')){
$this.next('.checked').show();
}
});
});
For above issue, i have done solution on codebins. So, try it on http://codebins.com/codes/home/4ldqpb6
Solution:
$(document).ready(function() {
$('input[type=radio]').each(function() {
if ($(this).is(':checked')) {
$(this).next('.checked').show();
}
$(this).click(function() {
if ($(this).is(':checked')) {
$(this).next('.checked').show();
}
});
});
});
demo you need to register an event when check box state changes : http://jsfiddle.net/FtPLS/2/ or http://jsfiddle.net/QCkpG/1/
Also I reckon you should use .next instead of .children.
if you want to hide .checked just do this => $('.checked').hide()
you could use $('input[type=radio]').is(':checked') for your check/uncheck condition.
Hope this helps the cause, :)
code
$(function() {
// here ==> $('.checked').hide(); will hide all the div with checked class
$('input').click(function() { // can use .change instead if you want
if ($('input[type=radio]').is(':checked')) {
alert('!')
$(this).parent().next('div').show(); // whatever you wanna show or
//$(this).next('div').show();
}
});
});
It seems to me that you're trying to get custom-styled radiobuttons? A pretty cool way without JS I had in a project was this (adapted to your code):
HTML
<div class="radio-spoof">
<input id="radio-1" type="radio" name="enquiry" value="General enquiry" class="radio"/>
<label for="radio-1">General enquiry</label>
</div>
CSS
.radio-spoof input {
position: absolute;
left: -9999px;
} /* not display: none so it is tabbable */
.radio-spoof label {
display: inline-block;
padding-left: 35px; /* width of your custom image + spacing to text */
height: 30px;
line-height: 30px; /* height of your custom image */
background: url(your/custom/image) center left no-repeat;
}
.radio-spoof input:checked + label {
background-image: url(your/custom/active/image);
}
The checkbox toggles everytime the label gets clicked, they're connected through input id and label for, and the label gets the input style.
If you want the checkboxes to look like default if they're not checked you can set it up like this:
CSS
.radio-spoof input + label { display: none }
.radio-spoof input:checked {
position: absolute;
left: -9999px;
}
.radio-spoof input:checked + label {
display: inline-block;
padding-left: 35px; /* width of your custom image + spacing to text */
height: 30px;
line-height: 30px; /* height of your custom image */
background: url(your/custom/image) center left no-repeat;
}
Then you have default radios and if they're checked the label takes their place...