I'm looking for a way to stopPropagation() the click event of an antd Dropdown component with a sole 'click' trigger.
Here's an example of a Dropdown where the open/close click event is propagated to the parent Collapse header, which causes the Panel to collapse/expand, which is undesired:
https://codesandbox.io/s/stop-propagation-dropdown-trigger-click-cg005
Screenshot
Note that click events of the button and the menu items can be stopped from propagating in the respective event handlers.
What I'm looking for is how to do the same for the dropdown click events (click on the "⋯" part), which doesn't seem to be easily accessible.
Providing the onClick={e => e.stopPropagation()} callback to the immediate child of <Dropdown trigger={["click"]}> should solve the issue. Tt worked for me:
return (
<Dropdown trigger={["click"]} overlay={actionsMenu}>
<div onClick={e => e.stopPropagation()} className="action-button-container">
<MoreOutlined />
</div>
</Dropdown>
)
#shimikano, as for your particular case, you can override the buttons by using the buttonsRender prop from the <Dropdown.Button> component. buttonsRender is a function that receives an array with 2 ReactNode elements inside, first one is the actual button (named Dropdown in your case), and the second one is more icon which you can override with the same icon to which you have access and can provide the onClick callback and call event.stopPropagation() inside
buttonsRender={buttons => {
buttons[1] = <MoreOutlined onClick={e => e.stopPropagation()} />;
return buttons;
}}
Here is how the collapse header would look like:
const header = (
<Space wrap>
<Dropdown.Button
size="small"
trigger={["click"]}
onClick={handleButtonClick}
overlay={menu}
buttonsRender={buttons => {
buttons[1] = <MoreOutlined onClick={e => e.stopPropagation()} />;
return buttons;
}}
>
Dropdown
</Dropdown.Button>
</Space>
);
Related
What do I want to do when the mouse entered the window with -webkit-app-region: drag attribute, then I find if I try to add the -webkit-app-region: drag attribute,the element invalidates all mouse event,include mouseenter and mouseleave.
I understand that the click event related to dragging, but why are events other same also failed
.app {
-webkit-app-region: drag;
}
function app() {
return (
<div
className={style['app']}
onMouseEnter={() => console.log('enter')}
onMouseLeave={() => console.log('leave')}
/>
)
}
I am using a React Material UI Tooltip component. Specifically :
render() {
const {comment} = this.props;
...
<Tooltip title={this.handleFlaggedComment(comment)}>
<IconButton className={classes.tooltipIconButton} aria-label="Reported" href="">
<ReportedIcon className={classes.reportedIcon} />
</IconButton>
</Tooltip>
...
}
The handleFlaggedComment is implemented as :
handleFlaggedComment = (comment) => {
return (
<Fragment>
<div>
REPORTED COUNT : {comment.reportedCount}
</div>
</Fragment>
)
}
Lets also assume there is a mapStateToProps which is implemented as :
mapStateToProps(state) {
return {
comment: state.commentsList.currentComment
}
}
When the reportedCount goes from 1 to say 3, and I hover over the icon to show the tooltip, I would expect it to show 3 as the reportedCount. However it only shows 1 , which was the initial value
Is there a way to make the tooltip title update and show the updated comment, specifically the correct reportedCount ?
let us also assume that some UI action is triggering the reportedCount to increase. An example, is clicking on an icon that increments the reportedCount by 1 and it is updating state in redux for 'currentComment'
I'm building a Vaadin 8 app ( first one for me ). I am using the designer to generate the UI. I've added several buttons to the dashboard which should fire a function when clicked. For some reason nothing fires when the image is clicked. Below is all the code that is involved. Can anyone see what I'm doing wrong?
This is the code from the .html file:
<vaadin-horizontal-layout responsive width-full margin>
**<vaadin-image icon="theme://images/properties.png" style-name="my-image-button" responsive alt="" _id="imagePropertyInfo"></vaadin-image>**
<vaadin-image icon="theme://images/occupants.png" responsive alt="" _id="imageOccupants"></vaadin-image>
<vaadin-image icon="theme://images/vendors.png" responsive alt="" _id="imageVendors"></vaadin-image>
</vaadin-horizontal-layout>
Here is the scss
.my-image-button
{
cursor: pointer;
}
Here is the code from the Dashboard UI
public DashboardHomeView( OnCallUI onCallUI )
{
this.onCallUI = onCallUI;
// Make it disabled until a property is selected
**imagePropertyInfo.setEnabled( false );
imagePropertyInfo.setStyleName( "my-image-button" );**
fetchPropertyBasicInfo();
}
protected void fetchPropertyBasicInfo()
{
List<PropertyProfileBasic> listOfPropertyProfiles = new ArrayList<PropertyProfileBasic>( OnCallUI.myStarService.fetchAllPropertyProfileBasicInformation() );
comboBoxGeneric.setCaption( "Select a Property" );
comboBoxGeneric.setItemCaptionGenerator( aProperty -> aProperty.toString() );
comboBoxGeneric.setItems( listOfPropertyProfiles );
comboBoxGeneric.addValueChangeListener( event -> fetchOccupantBasicInfo( event ) );
comboBoxGeneric.focus();
}
protected void fetchOccupantBasicInfo( ValueChangeEvent<PropertyProfileBasic> event )
{
// Fetch all the occupants for the selected property
if( event.getValue().getPropertyNo() != null )
{
// Fetch a list of occupant basic info for the selected property
List<OccupantProfileBasic> listOfOccupantProfiles = new ArrayList<OccupantProfileBasic>( OnCallUI.myStarService.fetchOccupantProfileBasicByPropertyNo( event.getValue().getPropertyNo() ) );
// Clear the existing grid et al
gridContainer.removeAllComponents();
// Add the occupant grid
occupantGrid = new OccupantProfileBasicGrid( listOfOccupantProfiles );
// Show the grid
gridContainer.addComponents( new Label( "Occupants" ), occupantGrid );
// Set the dashboard buttons to enabled now a property is selected
**imagePropertyInfo.setEnabled( true );
// Add the property info button
imagePropertyInfo.addClickListener( e -> fetchPropertyInformation() );**
}
}
protected void fetchPropertyInformation()
{
Notification.show( "Yo!", "You clicked!", Notification.Type.HUMANIZED_MESSAGE );
}
I assume you are using GridLayout. I am recommending another approach. Use Button, and set the button style to be borderless (apparently you want something like that. The icon of the button can be image from your theme, using ThemeResource. "Pseudo code" is something like this:
ThemeResource icon = new ThemeResource("/images/properties.png");
Button imagePropertyInfo = new Button(icon);
imagePropertyInfo.setStyleName(ValoTheme.BUTTON_BORDERLESS);
imagePropertyInfo.addClickListener( e -> fetchPropertyInformation() );
Note also, JavaDoc of Image component says.
"public Registration addClickListener(MouseEvents.ClickListener listener)
Add a click listener to the component. The listener is called whenever the user clicks inside the component. Depending on the content the event may be blocked and in that case no event is fired."
I think it does not like your way of setting image with theme, without using Resource.
If you want to remove the focus highlight of the button, it should be possible via this CSS rule:
.v-button-link:after {
content: none;
}
Also it is worth of mentioning that Image is not Focusable, while Button is. This means that even that Image can have click listener, it is not reached by keyboard navigation, Button is Focusable and is reached by tabbing etc. So using Button instead of Image makes your application more accessible.
I'm a bit new to react-native, so I might not have understood this while reading the docs but. I have a tab bar in an ios app with 2 tabs.
Currently the view code for one of the tabs is in the same file as the page that loads the the Tab bar (I call this HomeTab). The second tab (call Tab2) which contains the view code for the second tab is in a separate .js page and is loaded into HomeTab.
I'm having trouble passing information in HomeTab's state to Tab2, and do not want to write all of Tab2 into HomeTab like I did for Tab1 because I will get a really big file.
The code structure is a bit like this:
{View Code for Tab 1 here}
<TabBarIOS selectedTab={this.state.selectedTab}>
<TabBarIOS.Item
selected={this.state.selectedTab === 'Tab1'}
title = "Tab1"
icon = {require('image!Tab1')}
onPress={() => {
this.setState({
selectedTab: 'Tab1'
}
);
}}>
// Call Tab1 View here
</TabBarIOS.Item>
<TabBarIOS.Item
selected={this.state.selectedTab === 'Tab2'}
title = "Tab2"
icon = {require('image!Tab2')}
onPress={() => {
this.setState({
selectedTab: 'Tab2'
}
);
}}>
<Tab2/>
</TabBarIOS.Item>
Intuitively I feel like all I am doing is putting code in a separate file, so both tabs should have the same state, but when I print out anything from my state it is undefined. Any advice would be appreciated! Thanks.
I was fairly ignorant of the capabilities of javascript. I was able to pass props just by including it in the call to Tab2 like this
<Tab2 propName = {some information}/>
If I disable jQueryUI button using "disabled" option, button goes dim.
But I don't want it that way - I just want it unresponsive and styled in its original layout - no rollovers, no clicks - everything dead.
Unbinding button click from button doesn't help.
Unbinding all events from button using unbind() just as well.
Any ideas?
In fact, you could just remove the "disabled" classes after disabling the button:
$( "button" ).button();
$( "button" ).button('disable');
$( "button" ).removeClass('ui-button-disabled ui-state-disabled')
Here is a fiddle : http://jsfiddle.net/9gq9n/
Ok, at last I figured it out.
To disable any jQueryUI button, including 'buttonized' checkbox with label attached (while retaining its original layout), you have to do the following:
unbind its events
unbind events from its label(s)
So, here's an example:
$("mybuttons").unbind();
$("mybuttons").getLabels().unbind();
I'm using a plugin I recently wrote (originally by SO member Gijs, but didn't work always...)
jQuery.fn.getLabels = function () {
return this.map(function () {
var parentLabels = $(this).parents('label').get();
var associatedLabels = this.id ? associatedLabels = $("label[for='" + this.id + "']").get() : [];
return parentLabels.concat(associatedLabels);
});
};
Hope it helps.