The HTML:
<asp:TextBox ID="dataTextBox" MaxLength="10" runat="server"></asp:TextBox>
<a class='new_message' onclick='focusMethod();' tabindex='-1' href='#dataTextBox"> New Message</a>";
Jquery function:
function focusMethod() {
$('[class=new_message]').click(function (e) {
e.preventDefault();
$($(this).attr('href')).focus();
});
}
When i click the anchor link the focus should go to the input text box. But it is taking 2 clicks to perform.
My scenarios are:
onclick is used in anchor tag to prevent default behaviour i.e firing the href.
I am building an accessible form so i need the href with value (so i wont be able to use href="#")
If i use just the click event handler without the function it is not being fired( instead href is fired and focus is not going to textbox)
It takes 2 clicks because the function focusMethod is fired first and then event handler is attached.
Is there any way to avoid performing the function "focusmethod' and only perform click event handler?
Because your method focusMethod is binding a new click event which is then executing next time you click that element. Just remove the inline click event onclick='focusMethod();' as it's not needed. Then instead of a function you can just do:
$('[class=new_message]').click(function (e) {
e.preventDefault();
$($(this).attr('href')).focus();
});
Edit:
Since your element is dynamic you need to use $(document).on(...) instead, otherwise the selector $(...).click(..) isn't going to find the element as it wouldn't exist when setting up the click event binding.
Below is a basic example with the element being dynamically created:
$(document).on("click", "[class=new_message]", function (e) {
e.preventDefault();
console.log("clicked");
$($(this).attr('href')).focus();
});
$("body").html("<a class='new_message' tabindex='-1' href='#dataTextBox'> New Message</a>");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
remove click event in HTML.
use only class.click in JS.
for href you are opening with single quote but closing with double quote.
$('[class=new_message]').click(function(e) {
e.preventDefault();
$($(this).attr('href')).focus();
});
<a class='new_message' tabindex='-1' href='#dataTextBox'> New Message</a>
It takes 2 clicks because the function focusMethod is fired first and then event handler is attached.
You've correctly identified the issue, you're requiring a click to run the function that contains the jQuery .click function. Just remove the focusMethod() function (and onclick) altogether.
$('.new_message').click(function(e) {
e.preventDefault();
$($(this).attr('href')).focus();
});
<asp:TextBox ID="dataTextBox" MaxLength="10" runat="server"></asp:TextBox>
<a class='new_message' tabindex='-1' href='#dataTextBox'>New Message</a>
If #Spencer Wieczorek answer(accepted answer) is not working for someone then you should just need a simple replace 'click' to 'turbolinks:click'.
$(document).on("turbolinks:click", "[class=new_message]", function (e) {
e.preventDefault();
console.log("clicked");
$($(this).attr('href')).focus();
});
Related
I have some inputs and a button. I want to implement function which allows to delete one of recently focused/focused out input.
I set onfocusout function which sets a click listener on button. If I focus on first input then focus out from it and click on button - works fine. But when I focus on first input, then on second and click on button - i get deleteCell() function performed n times i focused out.
How to let it remember only last onfocusout event? It seems to count my onfocusout events before clicking on button.
Thank you.
var input = document.createElement("input");
input.setAttribute("onfocusout", "myFunction()");
function myFunction() {
document.getElementById("delete-cell").addEventListener("click", function () {
deleteCell();
});
}
function deleteCell() {
alert(1);
}
Try adding an on-focusout listener to the relevant class of elements, and then add a "to-delete" class for the element focusedout (using "this" property). But only add this "to-delete" class after you have first removed it from all elements. This should keep you dialed into the element related to the most recent focusout event.
$(".element-class").on("focusout", function() {
$(".element-class").removeClass("to-delete");
$(this).addClass("to-delete");
})
Then simply write a function that will delete the element with the "to-delete" class, triggered by an on-click event.
Here is fiddle: https://jsfiddle.net/gbrodzik/ej4czqrc/6/
On a click function I have the option of playing audio.
The click is only fired once (after I added .off(), which I seem to have to do for every click event because I think there's something I fundamentally don't get about how javascript works) but the function added to the "ended" listener shows it is firing the number of times the button has been clicked. I presume .play() is also being fired multiple times.
These need to be inside the click event to get the id so how do I stop these kinds of things from happening, here and elsewhere when using js? Adding event.stopPropagation(), event.bubbles = false and .off() everywhere seems unnecessary (and in this case doesn't make a difference anyway).
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
});
}
});
Move the ended event outside the click event,you are registering the event each time you click on the button
$('.button').on('click', function(event){
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
}
});
$('[id^="audio_"]').on("ended", function(){
console.log("ended");
});
Each time you click on the button a new event listener will be added to the ended event. To prevent that you can try defining the callback function before hand. That will prevent your event listener to be added in the event loop over and over.
An anonymous function has no signature, hence when you define the event with it, it will think that this is supposed to be a new event listener and invokes it multiple times. Check the working snippets to see the difference. Type something in the input box to see what is happening.
If this is confusing then removeEventListener can be the next option.
function ended(event){
console.log("ended");
}
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
document.getElementById('audio_'+id).addEventListener("ended", ended);
}
});
var input = document.getElementById('some');
function callback(event) {
console.log("PRINT");
}
input.addEventListener("keyup", callback)
// input.removeEventListener("keyup", callback)
input.addEventListener("keyup", callback)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="some" value="" >
Anonymous function as callback
var input = document.getElementById('some');
input.addEventListener("keyup", function(event) {
console.log("PRINT");
})
// input.removeEventListener("keyup", callback)
input.addEventListener("keyup", function(event) {
console.log("PRINT");
})
<input id="some" value="">
This fails because, every time you click the function, you add a new event listener to the button.
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
This is repeatedly adding the event listener to the button.If you need this inside the click event, check to see whether it exists already. If it does, don't add it again.
Use global flag which defines if you want to pause or play. and also use preventDefault (in case of any inline click event used).
You have to remove the registered event listener after your task is completed.
document.getElementById('audio_'+id).removeEventListener("ended", function(){
console.log("ended");
});
Or what you can do is that move the logic for registering event listener outside the click event listener. Like this the event will be registered only once.
document.getElementById('audio_'+id).addEventListener("ended", function(){
console.log("ended");
});
}
$('.button').off().on('click', function(event){
event.stopPropagation();
event.bubbles = false;
var id = $(this).attr('id')
if ($(this).hasClass('hasAudio')) {
document.getElementById('audio_'+id).play();
});
$(":input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
registerButtons();
});
function registerButtons() {
$("#order").on("click", function(e) {
console.log("click triggered");
alert("Hello World");
});
$("#order").on("mousedown mouseup", function(e) {
console.log(e.type + " triggered");
});
}
registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
<button id="order">Order</button>
</div>
I have a web page with a button and some input fields.
On the button an click event is registered
On the input fields an change event is registered
The onChange will trigger an AJAX server call, and the result will replace parts of the web page - including the button. After AJAX result is processed, all listener are registered again.
Now the problem. A user changes the value of an input field, and clicks directly the button - but to slow (lets assume the user needs 500ms for the click), so the onChange event is fired and the page is "updated/replaced". Now the "old" button fires an onMouseDown and the "new" button fires an onMouseUp event - but no onClick.
My current workaround is, to register the two mouseDown/mouseUp events, get the timestamp of the mouse down, and if the mouse up comes in 2 seconds, do what should be done by the onClick.
It is no option to remove the button part from the AJAX response - in worst case the button could be removed and replaced by an user info.
My hope is, that there is a better solution... any ideas?
You can take advantage of the event delegation and set your listener on the container instead of the button.
You are adding a click listener to your old button and your adding a new button to the dom. So the click won't work.
The button wasn't working because for some reason it can't focus when you hover over it. So I added a getFocus method and now it should work.
$("input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
});
function registerButtons() {
$('#section').on("mouseup", '#order', function(e) {
alert('Clicked!');
});
}
registerButtons();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" value="123"/>
<div id="section">
<button id="order">Order</button>
</div>
I just found out that jQuery provides a sweet API that can be used for event delegation. This way we don't have to manually check for event target. Check it out http://api.jquery.com/on/
$("input").on("change", function(e) {
console.log("change triggered");
$("#section").html("<button id='order'>Order</button>");
});
function registerButtons() {
$("#section").on("click", '#order', function(e) {
console.log("click triggered");
alert("Hello World");
});
$("#section").on('mouseover','#order', function(e){
$(this).focus();
});
}
registerButtons();
I had button which had onclick function
<div id="canvas">
<button onclick="document.location.href='hello.php'">Go</button>
</div>
Now I want to stop this onclick event which redirects to hello.php, so I have written the following jQuery function
$("#canvas").on('click', 'button', function(event) {
event.preventDefault();
});
This didn't work so I added a return false but it's still not working.
$("#canvas").on('click', 'button', function(event) {
event.preventDefault();
return false;
});
You can view it at Jsfiddle
Note: I do not want to remove onclick of button
The correct solution is to remove the onclick from the HTML in the first place.
Assuming that's not possible, you can remove it after the fact:
$("#canvas button").first().prop("onclick", null);
That clears the onclick property on the element, which removes the handler set up by the onclick attribute. (It's a no-op if the button doesn't exist at all.)
It's probably worth noting that if the button is in a form, it will now submit the form, since its onclick isn't taking the user away from the page. (Since button's default type is submit.)
You should just use the removeAttr jQuery method:
$('#canvas button').removeAttr('onclick');
I have this function in JS :
jQuery(function ($) {
$(document).on("click", ".botaoExcluirRecibos", function (e) {
e.preventDefault();
alert("Fired!");
});
});
And in my asp.net page i have this button:
<div class="listaExcluir" id="listaExcluir">
<ul id="listaArquivos">
<li>
<div class="voceAnexou"></div>
<div class="divInformacoesAtendimento divInformacoesAtendimentoTabelaRecibo">
<p>VocĂȘ anexou:<strong> file1.png </strong></p>
<button class="botaoVermelhoPequeno botaoExcluirRecibos" onclick="return false;">Excluir</button>
</div>
</li>
</ul>
</div>
The button is added dynamically on the li tag, and more buttons can be added by the user.
It's not firing the click event at FIREFOX , but at CHROME is.
Obs: I had to add the onclick event inline on the button for preventing the postback issue.
First, you can add "return false;" to your event handler and it will avoid postbacks - you don't need to have it inline.
Second, I would recommend a binding function:
function BindClick(){
$(".botaoExcluirRecibos").unbind("click"); // To prevent double-binding click events!
$(".botaoExcluirRecibos").on("click", function(e){
e.preventDefault();
console.log("Fired!"); //Use the console instead of alerts for debugging purposes!
return false;
});
}
Now, just call:
BindClick();
Every time you add a control to the page that will need this event handler. This should work in every browser.