jQuery keypress doesn't detect CTRL + V - javascript

The keypress doesn't detect CTRL + V when pressed on the text box. I have seen a similar post to mine. But we have different implementation. I want to trigger an ajax request if the user idle in typing for 1.5 sec.
$(document).ready( function() {
$(document).on('keypress', '#subject-name', function() {
updateTimeOut( this, checkSubject );
});
});
The method updateTimeOut() is something like this:
var updateTimeOut = function( textBoxObject, ajaxCall ) {
if (timeoutReference) clearTimeout(timeoutReference);
timeoutReference = setTimeout(function() {
doneTyping.call( textBoxObject, ajaxCall );
}, 1500);
};
My question is. Is't better to use change is the best for my task? Does change can also do check with interval?

Yes, you want to know when the values changes, no matter how it happens, keypress or not (e.g. right click text box and left click paste).
This should work for you
$(function() {
$(document).on('input', '#subject-name', function() {
updateTimeOut(this, checkSubject);
});
});
FYI, $(function() {}) is shorthand for $(document).ready(function() {}).

Related

jquery - do a click immediately on mousedown or touch

I have a 42" touchdisplay showing a webpage with IE9.
There are a lot of anchors on it. Sometimes a user does not just shortly taps a link but stays on it and nothing happens until he stops touching.
As a first solution I showed the user a message that he should take his finger of the touchpad.
var timeoutLongTouch;
$(".long-touch").on('mousedown.LongTouch', function () {
timeoutLongTouch = setTimeout(function () {
$("#warning").show();
}, 1000);
})
.on('mouseup.LongTouch', function () {
clearTimeout(timeoutLongTouch);
$("#warning").hide();
});
This works fine. But now I'd prefer to change the longtouch event to an immediatly fired click.
I tried several ways - f.e.
$(".long-touch").on('mousedown.LongTouch', function () {
var item = $(this);
setTimeout( function () {
console.log(item);
$(item).click();
}, 300);
});
But whatever I tried click is not fired until user takes his finger of.
Is there a way to convert the longtouch into a immiediate click when user touches a link, not depending of the duration of the topuch?
Could you try to use the following?
$('.long-touch').on('touchstart click', function(event){
event.stopPropagation();
event.preventDefault();
//do your stuff
});
For touch you need to use the touchstart, and we also listen to the click for normal desktop users.
I found a solution.
The idea of #Dirk-Jan together with not triggering a click, but simply refer to href location does it.
$('.long-touch').on('mousedown.LongTouch touchstart click', function(event){
event.stopPropagation();
event.preventDefault();
var item = $(this);
setTimeout( function () {
var dest = item.attr('href');
window.location.href = dest;
}, 300);
});

How do I detect when a div has lost focus?

Given the following markup, I want to detect when an editor has lost focus:
<div class="editor">
<input type="text"/>
<input type="text"/>
</div>
<div class="editor">
<input type="text"/>
<input type="text"/>
</div>
<button>GO</button>
EDIT: As the user tabs through the input elements and as each editor div loses focus (meaning they tabbed outside the div) add the loading class to the div that lost focus.
This bit of jquery is what I expected to work, but it does nothing:
$(".editor")
.blur(function(){
$(this).addClass("loading");
});
This seems to work, until you add the console log and realize it is triggering on every focusout of the inputs.
$('div.editor input').focus( function() {
$(this).parent()
.addClass("focused")
.focusout(function() {
console.log('focusout');
$(this).removeClass("focused")
.addClass("loading");
});
});
Here is a jsfiddle of my test case that I have been working on. I know I am missing something fundamental here. Can some one enlighten me?
EDIT: After some of the comments below, I have this almost working the way I want it. The problem now is detecting when focus changes to somewhere outside an editor div. Here is my current implementation:
function loadData() {
console.log('loading data for editor ' + $(this).attr('id'));
var $editor = $(this).removeClass('loaded')
.addClass('loading');
$.post('/echo/json/', {
delay: 2
})
.done(function () {
$editor.removeClass('loading')
.addClass('loaded');
});
}
$('div.editor input').on('focusin', function () {
console.log('focus changed');
$editor = $(this).closest('.editor');
console.log('current editor is ' + $editor.attr('id'));
if (!$editor.hasClass('focused')) {
console.log('switched editors');
$('.editor.focused')
.removeClass('focused')
.each(loadData);
$editor.addClass('focused');
}
})
A bit more complicated, and using classes for state. I have also added in the next bit of complexity which is to make an async call out when an editor loses focus. Here a my jsfiddle of my current work.
If you wish to treat entry and exit of the pairs of inputs as if they were combined into a single control, you need to see if the element gaining focus is in the same editor. You can do this be delaying the check by one cycle using a setTimeout of 0 (which waits until all current tasks have completed).
$('div.editor input').focusout(function () {
var $editor = $(this).closest('.editor');
// wait for the new element to be focused
setTimeout(function () {
// See if the new focused element is in the editor
if ($.contains($editor[0], document.activeElement)) {
$editor.addClass("focused").removeClass("loading");
}
else
{
$editor.removeClass("focused").addClass("loading");
}
}, 1);
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/8s8ayv52/18/
To complete the puzzle (get your initial green state) you will also need to also catch the focusin event and see if it is coming from the same editor or not (save the previous focused element in a global etc).
Side note: I recently had to write a jQuery plugin that did all this for groups of elements. It generates custom groupfocus and groupblur events to make the rest of the code easier to work with.
Update 1: http://jsfiddle.net/TrueBlueAussie/0y2dvxpf/4/
Based on your new example, you can catch the focusin repeatedly without damage, so tracking the previous focus is not necessary after all. Using my previous setTimeout example resolves the problem you have with clicking outside the divs.
$('div.editor input').focusin(function(){
var $editor = $(this).closest('.editor');
$editor.addClass("focused").removeClass("loading");
}).focusout(function () {
var $editor = $(this).closest('.editor');
// wait for the new element to be focused
setTimeout(function () {
// See if the new focused element is in the editor
if (!$.contains($editor[0], document.activeElement)) {
$editor.removeClass("focused").each(loadData);
}
}, 0);
});
Here's what worked for me:
$(".editor").on("focusout", function() {
var $this = $(this);
setTimeout(function() {
$this.toggleClass("loading", !($this.find(":focus").length));
}, 0);
});
Example:
http://jsfiddle.net/Meligy/Lxm6720k/
I think you can do this. this is an exemple I did. Check it out:
http://jsfiddle.net/igoralves1/j9soL21x/
$( "#divTest" ).focusout(function() {
alert("focusout");
});

Jquery rename content insite a tag and confirm it

The User should be able to change the Name and then confirm the change. I'm not able to archive it with this code as when I click confirm, it returns like before.
What am I missing?
Any better way to put this together (which I'm sure there's one) ?
Please check the demo where you can also see the changeElementTypefunction
http://jsfiddle.net/dLk6E/
js:
$('.replace').on('click', function () {
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').bind('click', function () {
$('.replace').show();
$('.confirm').hide();
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')) {
$(document).keypress(function (e) {
if (e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity', '1');
}
});
}
});
Here are your updated code and working fiddle http://jsfiddle.net/dLk6E/
(function($) {
$.fn.changeElementType = function(newType) {
var attrs = {};
$.each(this[0].attributes, function(idx, attr) {
attrs[attr.nodeName] = attr.nodeValue;
});
this.replaceWith(function() {
return $("<" + newType + "/>", attrs).append($(this).contents());
});
}
})(jQuery);
$('.replace').on('click', function (){
$("h2").changeElementType("textarea");
$('.replace').hide();
$('.confirm').show();
//Confermation of the change
$('.confirm').on('click', function(){
$('.replace').show();
$('.confirm').hide();
// you are missing this
$('.replaceble').html($("textarea").val());
$("textarea").changeElementType("h2");
});
if ($('textarea:visible')){
$(document).keypress(function(e) {
if(e.which == 13) {
alert('You pressed enter!');
$("textarea").changeElementType("h2");
$('.replace').css('opacity','1');
}
});
}
});
updated
jsfiddle.net/dLk6E/1
I think your code is right but you need to use the value you're entering when replacing it. So the confirmation binding would be something like this (fetching it, and then using it to update the textarea before "transforming" it into an h2 tag.
$('.confirm').bind('click', function(){
var valueEntered = $('textarea').val();
$('.replace').show();
$('.confirm').hide();
$("textarea").html(valueEntered).changeElementType("h2");
});
You could be using .on for this as well as of jQuery 1.7 is prefered to .bind.
Another thing I would suggest is whenever you struggle with something like this just put in google (or whatever...) exactly what you want, in this case "jquery get value of input" will get asw first result the jquery documentation
This way you won't forget it ;)
Update: Maybe a small detail but in the binding I use it would be more efficient to just hit $('textarea') once, so it would be something like this. Something that you may keep in mind (not really an issue here), better to store in a variable than hit the DOM several times.
$('.confirm').on('click', function(){
var $textarea = $('textarea');
$('.replace').show();
$('.confirm').hide();
$textarea.html($textarea.val()).changeElementType("h2");
});
jsfiddle

word counter Javascript function call

Wanted to have a word counter next to a input textbox on the website
Got it working to show the count when the user click or modify the text but I wanted to load up straight away when the page finish loading.
$(document).ready(function() {
$("#product_name").change(displayText).keyup(displayText);
function displayText(){
$("em#counter").text($(this).val().length +' chars');
}
});
So I tried this the code below but couldn't get it working and don't know why.
$(document).ready(function() {
if($("#product_name").length){
displayText();
}
$("#product_name").change(displayText).keyup(displayText);
function displayText(){
$("em#counter").text($(this).val().length +' chars');
}
});
Thanks so much.
Try this
if($("#product_name").length){
displayText();
}
$("#product_name").change(displayText).keyup(displayText);
function displayText(){
$("em#counter").text($("#product_name").val().length +' chars');
}
Demo: Fiddle
Problem was your displayText() call during page load. In displayText you had used $(this) to access the input field, which was working as a event handler. But when you call displayText directly this will point to the window object.
Try .on() with multiple event.
$("#product_name").on({
change: function() {
// Handle change event
},
keyup: function() {
// Handle keyup
}
});
and for "when the page finish loading." use $(window).load(function() { });

How to write onshow event using JavaScript/jQuery?

I have an anchor tag on my page, I want an event attached to it, which will fire when the display of this element change.
How can I write this event, and catch whenever the display of this element changes?
This is my way of doing on onShow, as a jQuery plugin. It may or may not perform exactly what you are doing, however.
(function($){
$.fn.extend({
onShow: function(callback, unbind){
return this.each(function(){
var _this = this;
var bindopt = (unbind==undefined)?true:unbind;
if($.isFunction(callback)){
if($(_this).is(':hidden')){
var checkVis = function(){
if($(_this).is(':visible')){
callback.call(_this);
if(bindopt){
$('body').unbind('click keyup keydown', checkVis);
}
}
}
$('body').bind('click keyup keydown', checkVis);
}
else{
callback.call(_this);
}
}
});
}
});
})(jQuery);
You can call this inside the $(document).ready() function and use a callback to fire when the element is shown, as so.
$(document).ready(function(){
$('#myelement').onShow(function(){
alert('this element is now shown');
});
});
It works by binding a click, keyup, and keydown event to the body to check if the element is shown, because these events are most likely to cause an element to be shown and are very frequently performed by the user. This may not be extremely elegant but gets the job done. Also, once the element is shown, these events are unbinded from the body as to not keep firing and slowing down performance.
You can't get an onshow event directly in JavaScript. Do remember that the following methods are non-standard.
IN IE you can use
onpropertychange event
Fires after the property of an element
changes
and for Mozilla
you can use
watch
Watches for a property to be assigned
a value and runs a function when that
occurs.
You could also override jQuery's default show method:
var orgShow = $.fn.show;
$.fn.show = function()
{
$(this).trigger( 'myOnShowEvent' );
orgShow.apply( this, arguments );
return this;
}
Now just bind your code to the event:
$('#foo').bind( "myOnShowEvent", function()
{
console.log( "SHOWN!" )
});
The code from this link worked for me: http://viralpatel.net/blogs/jquery-trigger-custom-event-show-hide-element/
(function ($) {
$.each(['show', 'hide'], function (i, ev) {
var el = $.fn[ev];
$.fn[ev] = function () {
this.trigger(ev);
return el.apply(this, arguments);
};
});
})(jQuery);
$('#foo').on('show', function() {
console.log('#foo is now visible');
});
$('#foo').on('hide', function() {
console.log('#foo is hidden');
});
However the callback function gets called first and then the element is shown/hidden. So if you have some operation related to the same selector and it needs to be done after being shown or hidden, the temporary fix is to add a timeout for few milliseconds.

Categories