I am wondering how can we hide all shown elements on click outside from those elements in vue:
<button #click="div1=true">Show div 1</button>
<div v-if="div1">DIV 1</div>
<button #click="div2=true">Show div 2</button>
<div v-if="div2">DIV 2</div>
How can I hide all divs besides div 1 if I click on div 1 or hide all divs on click on some random part of the page?
How does vuetify handle it?
Vue way is to use this.$el (DOM element of current component), you can change this.$el and use any other HTMLElement
<div class="modal" #click="handleClick">
<div class="modal-dialog">
<div class="modal-content">
...
</div>
</div>
And method should look like this
handleClick(e: Event): void {
if (e.target instanceof HTMLElement && !this.$el.contains(e.target)) {
this.$emit("hide"); //fires only on click outside
}
}
It's easy to detect click outside of the element if you know how event bubbling works in DOM.
Hiding other divs works perfectly well when you put state of every div into the components's state.
Here is an example: https://codesandbox.io/s/0480m38mww?fontsize=14&module=%2Fsrc%2FApp.vue
Learn more about Event Bubbling here - https://javascript.info/bubbling-and-capturing
I used this process so Home component would know that outside my Nav component has been clicked. It helps that I have my nav inside my Home Component.
My Home component template:
<div>
<nav-bar ref="nav"></nav-bar>
<div #click="useHideNavMethod()">
So I use ref="nav" to use methods from the Nav in my Home component. This means I can use the hideNav() method (which resides in Nav).
I have purposely put the nav outside of this div with the click method, so anywhere clicked other than Nav would initiate the useHideNavMethod() function.
In my Nav component template I have:
<nav id="nav">
which is referenced when I use ref="nav".
So inside my hideNav() I have this.styleNavLi.display = 'none'; so it would hide the nav bar.
So all I need to do to use that method in Home is to use:
useHideNavMethod() {
this.$refs.nav.hideNav();
}
Use div1 = !div1 for toggle view,
Or use div1 = true for one time only.
<template>
<div>
{{ div1 }}
<button #click="div1 = !div1">Show div 1</button>
<div v-if="div1">DIV 1</div>
{{ div2 }}
<button #click="div2 = !div2">Show div 2</button>
<div v-if="div2">DIV 2</div>
</div>
</template>
<script>
export default {
data() {
return {
div1: true, // set default value as you want
div2: false,
};
},
};
</script>
Related
I am trying to achieve situation described in How to open mat-menu from button click of a dynamically created open layers custom control?
So I want to add mat-menu opener for open-layers custom control that needs to be created dynamically. In original question there's good answer which I can't use because I don't have conrol for the map creation code.
So I have an angular PopUpMenuComponent (app-popup-menu) with HTML:
<div id="mat-menu-opener" [matMenuTriggerFor]="menu"></div>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
In app.component.html I have only the 3rd party map component that I have no control and the pop-up menu component :
<app-map-openlayers></app-map-openlayers>
<app-popup-menu></app-popup-menu>
In app.component.ts the custom control that I want to open the mat-menu i try following:
private createMenuButtonElement(): HTMLElement {
const element = document.createElement('div');
element.className = `ol-control button menu-opener`;
const popUpOpener = document.getElementById('mat-menu-opener');
if (popUpOpener !== null) {
element.appendChild(popUpOpener);
}
return element;
}
So I'm moving the div-element to custom control's child. The move works but the menu is not opened when I click the control. When I check in developer tools Element-tab the div-element looks ok, but the mat-menu does not.
<div class="ol-control button popup-menu-button" data-automation-id="mapBtn" title="">
<div _ngcontent-ng-cli-universal-c213="" aria-haspopup="true" id="mat-menu-opener" class="mat-menu-trigger" ng-reflect-menu="[object Object]"></div>
</div>
mat-menu element is found in page but doesn't have the buttons in it:
<app-popup-menu _ngcontent-ng-cli-universal-c360=""></app-popup-menu>
The question is: Can this be done this way?
Capture the MatMenuTrigger as a view child and in the createMenuButtonElement function use it to toggle, open or close the menu.
<div id="mat-menu-opener" #trig="matMenuTrigger" [matMenuTriggerFor]="menu"></div>
<mat-menu #menu="matMenu">
<button mat-menu-item>Item 1</button>
<button mat-menu-item>Item 2</button>
</mat-menu>
<app-map-openlayers></app-map-openlayers>
#ViewChild('trig') menuTrigger: MatMenuTrigger;
private createMenuButtonElement(): HTMLElement {
const element = document.createElement('div');
element.className = `ol-control button menu-opener`;
element.addEventListener('click', () => {
this.menuTrigger.toggleMenu();
});
return element;
}
I am trying to create a toggle on a sidebar so that the toggle button opens the sidebar. This works great on desktop, however, if I am using mobile, the toggle button gets hidden. Is it possible to add a close button in the sidebar which can close the sidebar without breaking the script? The script I have is:
<div id="sidebar">content</div>
<div id="filter-icon">Refine Selection <div id="filterswitch"></div></div>
<script>
jQuery(document).ready(function() {
jQuery("#filter-icon").click(function() {
jQuery("#filterswitch").toggleClass('active');
jQuery("#sidebar").toggleClass('show-sidebar');
});
});
</script>
Shouldn't be a problem, have you tried something like this?
<div id="sidebar"><button id="closeSidebar">Close</button></div>
<div id="filter-icon">Refine Selection <div id="filterswitch"></div></div>
<script>
const toggleSidebarAndSwitch = () => {
jQuery("#filterswitch").toggleClass('active');
jQuery("#sidebar").toggleClass('show-sidebar');
}
jQuery(document).ready(() => {
jQuery("#filter-icon").click(() => {
toggleSidebarAndSwitch()
});
jQuery("#closeSidebar").click(()=>{
toggleSidebarAndSwitch()
})
});
</script>
Yes it's possible just add another div in your sidebar like this:
<div id="sidebar">
content
<div class="filterswitch"></div>
</div>
<div id="filter-icon">
Refine Selection
<div class="filterswitch"></div>
</div>
If you ad the class filterswitch to both div's jQuery will automatically listen for clicks on both elements.
In angular 6,I need to create divs on click a button.The newly div created each time should be having different ids inside container.Here is the code below
app.html
<button (click)="creatediv()">Create div</button>
<div class="container">
<div id="div1">Newly div created</div>
<div id="div2">Newly div created</div>
</div>
app.ts
creatediv() {
}
You can use an array in your component .ts and iterate over this in your template:
template:
<button (click)="createDiv()">Create div</button>
<div class="container">
<div *ngFor="let div of divs" id="div{{div}}">Newly div created</div>
</div>
component:
export class DivsComponent {
divs: number[] = [];
createDiv(): void {
this.divs.push(this.divs.length);
}
}
for reverse order you can change the createDiv method to this:
createDiv(): void {
this.divs.unshift(this.divs.length);
}
I currently have a a parent div and a child div in the middle of the parent div. I want to be able to close the parent div only on clicking outside of the child div. How would I go about doing this? I have my code currently set up as below, with the triggerParentUpdate to set true or false whether to show div.
<div onClick={this.props.triggerParentUpdate} className="signupModalContainer">
<div className="embed-responsive embed-responsive-16by9">
<form action="action_page.php">
<div className="container">
<button onClick={this.props.triggerParentUpdate} type="button" className="closebtn">X</button>
</div>
</form>
</div>
</div>
the onclick function in the first div (className="signupModalContainer") makes it so that when I click that div or any of the child divs, all the divs close. if I take that onclick function out, then the divs close via the closebtn.
Thank you!
Create a handler for the child div's onClick event handler, which stops the propagation/bubbling up of the event to the parent.
Refer to Event.stopPropagation method for more info.
class SomeComponent extends Component {
handleCloseButton = e => {
// This stops the event from bubbling up.
// So it won't trigger the parent div's "onClick" to fire.
e.stopPropagation();
this.props.triggerParentUpdate(e);
}
render () {
// ...
return (
<div onClick={this.props.triggerParentUpdate} className="signupModalContainer">
<div className="embed-responsive embed-responsive-16by9">
<form action="action_page.php">
<div className="container">
<button onClick={this.handleCloseButton} type="button" className="closebtn">X</button>
</div>
</form>
</div>
</div>
);
}
)
I have a li,some other elements like divs, inputs inside this li,and everything inside the gridview.
I have a onmouseover="calcRoute();" on li.
PROBLEM : I have noticed that on hovering on inside element divs and coming out of element divs to the parent div causes the calcRoute(); to execute again ,ie bind google maps again, which causes a flickering due to map rebind.
TRIED : onmouseenter and onmouseleave,but it wont support in all browsers
<li onmouseover="calcRoute(8.4572136,76.94017529999996);return false; ">
<div class="li-inner">
<input type="image" name="ctl00$ContentPlaceHolder1$FESearchListingControl1$dlPhotoView$ctl01$imgPhotoView" id="ctl00_ContentPlaceHolder1_FESearchListingControl1_dlPhotoView_ctl01_imgPhotoView" src="../UploadedImages/House2469-22-8-2012.jpg" style="height:142px;width:219px;border-width:0px;">
<div class="title">
<a id="ctl00_ContentPlaceHolder1_FESearchListingControl1_dlPhotoView_ctl01_lblPropName" href="javascript:__doPostBack('ctl00$ContentPlaceHolder1$FESearchListingControl1$dlPhotoView$ctl01$lblPropName','')">Halloween</a>
<div class="star"></div>
</div>
<div class="address">
<div class="left-location">
<span id="ctl00_ContentPlaceHolder1_FESearchListingControl1_dlPhotoView_ctl01_lblDistrict">Trivandrum</span>
</div>
<div class="right-price"><span class="WebRupee">Rs</span>
<span id="ctl00_ContentPlaceHolder1_FESearchListingControl1_dlPhotoView_ctl01_lblPrice">500.00</span>
</div>
</div>
</div>
</li>
You can attach an id to the li elements and pass this id to the calcRoute function.
onmouseover="calcRoute(8.4572136,76.94017529999996, this.id);
Then, in this function you can set a flag for this li element that it's been hovered before.
var hoveredItems = {}; // this is a global object
function calcRoute(x,y,id) {
// put this control on top so that recurring operations will be prevented from being run.
if(hoveredItems[id]) return;
else hoveredItems[id] = true;
..
}
Maybe this helps...