In React, a <button> with icon does not trigger function - reactjs

I use reactstrap. I have this kind of <button> with an icon inside :
{this.props.mode === "update"
?
<Button
className="btn btn-danger btn-sm"
onClick={() => this.deleteQuestion()}
>
<i className="fa fa-trash"></i>
</Button>
: null
}
If I click on the icon, the function in not triggered.
If I click outside the icon (but inside the button), the function is triggered.
What is this mystery? I am a beginner in React and react-strap.

The reason it behaves this way is because icon captures click before it is propagated to the button. The easiest way to fix this is to add the following in your css
.btn i.fa{
pointer-events: 'none';
}
it will fix it for all the buttons in your project

There is a concept called event capturing and event bubbling in JavaScript. Take a look at Event Capturing and Event Bubbling. This concept helps you overcome the problem that you're facing currently.Take a look at this. You can add the same function onClick to the icon too. This will help you as well!!.. There are so many design templates available you can try those too. For eg. There's Ant Design. Hope it helps!!.. Happy Coding!!

Related

Why is my modal only taking the first prop passed to it? (Using React and Bootstrap)

Hello :) I'm using Bootstrap to make an offcanvas component that can render a modal for each item in an array passed to it. However, when clicking open my modals, they each display omly the first items props. Why? And, how can I fix it? I recreated it here in codesandbox codesandbox recreation
If i can improve my question let me know in a kind way, please.
The way you have done is not the correct way of building Modal in React .
However just to give you clarity about the mistake you have done:
The prop letter is passed correctly. The problem is the way you're calling the modal.
If you see your code in Example.js , you have used data-bs-target="#exampleModal". And id="exampleModal" for the modal to show up.
So all the handlers are pointing to exampleModal id . Hence After you click on the buttons only the first modal shows up.
To solve this , you need to assign the data-bs-target and id dynamically. Something like below :
<button
type="button"
class="btn btn-primary"
data-bs-toggle="modal"
data-bs-target={`#exampleModal${props.letter}`}
>
click to view prop
</button>
and then in Modal set id as :
<div
class="modal fade"
id={`exampleModal${props.letter}`}
tabindex="-1"
aria-labelledby="exampleModalLabel"
aria-hidden="true"
>
It should work as expected.
here is the working example : Demo

How do I propagate onClick from parent link to nested spans?

I have buttons that I'd like each line within which to have different styling, and I want to be able to add a class so the user knows which button they selected. I'd like the class to be added regardless of where I click on the button, but it's only being added when I click on the background. No style is added if I happen to click the text of the button, which is in spans. Does anyone know what I might be doing wrong?
Here is my code.
<a href="#" role="button" onClick={e => {
e.preventDefault();
let el = e.target;
setAgeSelection('0-3');
el.classList.toggle('selected');
}} className="btn-resume btn-resume-large btn-resume-blue">
<span className="txt-36px bold-txt">0-3 years</span><br />
<span className="txt-22px italic-txt">Career explorer</span>
</a>
And here it is in codepen:
https://codepen.io/ybilal253/pen/GRNdLzw
Please let me know if any further information is needed.
Thank you in advance!

call AngularJS service method based on the response from bootstrap popover

I have a bootstrap popover which has 2 buttons Yes or No. Based on the response from the user i need to call AngularJS service function. How do i do that??
Popover is created only if it meets a certain criteria (like existence of duplicate records)
HTML code looks something like below, but currently doesn't have 2 buttons & still need to work on it
$(document).ready(function () {
if (DuplicateRecord) {
$('[data-toggle="popover"]').popover();
}
});
<button href="#" data-toggle="popover" title="Popover Header"
data-content="Some content inside the popover" data-trigger="click"
data-html="false" data-placement="left">
Toggle popover
</button>
Looks like you are mixin concepts (or maybe I'm not getting your question), you can have a popover but the data-trigger="click" makes showing the popover on the click event and you wanna use that event to call the service method. Change the popover trigger to hover and then use the click event to call your service. Something like this just as an idea, the snippet is not tested.
<button
type="button"
data-toggle="popover"
title="Popover Header"
data-content="Some content inside the popover"
data-trigger="hover"
data-html="false"
data-placement="left"
ng-click="$ctrl.callSomeMethod()"
>
Toggle popover
</button>
You can take a look to UI Bootstrap lib which has a directives for the Bootstrap's components equivalents.

angular ui tooltip triggers ng-disabled of other buttons when hover on button

I using ui bootstrap tooltip plugin with something like this:
<button type="button" uib-tooltip="new item">
new item
</button>
<button ng-disabled="vm.testDisabled()">
search
</button>
angular.module('rgh').controller('CourseController', CourseController);
function CourseController () {
function testDisabled() {
console.log('testDisabled called')
return false;
}
}
but the problem is that when i hover on new item button, i see the testDisabled called logs in chrome console, i think its inappropriate behavior from uib-tooltip.
how can i resolve this problem?
It's not inappropriate, it's how angular works! when you pass over your button and the tooltip shows the digest loop runs, because you've provided your ngDisabled with a function, that function will run on each digest cycle (even when it is not needed) because it's returned result will be used to tell angular if it should disable the input or not!!
To avoid this, pass ngDisabled with a variable that will be changed in your controller on certain conditions
<button ng-disabled="vm.isTestDisabled">
search
</button>

Angular - diff in IE and Chrome

I have two button that are overlapping, and use ng-hide for the m with the same flag.
On Chrome it work perfectlly, but when I use IE 11, the icons are overlapping on page load.
I have two icons on in my search box:
And On IE11, when the page is loading:
The code is:
<button type="submit" class="btnSubmit" ng-show="vm.isSearchIconVisible" >
<i class="iconMglass"></i>
</button>
<button type="reset" ng-show="!vm.isSearchIconVisible" class="clearTextButton" ng-click="vm.clearSearchText()">
<span class="clearIcon">X</span>
</button>
How can I fix it ?
Try using ng-ifinstead of ng-show.
The ng-if directive removes the content from the page and ng-show/ng-hide uses the CSS display property to hide content.
Not using CSS by changing to ng-if prevents these CSS problems. Although the ng-ifcreates a new scope but that impact is nothing.
<button type="submit" class="btnSubmit" ng-if="vm.isSearchIconVisible" >
<i class="iconMglass"></i>
</button>
<button type="reset" ng-if="!vm.isSearchIconVisible" class="clearTextButton" ng-click="vm.clearSearchText()">
<span class="clearIcon">X</span>
</button>
If you don't want to change to ng-if, then please share a working Plunkr/... so help you find your problem. Since it will be a cssissue most likely.
The Problem was that IE11 save cash with old code, CTR+R dident solve this problem.
In the IE11 option I revoce the option to save cash and it solve the problem, the new code appear.

Resources