When div blurs check for content change? - javascript

I have set up some content editable divs that have onblur functionality
<div class="inline-edit" contenteditable="true"></div>
$(document).ready(function(){
$('div.inline-edit').blur(function()
{
//functionality
});
});
and that all works grand for the functionality I've set up.
However the problem is the functionality will always occur when the blur even fires, even if the content in the editable div is never changed!
As the onchange method only works for inputs/textareas etc
I was curious if there was a simple~ way to do something like:
$(document).ready(function(){
$('div.inline-edit').blur(function()
{
if($('div.inline-edit').contentChanged())
{
//functionality
}
});
});

You could also look for keypress inside the div.
var changed = false;
$('#your-div').keypress(function (){
changed = true;
});
Or if your div data is very simple, you could save the original content and compare it when needed.

If only using 1 div, I'd set up an old and new variable and compare them on blur.
$(document).ready( () => {
var oldVal = $('.inline-edit').val();
$('.inline-edit').blur( () => {
let newVal = $('.inline-edit').val();
if (newVal === oldVal) {
return
}
//functionality
});
});

Related

jquery onblur not firing

I am trying to get an onblur/onfocus combination working for a pair of text boxes which I am selecting via class in jquery. I am not getting any errors in debug, but the blur function never seems to be called. When debugging my breakpoint in the blur function is not hit.
$(document).ready(function () {
var row = $(this).closest('tr');
$('.editClass').click(function () {
var editBoxes = $(row).find('.editClass');
var focus = 0;
$(editBoxes).focus(function () { focus++ });
$(editBoxes).blur(function () {
focus--;
setTimeout(function () {
if (!focus) {
alert('LOST FOCUS'); // both lost focus
}
}, 50);
});
});
});
Pretty sure the problem here was that the editBoxes were dynamically added to the page. This was not apparent in my question. Since they were dyncamically added I need to use
$(document).on('blur', '.editBoxes', function (){
...
}
The last two lines of your code example should be this
});
});
This is needed for closing the ready and click function call.
Another possible problem is that you wrap the focus and blur listeners in a click handlers. Why did you do this?

Jquery - How to copy an input that has a value on load

I have a website url field that has the value set for returning visitors who have previously filled out the form. If they change the value, then ('keyup blur paste', function() will copy it to a div. If they do not change the value, the ('keyup blur paste', function() does not copy the value to the div
I would like to figure out how to add to this script a function that would also copy the value to the div if they do not change it, because blur only works if they click in the input before they submit the form.
Here is my current script:
$(function () {
$('#Website').on('keyup blur paste', function() {
var self = this;
setTimeout(function() {
var str = $(self).val();
$("#viewer").text(str.replace(/^http\:\/\//, ''));
}, 0)
})
});
If I get you correctly, you want to populate the div on load as well as on keyup/blur/paste? Something like this?
$(function () {
$('#Website').on('keyup blur paste', function() {
var self = this;
setTimeout(function() {
var str = $(self).val();
$("#viewer").text(str.replace(/^http\:\/\//, ''));
}, 0)
});
// just add the line below
$("#viewer").text($('#Website').val().replace(/^http\:\/\//, ''));
});
I've updated the fiddle you created to demonstrate this working: http://jsfiddle.net/8kn4V/2/
on your page load...
$('#mydiv').html('whatever the value of the cookie');
is that what you need? as they mentioned in the comments above, your question is a little confusing.
use val() for input , select and textareas, and use text() for general elements like divs.
First solution
It seems now you are using a timeout of 0. That is not necessary at all, I think. So please check out this Fiddle:
$('#website').on("keyup blur paste", function () {
var s = $(this).text();
$("#viewer").text(s.replace(/^http\:\/\//, ''));
});
Edited solution
Now it seems you also want code that update #viewer from #website even when not triggered.
Here is a second fiddle — I hope you'll give credit if this solves the problem as it stands currently.
Relevant code:
function viewerupdate(me){
var s = me.text();
$("#viewer").text(s.replace(/^http\:\/\//, ''));
}
$('#website').on("keyup blur paste", function () { viewerupdate($(this)) });
var current_viewer = $('#viewer').text();
$('#submit').click(function(){ // assumes in the case that no change was made, that the submission is done through #submit
if($('#viewer').text() == current_viewer )
viewerupdate($('#website'));
});

lostfocus in 3 elements jquery

I have this code in my page
$("#ddlBirthdayDay,#ddlBirthdayMonth,#ddlBirthdayYear").change(function () {
$("form").validate().element("#ddlBirthdayYear");
});
I need to change it to: I haven't the focus in the three input $("#ddlBirthdayDay,#ddlBirthdayMonth,#ddlBirthdayYear"), I validate the element in the form.
How can I do this in jquery??
If all of your elements are in the same wrapper you could use focusout.
http://api.jquery.com/focusout/
Together with the :focus selector.
http://api.jquery.com/focus-selector/
var focusTimer = null;
$("form").on("focusout", function(){
clearTimeout(focusTimer);
focusTimer = setTimeout(function(){
var focusedElements = $("#ddlBirthdayDay,#ddlBirthdayMonth,#ddlBirthdayYear").filter(':focus');
alert(focusedElements.length);
}, 50);
});
Unfortunately you would need the set timeout as tabbing through the input fields would cause wrong results otherwise.
jsfiddle Demo
You can add an attribute to each element to say it lost focus. Then when all elements have lost focus, fire the validate event for each:
var $elems = $("#ddlBirthdayDay,#ddlBirthdayMonth,#ddlBirthdayYear");
$elems.blur(function () {
// Add a flag to this element to say it's lost focus
$(this).attr("data-blurred", "true");
console.log("blurred");
// If the number of elements in total equals the number with the blurred flag...
if($elems.filter("[data-blurred]").length === $elems.length) {
// Iterate over all the original elements and fire the validate event
$elems.each(function() {
$("form").validate().element($(this));
});
}
});
Here is a fiddle.
Sample code:
$(function(){
$('#a,#b,#c').on('blur',function(e){
setTimeout(function(){
if (!$('#a,#b,#c').is(':focus')) {
alert('Lost focus on all controls');
}
}, 50);
});
});
Take a look at my demo: Detect if controls lost focus

How can I update a input using a div click event

I've got the following code in my web page, where I need to click on the input field and add values using the number pad provided! I use a script to clear the default values from the input when the focus comes to it, but I'm unable to add the values by clicking on the number pad since when I click on an element the focus comes from the input to the clicked number element. How can I resolve this issue. I tried the following code, but it doesn't show the number in the input.
var lastFocus;
$("#test").click(function(e) {
// do whatever you want here
e.preventDefault();
e.stopPropagation();
$("#results").append(e.html());
if (lastFocus) {
$("#results").append("setting focus back<br>");
setTimeout(function() {lastFocus.focus()}, 1);
}
return(false);
});
$("textarea").blur(function() {
lastFocus = this;
$("#results").append("textarea lost focus<br>");
});
Thank you.
The first thing I notice is your selector for the number buttons is wrong
$('num-button').click(function(e){
Your buttons have a class of num-button so you need a dot before the class name in the selector:
$('.num-button').click(function(e){
Secondly, your fiddle was never setting lastFocus so be sure to add this:
$('input').focus(function() {
lastFocus = this;
...
Thirdly, you add/remove the watermark when entering the field, but ot when trying to add numbers to it (that would result in "Watermark-text123" if you clicked 1, then 2 then 3).
So, encalpsulate your functionality in a function:
function addOrRemoveWatermark(elem)
{
if($(elem).val() == $(elem).data('default_val') || !$(elem).data('default_val')) {
$(elem).data('default_val', $(elem).val());
$(elem).val('');
}
}
And call that both when entering the cell, and when clicking the numbers:
$('input').focus(function() {
lastFocus = this;
addOrRemoveWatermark(this);
});
and:
$('.num-button').click(function(e){
e.preventDefault();
e.stopPropagation();
addOrRemoveWatermark(lastFocus);
$(lastFocus).val($(lastFocus).val() + $(this).children('span').html());
});
You'll see another change above - you dont want to use append when appends an element, you want to just concatenate the string with the value of the button clicked.
Here's a working branch of your code: http://jsfiddle.net/Zrhze/
This should work:
var default_val = '';
$('input').focus(function() {
lastFocus = $(this);
if($(this).val() == $(this).data('default_val') || !$(this).data('default_val')) {
$(this).data('default_val', $(this).val());
$(this).val('');
}
});
$('input').blur(function() {
if ($(this).val() == '') $(this).val($(this).data('default_val'));
});
var lastFocus;
$('.num-button').click(function(e){
e.preventDefault();
e.stopPropagation();
var text = $(e.target).text();
if (!isNaN(parseInt(text))) {
lastFocus.val(lastFocus.val() + text);
}
});
Live demo
Add the following function:
$('.num-button').live( 'click', 'span', function() {
$currObj.focus();
$currObj.val( $currObj.val() + $(this).text().trim() );
});
Also, add the following variable to global scope:
$currObj = '';
Here is the working link: http://jsfiddle.net/pN3eT/7/
EDIT
Based on comment, you wouldn't be needing the var lastFocus and subsequent code.
The updated fiddle lies here http://jsfiddle.net/pN3eT/28/

Do not fire one event if already fired another

I have a code like this:
$('#foo').on('click', function(e) {
//do something
});
$('form input').on('change', function(e) {
//do some other things
));
First and second events do actually the same things with the same input field, but in different way. The problem is, that when I click the #foo element - form change element fires as well. I need form change to fire always when the content of input is changing, but not when #foo element is clicked.
That's the question )). How to do this?
Here is the code on jsfiddle: http://jsfiddle.net/QhXyj/1/
What happens is that onChange fires when the focus leaves the #input. In your case, this coincides with clicking on the button. Try pressing Tab, THEN clicking on the button.
To handle this particular case, one solution is to delay the call to the change event enough check if the button got clicked in the meantime. In practice 100 milisecond worked. Here's the code:
$().ready(function() {
var stopTheChangeBecauseTheButtonWasClicked = false;
$('#button').on('click', function(e) {
stopTheChangeBecauseTheButtonWasClicked = true;
$('#wtf').html("I don't need to change #input in this case");
});
$('#input').on('change', function(e) {
var self = this;
setTimeout(function doTheChange() {
if (!stopTheChangeBecauseTheButtonWasClicked) {
$(self).val($(self).val() + ' - changed!');
} else {
stopTheChangeBecauseTheButtonWasClicked = false;
}
}, 100);
});
});
And the fiddle - http://jsfiddle.net/dandv/QhXyj/11/
It's only natural that a change event on a blurred element fires before the clicked element is focused. If you don't want to use a timeout ("do something X ms after the input was changed unless in between a button was clicked", as proposed by Dan) - and timeouts are ugly - you only could go doing those actions twice. After the input is changed, save its state and do something. If then - somewhen later - the button is clicked, retrieve the saved state and do the something similar. I guess this is what you actually wanted for your UI behaviour, not all users are that fast. If one leaves the input (e.g. by pressing Tab), and then later activates the button "independently", do you really want to execute both actions?
var inputval = null, changedval = null;
$('form input').on('change', function(e) {
inputval = this.value;
// do some things with it and save them to
changedval = …
// you might use the value property of the input itself
));
$('#foo').on('click', function(e) {
// do something with inputval
});
$('form …').on('any other action') {
// you might want to invalidate the cache:
inputval = changedval;
// so that from now on a click operates with the new value
});
$(function() {
$('#button').on('click', function() {
//use text() not html() here
$('#wtf').text("I don't need to change #input in this case");
});
//fire on blur, that is when user types and presses tab
$('#input').on('blur', function() {
alert("clicked"); //this doesn't fire when you click button
$(this).val($(this).val()+' - changed!');
});
});​
Here's the Fiddle
$('form input').on('change', function(e) {
// don't do the thing if the input is #foo
if ( $(this).attrib('id') == 'foo' ) return;
//do some other things
));
UPDATE
How about this:
$().ready(function() {
$('#button').on('click', function(e) {
$('#wtf').html("I don't need to change #input in this case");
});
$('#input').on('change', function(e) {
// determine id #input is in focus
if ( ! $(this).is(":focus") ) return;
$(this).val($(this).val()+' - changed!');
});
});

Categories

Resources