Using EUI inside FieldFormatter plugin

I have a FieldFormatter where I want to use EUI to create a html representation of some data. I want a modal dialog to open when I press on one field. This is a type of extended version for the "Truncated String" FieldFormatter.

Here is an extract of the code:

public.js:

TruncatedField.prototype._convert = {
  text: function (value) {
    return value;
  },
  html: function (value, _, document) {
    var htmlString = '<div>' + 
      '<button class="euiButton" type="button">' +
        'Truncated text example ...' + 
      '</button></div>';

    return htmlString;
  }
};

This gives me a button that I can click, but I cannot figure how to open up an overlapping modal dialog from pressing the button. I tried look through the tutorials and examples at the EUI github page but I cannot find a complete example.

How do I make this work, and how do I insert the full text of my truncated string into this modal dialog?

Many thanks!

Hi @Elaak,

Field formatters don't expose a render function of some kind that would be necessary to implement something like this in a clean way. You just return the HTML, it's not possible to attach event handlers to your HTML elements that would allow you to react to a click to do something like opening a popup. However you can work around by this by a global event handler and a data-attribute on your button. Then you can intercept all clicks to all buttons and trigger your action if the clicked element includes the data attribute. I answered a similar question here: Run script inside hmtl of field formatter

In your case the script wouldn't trigger an HTTP call, but render a react element using ReactDOM.render.

Let me know whether that helps!

Hi @flash1293,

Thanks, the ReactDOM.render() was what I was looking for! The only issue I am left having is that the appears to overwrite the height of my Kibana dashboard, because the vertical scrollbar is removed. I tried to adjust the height of the overlay with style={height: 10000px}(just to be extreme), but it made no difference.

I’m not sure I’m understanding 100% correctly - could you post your code and a screenshot of the problem?

What I mean is that in my Dashboard, I press my generated and a <EuiModal> dialog is showed surrounded by a <EuiOverlayMask>. In the Dashboard I have many visualizations, so there is a scrollbar to navigate and show the lower visualizations. But, when this dialog opens, the scrollbar disappears.

I cannot show a screenshot, but the code is the following:

import React, { Component } from 'react';
import {
  EuiModal,
  EuiModalBody,
  EuiOverlayMask
} from '@elastic/eui';

export default class SublabelsFieldEditDialog extends Component {
  constructor(props) {
	super(props);

	this.state = {
	  isModalVisible: true
	};

	this.onClose = this.closeModal.bind(this);
	this.showModal = this.showModal.bind(this);
  }

  closeModal() {
	this.setState({ isModalVisible: false });
  }

  showModal() {
	this.setState({ isModalVisible: true });
  }

  // FIXME EuiOverlayMask "removes" the scrollbar, which affects position and sizes of ui components.
  render() {
	let basicModal = null;
	if (this.state.isModalVisible) {
		basicModal = (
		<EuiOverlayMask>
		  <EuiModal onClose={this.onClose} style={{ padding: '25px'}}>
			<EuiModalBody>
				<button className="dialogBtns"
						data-id="editFieldData"
						data-field="clazz"
						data-document={this.props.id}
						data-index="myIndex"
						data-label="MyLabel"
						onClick={this.closeModal}>
					MyLabel
				</button>
			</EuiModalBody>
		  </EuiModal>
		</EuiOverlayMask>
		);
	}

	return basicModal;
  }
}

I hope this makes things more clear.

It should be fine to just omit the EuiOverlayMask. Then the modal should be shown without blocking the rest of the page (which includes scrolling).