I am using ReactJS with React-Bootstrap and am rendering the following content:
<div onClick={this.openModal.bind(this)} className="container">
<div className="content">
<div className="list">
...
</div>
<Button onClick={this.deleteContent.bind(this)}
className="delete-content">X
</Button>
<Modal show={this.state.showModal}
onHide={this.closeModal.bind(this)}
className="edit-content">
...
<Button onClick={this.closeModal.bind(this)}
className="close-modal">X
</Button>
</Modal>
</div>
<div>
In <div className="content">, I am rendering a set of components, and when you click on the <div className="Container">, it will open the Modal so you can edit the container's contents. There is a button to delete the container all together, which is inside the <div className="container">, as many containers will be rendered iteratively.
I am controlling whether the Modal is open with the component's state, where this.openModal() and this.closeModal() simply toggle a boolean that determines if the Modal should be shown (this.state.showModal).
My problem is: when I click the Button with className="delete-content" in the container, it also registers a click to open the Modal, because <div className="container"> has an onClick property. Thus, when I delete containers, the app gets stuck thinking the Modal is open, even though it's not.
My first idea to fix this is to move the onClick property from the <div className="container"> to <div className="list">, but I would like all of the space around the <Button className="delete-content"> to be clickable, and if I move it to list it will restrict the clickable area.
Is it possible to somehow implement when the delete-content Button is clicked to temporarily disable the onClick property of the <div className="container">? Or any other ideas/fixes?
It happens because of event propagation. To fix the problem you need to use stopPropagation on the event object.
handleDelete(event) {
event.stopPropagation()
this.deleteContent()
}
<Button
onClick={this.handleDelete.bind(this)}
className="delete-content">X
</Button>
Related
I am creating a custom dropdown menu.
The menu contains some items and should remain open when a user clicks on any of these items.
To check if the user clicks inside the dropdown menu I check via window.onclick if event.target.matches('dropdown-content *'). See the snippet below for context.
<div id="myDropdown" class="dropdown-content">
<div class="dropdown-grid">
<div class="add-offset">
<div class="dd-header">
<div (click)="setupNewCol()"><i class="fas fa-plus plus-sign"></i></div>
</div>
</div>
</div>
</div>
This works, but when I add *ngIf to the div with the function call the CSS selector 'dropdown-content *' doesn't seem to work anymore.
This is the HTML with the *ngIf
<div id="myDropdown" class="dropdown-content">
<div class="dropdown-grid">
<div class="add-offset">
<div class="dd-header">
<div *ngIf="!settingNewOffset; else offsetSelection" (click)="setupNewCol()"><i class="fas fa-plus plus-sign"></i></div>
<ng-template #offsetSelection>
<div (click)="addCol()">
CLICK ME
</div>
</ng-template>
</div>
</div>
</div>
</div>
With the introduction of the *ngIf in combination with ng-template the CSS selector doesn't recognize the clicks to be part of '.dropdown-content *' anymore. Why is this and what is a solution to this problem?
Why it won't register the click on target 'dropdown-content' is probably because now the clicked target is a div, that does not have 'dropdown-content'. Probably the target parent has that class, but not the target.
To check if a user clicks on any of the items. You already have methods addCol() or setupNewCol(). If this method runs then user has clicked some of the item where the method was attached. You could also just attach another method to the item e.g (click)="addCol(); onItemClick($event)"
onItemClick(event:any) {
console.log(event)
}
I don't see where the menu closing part is but using onItemClick you could just cancel that or try to cancel the event from propagating at all.
(click)="addCol(); event.stopPropagation()"
I have a button and a div in a ngfor loop
and I want each button to be able to show and hide the div each time i click on it
the problem is that I don't already know the number of buttons and div it depends on the data in my database. just want every button to be responsible on the div next to it:
here is the code:
<div *ngFor="let par1 of lstUser1">
<button id="bt2" class="arrow2" (click)="arrowButton('bt2')">
my button
</button>
<div>
my div to show and hide
</div>
</div>
and here is an example of the design i'm trying to make
Yuo can use for show and hide div
*ngIf
<div *ngFor="let par1 of lstUser1">
<button id="bt2" class="arrow2"
(click)="changeMyDivStatus()">
my button
</button>
<div *ngIf="showMyDiv">
my div to show and hide
</div>
</div>
.ts file must have "showMyDiv" variable as boolean variable
changeMyDivStatus(){
showMyDiv = !showMyDiv;
}
I am trying to fix an accessibility defect in an Angular project at work. When a page loads and I start to tab through the page, the first element that is visible in the form is read twice. My code is something like below
<form [formGroup]="form" role="form" attr.aria-label="Edit Form" novalidate>
<div class="form-row">
<div class="col-md-9 col-sm-12 col-lg-9 paddingLR0">
<!-- Hidden code not rendered due to ngIf=false -->
<div role="region" attr.aria-label="Edit button region" *ngIf="viewMode">
<!-- Hidden elements not rendered due to ngIf=false -->
<button *ngIf="isEditable" [disabled]="!canEdit" type="submit" (click)="enableEdit()">
Edit
</button>
<div class="back-header">
<a tabindex=0 (keyup.enter)="back()" (click)="back()" (mouseover)="changeBackIconOnHover('back-region-top')" (mouseout)="changeBackIcon('back-region-top')" id="back-region-top">
<img src="{{pathImg}}/back_black.png"
<span class="margin-left10">Back</span>
</a>
</div>
</div>
</div>
</div>
<!-- More code here -->
</form>
If you see the code the first element that is visible is the Edit button, nested in a div with role as region, which is in turn inside a form with role form. When I tab through the page instead of just reading the button just once Edit button JAWS reads Edit Form form region. Edit Button on first tab, then reads Edit button region. Edit Button. There are no tabindexes on the parent elements. Removing the role attribute and the corresponding labels does not work. How do I only make jaws read the edit button once?
The above problem was occuring because of an empty div which had a tabindex=0.
So in the code snippet above I had a commented line
<!-- Hidden code not rendered due to ngIf=false -->
That referred to multiple divs which are warning, success and error messages related to the form in my actual code. Each of those divs have an ngIf for conditional rendering and a tabindex=0 to make it tab accessible. Except one of those divs simply had a tabindex but no ngIf. So it was always rendered. Like below.
<div tabindex=0>
<div ngIf="condition"> {{errormessage}}
</div>
</div>
If JAWS tabs onto an empty element it reads the previous labels. I removed the outer div which was remaining empty and the problem is solved.
So I have this component that is a button, which when clicked, navigates to a certain route. However, I want to put a button inside this, which doesn't make it navigate and does something else.
How do I do this? It is the follow/unfollow button.
<button type="button" class="btn" (click)='navigate()' *ngIf="searchResult.username"><mat-card>
<mat-card-header>
<mat-card-title>{{searchResult|null:['firstname']}} {{searchResult|null:['lastname']}}</mat-card-title>
</mat-card-header>
<mat-card-content class="container">
<div>{{searchResult|null: ['username']}}</div>
<div>
<!-- option to follow -->
<div *ngIf="!result.followers.includes(this.selfUsername)" class="follow">
<button mat-raised-button (click)="onFollow()">
Follow
</button>
</div>
<!-- already following -->
<div *ngIf="result.followers.includes(this.selfUsername)" class="follow">
<button mat-raised-button (click)="onUnfollow()">
Unfollow
</button>
</div>
</div>
<div>
<!-- dunno why these dont work -->
<!-- <p *ngFor="let item of searchResult|null:['history']">{{item}}</p> -->
</div>
<div>
<!-- <p *ngFor="let item of searchResult|null:['whishlist']">{{item}}</p> -->
</div>
</mat-card-content>
</mat-card>
</button>
Use button tags only when making interaction like calling functions that do something.
In your case you want to "hyperlink" somewhere (in this case it's a mat-card) and inside of if you want to place any buttons...let's say.
For navigation you should always use anchor tags like <a ... href="" or routerLink="">...content </ a>
So, just change the root <button ...> to <a ...>.....
and that should be it.
Like gsa.interactive said, you have to use a link for redirection.
With this logic you cannot have a clickable child button if it is located in a clickable parent element. You can't position these child buttons above the parent with z-index.
A child's z-index is set to the same stacking index as its parent.
2 possibilities:
you don't overlay the clickable link with the buttons.
Either you overlay them in the following way:add position: relative to the parent with a z-index 0 and add position : absolute to the buttons with z-index 1 with a specific position
How do I change or add any code in order to tap and hold to show the pop up, currently once I press the button the pop up window will appear, I want to change it to tap and hold.
<div id="ScenePop1">
1
<div class="popup1">
<h2>Scene 1</h2>
<button id="store1">Store</button>
<button id="del1">Delete</button>
<a class="close1" href="#close"></a>
</div>
</div>
my code here: http://jsfiddle.net/oajt5p28/
This link come to elegant solution with the combination of jquery, jmobile and simpledialog2: http://www.raymondcamden.com/2012/05/23/Context-Menu-Example-with-jQuery-Mobile.
Or use could use html5 dialog element, and catch taphold event following this way:
How to detect a long touch pressure with javascript for android and iphone?