So I've got a page with a search box, a check-mark, and a loading spinner. When the user focuses on the search box, spinner fades in. User un-focuses on search box, spinner fades out. I have a function to toggle the check-mark after the user presses enter in the search box, however, i would like the check-mark to stay visible forever. As of now, when the user presses enter, it toggles the checkmark and shortly fades out because the unfocus function is called automatically.
Toggle checkmark function:
$('#searchText').on('keypress', function (e) {
if (e.which === 13) {
var val = $('#searchText').val();
$('.circle-loader').toggleClass('load-complete');
$('.checkmark').toggle();
alert(val);
return false;
}
});
Fade in and out function:
$(function () {
$('#searchText').focusin(function () {
$('#check').fadeIn();
}).focusout(function () {
$('#check').fadeOut();
});
});
How can i override the fade in and out function (or rewrite this perhaps) to stop when the user presses enter in the search box?
Thanks in advance.
Use the jQuery .stop method. When .stop() is called on an element, the currently-running animation (if any) is immediately stopped. If, for instance, an element is being hidden with .slideUp() when .stop() is called, the element will now still be displayed, but will be a fraction of its previous height. Callback functions are not called.
https://api.jquery.com/stop/
I would approach this with a boolean to indicate if a search has been performed. See below as an example. Without knowing the structure of your code I made it global but that could be changed to check a particular object instead.
Toggle checkmark function:
var searchPerformed = false;
$('#searchText').on('keypress', function (e) {
if (e.which === 13) {
searchPerformed = true;
var val = $('#searchText').val();
$('.circle-loader').toggleClass('load-complete');
$('.checkmark').toggle();
alert(val);
return false;
}
});
Fade in and out function:
$(function () {
$('#searchText').focusin(function () {
$('#check').fadeIn();
}).focusout(function () {
if (!searchPerformed)
$('#check').fadeOut();
});
});
Fixed with
$('#searchText').unbind("focusin");
$('#searchText').unbind("focusout");
in the toggle check-mark function.
Thanks for alternate methods as well everyone, will be handy in the future.
Related
Want to make it so when my menu items transition away, the search bar pops up.
let menuItemsQuerySelector = document.querySelectorAll(".menu-item");
searchElement.addEventListener("click", function() {
console.log("Clicked search");
menuItemsQuerySelector.forEach(function(menuItem) {
console.log("Boom");
menuItem.classList.toggle("hide-item");
});
});
};
this is what i have so far to make the toggle animation work. my claases for the search bar are, search-from, i need to make it active somehow when the menu disappears. The css class is already set up.
You can use the "transitionend" event to execute code after the transition ends.
You would have to add a boolean to check whether the transition was hidden-visible or visible-hidden
let hidden = false;
searchElement.addEventListener("click", function() {
hidden = true;
//your other code
});
//Further down the line when showing your elements again
hidden = false;
However seeing that you have multiple elements that transition at the same time, you could either:
Hook the event only on one of them
menuItemsQuerySelector[0].on('transitionend', () => {
if(hidden)
//your code here
});
or Use a timed function
setTimeout(() => {
if(hidden)
//your code here
}, <delay in millisecods>);
Pre-story: I am using Algolia search to search on my website.If the user start typing in the input field the results will start appearing on the screen.
End goal: close the filters (toggle functionality) by default.
Issues: when the user start typing in the input the url change and the filters stay open.
If I apply the code in the console after the user finishes with typing I can see the button being close.
If I apply the jQuery codes bellow and while I am typing the filters stay closed, but again once the user stops typing the filters open again.
Once I finish with typing (input looses focus) the filters open again.
My approach:
First
$("input#dropdown_search").on('input',function(e){
$("b- utton.button.filters__button").click();
});
Second
$('input#dropdown_search').keyup(function() {
$("button.button.filters__button").click();
});
Third
$('input#dropdown_search').on('inputchange', function() {
$("button.button.filters__button").click();
});
Fourth
$("input#dropdown_search").on('change keyup paste', function () {
ApplyFilter();
});
function ApplyFilter() {
$("button.button.filters__button").click();
}
It seems that they don't reach the end goal where they keep the filter hidden even after the user stops typing.
Can you please help?
Try this
$("input#dropdown_search").on('change', function () {
$("button.button.filters__button").trigger("click");
});
For your stop typing problem try this answer: Run javascript function when user finishes typing instead of on key up?
You can use trigger to trigger click
$("#dropdown_search").on('change keyup paste',function(event){
$(".buttonclass").trigger('click'); //trigger .buttonclass button on trigger of events
})
$(".buttonclass").on('click',function(event){
alert("I am clicked")
})
Example jsFiddle
Try this:
var timer;
$("input#dropdown_search").on('change keyup', function () {
clearInterval(timer);
timer = setInterval(function() {
ApplyFilter();
}, 1500);
});
type in first input , that will click the button immediately then fire function to change the second input value
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<input type=text id=dropdown_search>
<input type=text id=dropdown_search2>
<button id=target onclick="be()">
<script>
onload = function () {
var t = document.getElementById('dropdown_search');
t.oninput = function (){
document.getElementById("target").click();
};
t.onpropertychange = t.oninput; // for IE8
t.onchange = t.oninput;
};
function be() {
var t = document.getElementById('dropdown_search').value;
document.getElementById('dropdown_search2').value=t;}
</script>
</body></html>
I have some code in which I want to stop user from clicking a button multiple times. I have tried multiple things including disabling button on click and enabling it at the end but nothing is working perfectly.
I want to stop "click" event of jQuery (single click) from being executed in case user has clicked on it two or more times.
This is my js fiddle: https://jsfiddle.net/tm5xvtc1/6/
<p id="clickable">Click on this paragraph.</p>
<p id="main">
I will change on clicking
</p>
$("#clickable").click(function(){
$('#main').text('Single click');
});
$("#clickable").dblclick(function(){
$('#main').text('Double click')
});
If i try double clicking, the behavior is:
Single click gets executed first => Then double click gets executed.
I want to prevent single click event to be executed in case user clicks on button multiple times. Suggestions?
According to the jquery documentation:
It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable.
That being said, you can accomplish what you want by using $('#main').addClass('clicked-once'); and testing for the existence of that class before executing the code inside the single click handler.
$("#clickable").click(function(){
if($(this).hasClass('clicked-once')){
return false;
} else {
$(this).addClass('clicked-once');
$('#main').text('Single click');
}
});
$("#clickable").dblclick(function(){
$('#main').text('Double click')
});
jsfiddle: https://jsfiddle.net/nbj1s74L/
This is bit tricky. You need to calculate the time taken for double click and trigger events. Try the below code
$(function() {
var clicks = 0;
var timer = null;
$("#clickable").on("click", function(e) {
clicks++; // Increment click counter
if (clicks === 1) {
timer = setTimeout(function() {
$('#main').text('Single click');
clicks = 0; //Reset
}, 800); // Increase or decrease if there is slowness or speed
} else {
clearTimeout(timer); //prevent single-click action
$('#main').text('Double click')
clicks = 0; // Reset
}
});
$("#clickable").on("dblclick", function(e) {
e.preventDefault(); //Prevent double click
});
});
Demo : https://jsfiddle.net/cthangaraja/e9e50jht/2/
I found the answer for this.
$(document).on('click', '#clickable', function () {
$(this).prop('disabled', true);
//LOGIC
setTimeout(function () { $(this).prop('disabled', false); }, 500);
});
Its working for me. The set timeout for 500ms doesn't allow code to be re-entrant which is working fine for me at various network/device speeds.
Slight change in the answer given by maverick.
In the set timeout method, reference of this is changed. Hence the code should be changed to:
$(document).on('click', '#clickable', function () {
var self = this;
$(this).prop('disabled', true);
//LOGIC
setTimeout(function () { $(self).prop('disabled', false); }, 500);
});
window.numOfClicks = 0
$("#clickable").click(function(){
window.numOfClicks += 1;
//rest of code
});
Record the number of clicks to use for your functions, example:
if (window.numOfClicks > 1){ //do this}
If you need it reset just put a timeout in the .click()
var resetClicks = function(){ window.numOfClicks = 0 }
$("#clickable").click(function(){
//your other code
setTimeout(resetClicks,5000); //reset every 5 seconds
});
When user clicks on input field, two consecutive events are being executed: focus and click.
focus always gets executed first and shows the notice. But click which runs immediately after focus hides the notice. I only have this problem when input field is not focused and both events get executed consecutively.
I'm looking for the clean solution which can help me to implement such functionality (without any timeouts or weird hacks).
HTML:
<label for="example">Example input: </label>
<input type="text" id="example" name="example" />
<p id="notice" class="hide">This text could show when focus, hide when blur and toggle show/hide when click.</p>
JavaScript:
$('#example').on('focus', _onFocus)
.on('blur', _onBlur)
.on('click', _onClick);
function _onFocus(e) {
console.log('focus');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
$('#notice').removeClass('hide');
}
function _onClick(e) {
console.log('click');
$('#notice').toggleClass('hide');
}
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide');
}
UPDATED Fiddle is here:
I think you jumbled up the toggles. No need to prevent propagation and all that. Just check if the notice is already visible when click fires.
Demo: http://jsfiddle.net/3Bev4/13/
Code:
var $notice = $('#notice'); // cache the notice
function _onFocus(e) {
console.log('focus');
$notice.removeClass('hide'); // on focus show it
}
function _onClick(e) {
console.log('click');
if ($notice.is('hidden')) { // on click check if already visible
$notice.removeClass('hide'); // if not then show it
}
}
function _onBlur(e) {
console.log('blur');
$notice.addClass('hide'); // on blur hide it
}
Hope that helps.
Update: based on OP's clarification on click toggling:
Just cache the focus event in a state variable and then based on the state either show the notice or toggle the class.
Demo 2: http://jsfiddle.net/3Bev4/19/
Updated code:
var $notice = $('#notice'), isfocus = false;
function _onFocus(e) {
isFocus = true; // cache the state of focus
$notice.removeClass('hide');
}
function _onClick(e) {
if (isFocus) { // if focus was fired, show/hide based on visibility
if ($notice.is('hidden')) { $notice.removeClass('hide'); }
isFocus = false; // reset the cached state for future
} else {
$notice.toggleClass('hide'); // toggle if there is only click while focussed
}
}
Update 2: based on OP's observation on first click after tab focus:
On second thought, can you just bind the mousedown or mouseup instead of click? That will not fire the focus.
Demo 3: http://jsfiddle.net/3Bev4/24/
Updated code:
$('#example').on('focus', _onFocus)
.on('blur', _onBlur)
.on('mousedown', _onClick);
var $notice = $('#notice');
function _onFocus(e) { $notice.removeClass('hide'); }
function _onClick(e) { $notice.toggleClass('hide'); }
function _onBlur(e) { $notice.addClass('hide'); }
Does that work for you?
Setting a variable for "focus" seems to do the trick : http://jsfiddle.net/3Bev4/9/
Javascript:
$('#example').on('focus', _onFocus)
.on('click', _onClick)
.on('blur', _onBlur);
focus = false;
function _onFocus(e) {
console.log('focus');
$('#notice').removeClass('hide');
e.preventDefault();
e.stopPropagation();
e.stopImmediatePropagation();
focus = true;
}
function _onClick(e) {
console.log('click');
if (!focus) {
$('#notice').toggleClass('hide');
} else {
focus = false;
}
}
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide');
}
If you want to hide the notice onBlur, surely it needs to be:
function _onBlur(e) {
console.log('blur');
$('#notice').addClass('hide'); // Add the hidden class, not remove it
}
When doing this in the fiddle, it seemed to fix it.
The code you have written is correct, except that you have to replae $('#notice').removeClass('hide'); with $('#notice').addClass('hide');
Because onBlur you want to hide so add hide class, instead you are removing the "hide" calss.
I hope this is what the mistake you have done.
Correct if I am wrong, Because I don't know JQuery much, I just know JavaScript.
you can use many jQuery methods rather than add or move class:
Update: add a params to deal with the click function
http://jsfiddle.net/3Bev4/23/
var showNotice = false;
$('#example').focus(function(){
$('#notice').show();
showNotice = true;
}).click(function(){
if(showNotice){
$('#notice').show();
showNotice = false;
}else{
showNotice = true;
$('#notice').hide();
}
}).blur(function(){
$('#notice').hide();
});
I have a small jQuery script:
$('.field').blur(function() {
$(this).next().children().hide();
});
The children that is hidden contains some links. This makes it impossible to click the links (because they get hidden). What is an appropriate solution to this?
This is as close as I have got:
$('.field').blur(function() {
$('*').not('.adress').click(function(e) {
foo = $(this).data('events').click;
if(foo.length <= 1) {
// $(this).next('.spacer').children().removeClass("visible");
}
$(this).unbind(e);
});
});
The uncommented line is suppose to refer to the field that is blurred, but it doesn't seem to work. Any suggestions?
You can give it a slight delay, like this:
$('.field').blur(function() {
var kids = $(this).next().children();
setTimeout(function() { kids.hide(); }, 10);
});
This gives you time to click before those child links go away.
This is how I ended up doing it:
var curFocus;
$(document).delegate('*','mousedown', function(){
if ((this != curFocus) && // don't bother if this was the previous active element
($(curFocus).is('.field')) && // if it was a .field that was blurred
!($(this).is('.adress'))
) {
$('.' + $(curFocus).attr("id")).removeClass("visible"); // take action based on the blurred element
}
curFocus = this; // log the newly focussed element for the next event
});
I believe you can use .not('a') in this situation:
$('.field').not('a').blur(function() {
$(this).next().children().hide();
});
This isn't tested, so I am not sure if this will work or not.