Angular Material Limit toggling of MatExapansionPanel to only clicking arrow - angularjs

I'm using Angular Material to create my toggling panels. I still want my panel to expand and contract when clicking the arrow, but I not when I click anywhere in the panel header because I want to add a checkbox at the top. Currently, when I click on my checkbox, the toggling event of the panel fires when I click the checkbox. The 'change' event of the checkbox still fires afterward.
I don't mind to have the panel toggles only when clicking its arrow, how do I stop the toggling of the panel from firing when clicking anywhere in the top?
HTML
<mat-expansion-panel #panel
(opened)="togglePanel()"
(closed)="togglePanel()">
<mat-expansion-panel-header>
<mat-panel-title>
<mat-checkbox (change)="onCheckChanged($event)">
<label>Options 1</label>
</mat-checkbox>
</mat-panel-title>
<mat-panel-description></mat-panel-description>
</mat-expansion-panel-header>
</mat-expansion-panel>
TypeScript
togglePanel() {
// this event fires before the onCheckChanged event
}
onCheckChanged(event: MatCheckboxChange) {
// this event fires after the togglePanel event
}

There is currently a feature request in for this, about a year old so not sure of the ETA... seems to be some workarounds people are playing with that might help but appear to have mixed reviews.
https://github.com/angular/material2/issues/8190
Revision
I tested the following in stackblitz and it seems to work.
HTML
<mat-accordion>
<mat-expansion-panel #expansionPanel>
<mat-expansion-panel-header (click)="expandPanel(expansionPanel, $event)">
Component
expandPanel(matExpansionPanel, event): void {
event.stopPropagation(); // Preventing event bubbling
if (!this._isExpansionIndicator(event.target)) {
matExpansionPanel.close(); // Here's the magic
}
}
private _isExpansionIndicator(target: EventTarget): boolean {
const expansionIndicatorClass = 'mat-expansion-indicator';
return (target['classList'] && target['classList'].contains(expansionIndicatorClass) );
}
Stackblitz
https://stackblitz.com/edit/angular-5kugm3?embed=1&file=app/expansion-overview-example.html

Related

Slide page up to make room for iOS keyboard

In React (not React Native), how can I slide the page-content up to make room for the iOS keyboard when a textarea element gains focus?
Below please find my attempt. This now works fine. However, I am curious if this is considered good practice, or if there is an existing solution?
// When the textarea element gains focus,
// scroll the content up (to make room for the iOS keyboard)
scrollContent = () => {
console.log("Gained focus");
this.scrollViewRef.current.style.marginTop = '-250px';
}
// When the textarea element loses focus,
// scroll the content back down (since the iOS keyboard is gone now)
unScrollContent = () => {
console.log("Lost focus");
this.scrollViewRef.current.style.marginTop = '0px';
// The textarea's onBlur is causing the button's onClick not to fire
// so need to manually call the button's onClick
if(e.relatedTarget === this.buttonRef.current) {
this.buttonRef.current.click();
}
}
render() {
return (
<div
ref={this.scrollViewRef}
>
<textarea
onFocus={this.scrollContent}
onBlur={this.unScrollContent}
/>
<div
ref={this.buttonRef}
onClick={this.handleSubmitForm}
tabIndex="1"
>
Save
</div>
</div>
)
}
In particular, if the user tries to click on the form's submit button while the textarea element has the focus, it will only trigger the textarea's onBlur (and scroll the page-content up again), but it won't call the submit button's onClick. Hence the need to check what element was clicked on in the if statement, and if it was the button, manually trigger the click.
Is there a better way?

Why is "ripple effect" from Material-UI not visible when used in Popup (inside Leaflet map)?

I'm trying to put Material-UI Button inside Popup (Leaflet library).
When I'm doing it outside Popup => everything works fine, each button click triggers ripple effect.
When I'm trying to put the same code inside marker popup, something destroyes (overrides) ripple style and its's no longer visible.
Is it possible to somehow fix this problem?
Here's my codesandbox: https://codesandbox.io/s/react-leaflet-ripple-ivsxy
I have two buttons here:
(1) Outside the popup - works OK
(2) In the popup (popup is visible after click on marker) - button is visible but ripple effect is broken
Regarding why, in Material-UI ripple handler is triggered on mousedown event (from ButtonBase.js):
const handleMouseDown = useRippleHandler('start', onMouseDown);
but in leaflet mousedown event inside popup doesn't propagate outside the map in leaflet and this is by design (refer this thread for some details), that's the reason why ripple effect is missing.
To circumvent this behavior, one option would be to restore mousedown event propagation as demonstrated in the following Popup custom component:
class MyPopup extends Component {
componentDidMount() {
const { map } = this.props.leaflet;
map.on("popupopen", e => {
L.DomEvent.off(
this.getWrapper(),
"mousedown",
L.DomEvent.stopPropagation
);
});
map.on("popupclose", e => {
L.DomEvent.on(this.getWrapper(), "mousedown", L.DomEvent.stopPropagation);
});
}
getWrapper() {
return document.querySelector(".leaflet-popup-content-wrapper");
}
render() {
return <Popup {...this.props} />;
}
}
Here is an updated CodeSandbox

I need to show a PopOver in Ionic 3 via code for an specific element on the page

I have a PopOver page and I pass a string message to it, what I want is use this popover as a Tooltip for some elements on the page.
Example, on my page I have this:
<button ion-button icon-only clear (click)="shareThisCardByEmail(item)" (blur)="showTooltipShareByEmail($event)" >
Share
</button>
In this case I am associating the event "blur" (I am not sure what would be the best for this case) and I need when the view is loaded that event is shot and the popover is shown to the user.
On the component I have this:
showTooltipShareByEmail(event ? : any) {
let popover = this.popoverCtrl.create(PopoverTooltipPage, {
"message": 'This is a message on the tooltip popover about sharing by email'
});
let navOptions: any = {
animate: true,
ev: event
};
popover.present(navOptions);
}
How would I activate one specific event for an specific element on the page then the tooltip would be displayed?
I saw 2 questions but I'm trying to answer this:
I need when the view is loaded that event is shot and the popover is shown to the user
Check this out for the lifecycle events https://ionicframework.com/docs/api/navigation/NavController/.
You can call the popover when the view did load at here
ionViewDidLoad() {
console.log("I'm alive!");
// Right here
}

Extjs mouseover and click event not working together for an element id

I have a button and in my controller i created one mouse over event and a click event for that button's id. But everytime when i click button it goes to the mouseover event function only, but when I comment the mouseover it goes to the click event function nicely. Why this is so? I am using ext4.1
thanks in advance.
me.control({
'#notificationIconId':{
click:me.notificationClick
},
'#notificationIconId':{
mouseover:me.notificationMouseOver
}
});
},
notificationMouseOver : function (){
alert('1')
},
notificationClick :function(menuitem)
{
alert('2')
}
You're using two times the same key '#notificationIconId' in a Javascript object... So, the last one is overriding previous ones.
You can add multiple listeners for the same selector:
'#notificationIconId': {
click: me.notificationClick
,mouseover: me.notificationMouseOver
}

Backbone.js View events disable enable

If I have a View in backbone.js and it has an event in the events list:
events: {
'click #somebutton': 'clicked'
},
clicked: function () {
console.log('clicked');
}
How can I then disable/enable that event? So for instance if its clicked then
the event is removed (the button remains on screen but is greyed out etc). When some other part of the view is updated or whatever the event
enabled. Sure I can use jquery but I want to know if this functionality is available in backbone.
Thanks for any answers
Paul
You can always use delegateEvents() and undelegateEvents() to redo your event binding between the DOM and your Backbone View. That said, I usually just keep the event handler and add a conditional in the handler.
// .disabled class (CSS) grays out the button
clicked: function(event) {
var buttonEl = $(event.currentTarget);
if (buttonEl.hasClass('disabled')) {
// Do nothing
} else {
// Do something AND...
buttonEl.addClass('disabled');
}
}
Then you can have your other view or code simply removeClass('disabled') when you want to restore functionality.
UPDATE - disabled property
See comments, but a simpler, much better solution is to use the disabled property disabled="disabled" of buttons.
Use delegateEvents and undelegateEvents for binding and unbinding events. Check for reference: delegateEvents

Resources