Notice: The Monaca & Onsen UI Community Forum is shutting down.

For Onsen UI bug reports, feature requests and questions, please use the Onsen UI GitHub issues page. For help with Monaca, please contact Monaca Support Team.

Thank you to all our community for your contributions to the forum. We look forward to hearing from you in the new communication channels.

React based Popover not working in Safari



  • Hey all. I’m trying to use the Popover component with React in Onsen 2, with mixed results.

    I’m using the Popover in conjunction with the react-google-maps component. When a user clicks on a pin on the map, a Popover is supposed to show.

    My code looks like the following:

    
    getTarget()
    {
    	return this.state.selectedCluster;
    }
    
    maybeRenderPopover()
    {
    	if ( this.state.showPopover )
    	{
    		return (
    			<Popover 
    				isOpen={true}
    				onPostHide={this.didHidePopover.bind(this)}
    				getTarget={this.getTarget.bind(this)}
    			>
    				<ServiceList
    					selectable={true}
    					services={this.state.selectedServices}
    					onSelect={this.handleServiceSelection.bind( this )}
    				/>
    			</Popover>
    		);
    	}
    	else
    	{
    		return null;
    	}
    }
    
    
    render()
    {
        return (
    <Page
       renderModal={this.renderModal.bind( this )}
    >
         <Splitter> 
            <SplitterSide
    		side='left'
    		width={200}
    		collapse={true}
    		isOpen={this.state.showMenu}
    		onOpen={this.showMenu.bind(this)}
    		onClose={this.hideMenu.bind(this)}
    	>
    		{this.renderMenu()}
    	</SplitterSide>
    	<SplitterContent>
    		<Page
    			renderToolbar={this.renderToolbar.bind(this)}
    		>
    			<Map
    				style={styles.map}
    				zoom={this.props.map.zoom}
    				center={this.props.map.center}
    				objects={this.props.sync.services}
    				cluster={true}
    				onZoomChanged={this.props.changeZoom}
    				onCenterChanged={this.props.changeCenter}
    				onClusterClick={this.handleClusterClick.bind( this )}
    			/>
    			{this.maybeRenderPopover()}
    		</Page>
    	</SplitterContent>
       </Splitter>
    </Page>
    );
    }
    

    Because the Popover’s target is a pin on the map, which can move if the user pans, I was having trouble with setting it’s isOpen property to this.state.showPopover. If I panned the map, the Popover wouldn’t render in the correct position.

    The way I’m doing it now works perfectly on Chrome based browsers. But on Safari, both on macOS and iOS, the Popover never displays.

    Any chance someone might know what I’m doing wrong?

    Thanks,

    Scott



  • Found a workaround for anyone who is interested.

    If you want to immediately display a popover, it does not seem to work to set the isOpen property to “true”. At least it doesn’t work in every browser.

    However, you can create an additional property that will initially be set to false, and in the postHide handler, set it to true and the Popover will work in every browser that I’ve tried it in.

    In other words:

    if ( this.state.showPopover )
    {
       return (
          <Popover
               isOpen={this.state.reallyShowPopover}
               ...
               onPostHide={ () =>
               {
                    if ( this.state.reallyShowPopover )
                    {
                        this.setState(
                        {
                            showPopover: false,
                            reallyShowPopover: false
                       } );
                   }
                   else
                   {
                       this.setState(
                       {
                           reallyShowPopover: true
                       } );
                   }
               } }
    

    I looked at the source code of the React Onsen components and perhaps there is an ordering issue when the isOpen property is true initially.