I have set up previous focus storage in my document. When the button is clicked, a function gets executed. The value 0 is transported as a variable from the button to the function. In the function the new value is set to the previous focussed element. But it doesn't work. Why not? The reason why I do it this way is because I have more buttons, that give different values but only have to use the same function: setNewValue
Main script:
window.prevFocus = $();
// Catch any bubbling focusin events (focus does not bubble)
$(document).on('focusin', ':input', function () {
// Test: Show the previous value
$("#debug").html(prevFocus.attr("id"));
// Save the previously clicked value for later
window.prevFocus = $(this);
});
Button script
$("#butSetVal0").on({
click: function(){
newVal = 0;
setNewValue(newVal);
}
});
set new value script:
function setNewValue(newVal){
prevFocus.val(newVal).trigger("input");
}
I fixed it already. The solution is to set the eventhandler of the button on 'mousedown'. The 'click' trigger detects two clicks. The second click interprets as the previous focus element, so the button itself.
Related
I have a checkbox in a sortable div where the click or changed event is triggered twice on touch devices but not on desktop (nor simulating touch on Firefox dev tools) for some obscure reason. The unwanted effect is the checkbox being toggled twice in a row leaving it at its original state. I mention the div is sortable because when they are made no longer sortable the checkbox works just fine. Here is the relevant part:
$sortable.sortable({
items: '.sortable',
cancel: 'input,textarea,button,select,option'
});
I have no idea why the sortable widget makes the click event be fired twice.
My attempts to handle this have been unsuccessful:
I've tried disabling the default behaviour of toggling a the checkbox and setting its value manually. However for some reason the checkbox won't be checked/unchecked. If I do it via console it does work:
// same with the "change" event
// the reason the event is bound to $sortable rather than the inputs themselves is that
// new sortable divs are added dynamically so otherwise they wouldn't have the event bound to them
$sortable.on('click', 'input[type="checkbox"]', function (e) {
e.stopImmediatePropagation();
// this does disable the default behaviour of checking/unchecking the box
e.preventDefault();
const $this = $(this);
// this doesn't check/uncheck the box at all, but setting a global variable to $this and doing it via console does work
$this.prop('checked', !$this.prop('checked'));
});
I have tried a more typical approach using a flag, however there seems to be some race condition (or whatever it's called because if I am not mistaken js is monothreaded) and the function is run twice anyway:
let checked = false;
$sortable.on('click', 'input[type="checkbox"]', function() {
if (checked) return;
// this is output twice, which is not what we are after
console.log('running');
checked = true;
// here ideally we would set the value of the checkbox
checked = false;
});
I have checked for any problematic events bound to the inputs using $._data($checkboxes[0], 'events') but other than a bootstrap tooltip (mouseover and mouseout events) and of course the change event there's nothing else fishy.
edit: Basically it seems that the sortable widget produces a separate click event when you click anywhere in the div or its children. That's the reason why click/change is fired twice.
My question is: how can I discriminate between the originator of the event so that if it's the sortable plugin the event can be ignored, while if it's the listener I set up the checkbox does change its value (and I perform any other actions I may want to perform when the checkbox is actually checked)?
try touchend and if it works for click as well use the following way , else separate it
$sortable.on("touchend click", 'input[type="checkbox"]', function(e) {
if(e.type == 'touchend'){
$(this).off('click');
// your function
}
});
else try this for both
let checked = false;
$sortable.on("touchend click", 'input[type="checkbox"]', function(e) {
if(e.type == "touchend") {
checked = true;
// your function
}
else if(e.type == "click" && !checked ) {
// your function
}
});
I am attempting to add an event handler to an anchor only when certain form fields are populated, like so:
$('#newName, #newFrom').keyup(function (e) {
if ($('#newName').val() || $('#newFrom').val()) {
$('#add-person').click(function (e) {
//Handle event, includes adding a row to a table.
$('this').off();
});
}
});
It seems like the first event is getting propagated to the second one since I end up with the same number of rows in my table as keys I have typed.
I've tried adding
e.stopPropagation();
But with no success.
$('this').off(); should be $(this).off();
also probably you'd better go using the input event instead of keyup. input event will trigger even if one pastes content into your fields.
nevertheless I'd go the other way around:
// (cache your selectors)
var $newName = $("#newName"),
$newFrom = $("#newFrom");
// create a boolean flag
var haveNewValue = false;
// modify that flag on fields `input`
$newName.add( $newFrom ).on("input", function() {
haveNewValue = ($.trim($newName.val()) + $.trim($newFrom.val())).length > 0;
});
// than inside the click test your flag
$('#add-person').click(function (e) {
if(!haveNewValue) return; // exit function if no entered value.
// do stuff like adding row to table
});
What was wrong:
on every keyup you was assigning a new (therefore multiple) click event/s to the button, but the (corrected to:) $(this).off() was triggered only after an actual button click.
Also a better way to use .on() and off.() (notice the difference in using the .click() method and the .on() method) is:
function doCoffee() {
alert("Bzzzzzzzz...BLURGGUZRGUZRGUZRG");
}
$("#doCoffeeButton").on("click", doCoffee); // Register "event" using .on()
$("#bossAlertButton").click(function() {
$("#doCoffeeButton").off("click"); // Turn off "event" using .off()
});
I have an input text that I need detect when the text (value) change.
The value can be changed in two ways:
Allow to the user write in it.
The user click a button, runs a jQuery event and fill it with the
result.
For the item 1 I solved using keyup but for the item 2 I have no idea how can I detect when the text is changed.
I try change() but does not work.
You can use .trigger() inside your function where you fill the input.
$("#idOfButton").click(function() {
//do some stuff
//fill input
$("#edit").val("new stuff!").triggerHandler("keyup"); //<--Trigger keyup event
});
Demo: http://jsfiddle.net/Q8fCa/1
Add event handler on change() for item2 and in item1 keyup handler, trigger item2 change() event. Simple like that...
"runs a jQuery event and fill it with the result."
you can call another function from your jquery event.
$('sel').click(function(){
textedited(); // call your new function.
});
You can create an interval that checks whether the value of the input field has changed in every occasion (user input or button click) :
var oldValue = $('#field').val();
var newValue = oldValue;
var checkInputFieldInterval = window.setInterval(function() {
newValue = $('#field').val();
if (newValue !== oldValue) {
// VALUE CHANGED, DO STUFF
oldValue = newValue;
}
}, 100);
Note the the "100" is the interval period in ms. You can find more information about the setInterval() method on this page http://www.w3schools.com/jsref/met_win_setinterval.asp
You can do...
$('.name').on('keyup', function(){
/* I'll run when the button is clicked or there's a keyup event. */
})
$('button').on('click', function(){
$('.name').val('Bill').trigger('keyup');
})
Here's a quick demo: http://jsbin.com/uteceb/1/edit
Im trying to call a function when the value of any form value changes.
This is my code:
function reload()
{
tmp = findSWF("chart");
x = tmp.reload("chart.php", false);
}
function findSWF(movieName) {
if (navigator.appName.indexOf("Microsoft")!= -1) {
return window["ie_" + movieName];
} else {
return document[movieName];
}
}
$(".formclass").change(function() {
reload();
});
If i make a link with an onclick action, it works, but using the last .change action, nothing happens.
Ideally, i could also pass the name and value of what has changed to that url
the change event only kicks in when you changed the value AND the control loses focus for text controls:
The change event is sent to an element
when its value changes. This event is
limited to elements,
boxes and
elements. For select boxes,
checkboxes, and radio buttons, the
event is fired immediately when the
user makes a selection with the mouse,
but for the other element types the
event is deferred until the element
loses focus.
if you want to trigger the function as the user types in the control, try keydown() or keypress()
I have a page with a set of checkbox's, that I want to run a Javascript function on when there is a change (I have done something very similar with dropdown's - and that worked)
However with the checkbox's I have three problems:
my onChange event only runs "sometimes" (you have to change the focus between the different checkbox controls
when it does run it is returning the result of the previous checkbox (not the one just clicked on)
the jQuery always return the value true
Checkbox creation
<%= Html.CheckBox("sl-" + row.Id, value, new { onChange = "SuitabilityChecked("+row.Id+", "+key+")"})%>
Javascript
function SuitabilityChecked(providerId, parentRecordId) {
var params = {};
params.providerId = providerId;
params.parentRecordId = parentRecordId;
var value = $("#sl-" + providerId).val();
params.value = value;
$.getJSON("SuitabilityChecked", params, null);
};
Browsers are funny about radio buttons and check boxes and can delay the onchange until focus change. Try adding an onclick event to blur or call the change event directly.
Maybe something like this using jQuery Live (untested, off the top of my head):
$(':checkbox').live('click', function() { $(this).change(); });
What's happening:
Checkbox A clicked
Checkbox B clicked
Checkbox A has lost focus and fires onChange
Which makes it seem as if Checkbox B is returning the result of Checkbox A. If you were to press Tab after clicking Checkbox B in this scenario, you'd notice that its onChange would fire.