jQuery / Javascript replace function only works once - javascript

I have a button as such
<button id="toggle_photo">
<span id="photo_text">Hide Photos (1)</span>
<img class="icon" alt="Photos" src="/img/photos-16.png">
</button>
And jQuery / Javascript to change the text upon clicking
$('#toggle_photo').click(function(){
var text = $('#photo_text').text();
$('#photo_text').text(
text.match(/Hide Photos/) ? text.replace("Hide", "Show") : text.replace("Show", "Hide"));
$('.photo_frame').toggle('slow');
});
This works the first time the button is clicked and the button text changed from Hide Photo (1) to Show Photo (1). Next, the button html is replaced with new text via an AJAX call, new contents are the same except perhaps for the count, so it might show this instead
<button id="toggle_photo">
<span id="photo_text">Hide Photos (3)</span>
<img class="icon" alt="Photos" src="/img/photos-16.png">
</button>
However, this time the element didn't trigger a click event, why?

You already gave the answer yourself:
Next, the button html is replaced with new text via an AJAX call...
You are removing the current element and adding a new one. The elements might be of the same type and have the same ID, but they are still different elements.
You either have to bind the event handler again after you changed the HTML, or you use .live() [docs] or .delegate() [docs] to bind the event handler.
Edit: I'm actually not sure whether you replace the whole button or just its contents. But I assume this is the problem. If this does not help, you have to be more specific and also post the function which replaces the HTML.

Related

difference between having a click handler on a button or on its parent?

Between
<button onClick={...}>Click me</button>
and
<span onClick={...}>
<button>Click me</button>
</span>
are there any differences for the user? I know that the click event will always bubble up to the span element, but are there any accessibility issues or unintended consequences that could arise from this?
There is a massive difference!
If you tab to a <button> so it is focused you can activate it using Enter and it will activate the click handler. It will not do this with a <span> (even if you add tabindex="0" to the <span> so it is focusable).
Also having a click handler on a <span> around a <button> will cause issues as you then have nested active elements. This means that when you click on the <button> that is within a <span> there is no way of knowing which element is supposed to fire an event (is it the <span> click handler or the <button> click handler?)
The question is, why do you want to attach the handler to the <span> as it may be that there is a better way to do what you are attempting. Let me know and I will see if I can help you structure things better / work around the problem!
since your question is about accessibility, you sure shouldn't do this because you have a native element for "clicking things" in HTML, but if you insist you can make a span work as a button by:
adding the role='button' attribute
handle the aria-pressed attribute value
define a value for tabindex attribute.
if you didn't do this the screen readers users will have a difficult time in your website
this link contains an example how button can be considered a div with extra attributes: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role
In that setup, you should be fine. If however you had a <span> inside of the <button>, then that's when you'll run into issues because a button should not contain children elements, only the value.
<button type="button" onclick="alert("Yo");"></button>
= works
<button type="button"><span onclick="alert("Yo");"></button> = fails
And then I believe Firefox handles these events differently to Chrome, but the latest builds should be ok.
when you call the onclick on span you dont need to use event.preventDefault. but when you use button or a you need to use event.preventDefault. that the basic difference
Why do you need the button element? Just use <span onclick="onClick()> You can style the span with css. Personally I think button is redundant.

Why isn't clear button function isn't working?

The clear button isn't working to clear list-group history
//html
<button class="btn btn-primary mb-3"
type="button"
id="clear-inputs"
onclick="clearIt()">
Clear history
</button>
<form id="history"></form>
<div class="list-group" id="history"></div>
//javascript clear button function
function clearIt() {
document.getElementById('history').value = "";
}
You have two elements with the same id (the <form> and the <div>). Browsers will render this, but it is invalid html, as the id attribute is supposed to be unique to an element. getElementById() is going to grab the first element with the designated id.
The second problem with your html is that neither form or div elements have a value attribute, so there is nothing for your function to clear. It is unclear from your example which element is supposed to be cleared by your button. For the <div>, you could try setting document.getElementById('yourUniqueId').innerHtml = "". That will clear any html inside of the <div>.
You don't need javascript for clear button, you can just use html for clear button only in form tag. Use for clear.
Here is a simple example: example
you have two 'history' id's - not a good practice
use 'innerhtml' instead of value - will yield much better results. value is better for like inputs like a
Make sure you provide a unique ID for your elements,
2 elements above has the same ID, also the function must be defined before calling it.
Always check your Console for logging/errors :)

detect a button click without getElementById

In jupyter, there is a button pointed out by red arrow
Which could be used to summon up a inner command palette
Which is actually an input and a list of <li>
The key function of the button is data-jupyter-action="jupyter-notebook:show-command-palette"
<button class="btn btn-default" title="open the command palette" data-jupyter-action="jupyter-notebook:show-command-palette"><i class="fa-keyboard-o fa"></i></button>
I guess I need a javascript snippet to handle data-jupyter-action attribute.
Usually, script can identify the element by getElementById but this button doesn't have an Id.
How can I detect the button clicking and respond "jupyter-notebook:show-command-palette" action?
You can use querySelector instead of getElementById.
querySelector select elements with css selector.
let elem = document.querySelector('[data-jupyter-action="jupyter-notebook:show-command-palette"]');
This will return the element if it exists. It returns undefined if not found.

Is there a way to define onClick element within <a> tag that will not launch href?

I have a list of box elements that are clickable using <a href> and in this box element I want to add icon that will do something onClick, but will not fire <a href>. To be more precize I am using React for that. I pass down a function in props to child component that is covered with a tag. When I click specific icon I just want to launch the function I passed and not go to href. If You click anywhere else within box it will fire href.
I tried adding <a> element on the icon and override original <a>, but it didn't really work out and it is not allowed by HTML. Right now both a and onClick fires up together.
Here is some code I reduced it to simple example instead of passing the whole thing:
<a href="https://stackoverflow.com/">
<div className="content is-relative">
<p className="stream__title">{this.props.stream.title}</p>
<p className="stream__game">{this.props.stream.game}</p>
<FontAwesomeIcon onClick={() => this.props.follow(this.props.stream.user)}
className="stream__follow" icon="heart" size="lg"/>
</div>
</a>
Any ideas how to fix this problem?
You are facing this problem because icon is wrapped inside box.
In javascript events are bubbled up by default.
i.e. An event of clicking on icon will be bubbled up and will be handled by box href.
If you want to change this behaviour, use stopPropogation().
<div onclick="alert(`I will not handle it anymore`)">
<button onclick="event.stopPropagation()">Let me do it for once!</button>
</div>

problem with event handlers in dojo

I have a span inside which i have a achor tag.For anchor tag , i have used DojoAttachEvent,Now somwhere in my code i replace innerHTML of span as show below.
<span id ="xyz"> <a dojoAttachEvent="onmouseover:_myfunction"> txt223 </a> </span>
Now i replace text of span as follows:
var tmptxt = dojo.byId("xyz").innerHTML
dojo.byId("xyz").innerHTML = "some more txt" +tmptxt
Now after running this code the function _myfunction doesnot get called when onmoveover gets triggered.
I know that i can get away with the problem by using two spans ,one for next txt and one for anchor , but due to some css issues(i get each span on new line,its some two colum css and if i use 2 spans txt and anchor come on 2 different line which we dont want) i cant do it.
I tried to use dojo.connect , but the problem is as my span is present in some wizard the event gets triggered when am on page other then the page which is the current page of wizard.
Try this code.it may helps.
<span id ="xyz"> <a dojoAttachEvent="onmouseover:_myfunction();return true;"> txt223 </a> </span>
First of all, if this isn't inside a widget template, dojoAttachEvent isn't what you want - you probably want something more like onMouseOver="_myfunction();".
Secondly, if you're replacing the innerHTML of the parent node of the node in question with the event, then naturally you're going to end up clobbering that node out of existence, and the event along with it, and you'd have to hook it up again one way or another. Is there a reason you can't be more careful with your DOM manipulation? Like, put an id on the a tag (or query for it from the span) and change only that node's innerHTML?

Categories

Resources