Description
Description
After updating a project to obtain latest fixes, I noticed that the custom renderer I defined in the project didn't worked anymore.
This is important to have for the future JSON fields or customizations.
In particular the new feature #9553 , backported, applied these changes :
Wrapping all formatters breaks the possibility to use popups as custom renderers.
Solution We should apply the wrapper to each of the default rendererers (string, date ...) but not wrap every renderer, that may include also custom ones, with custom popups that may be broken by this change.
How to reproduce
- As a developer, create and register a renderer to a field, then assign it to a column.
Sample formatter code:
import React from "react";
import { Popover, OverlayTrigger} from "react-bootstrap";
const PopupFormatter = ({ children, placement = 'left' }) => {
return (
<OverlayTrigger
trigger="click"
rootClose
key={placement}
placement={placement}
overlay={
<Popover id={`popover-positioned-${placement}`}>
{children}
</Popover>
}
>
<div
className="popup-formatter-container"
style={{
width: "100%",
height: 25,
overflow: "hidden"
}}
>
Click To Show
</div>
</OverlayTrigger>
);
};
export default PopupFormatter;
const renderObject = (obj, labels = {}) => {
if (Array.isArray(obj)) {
return (<ul>
{obj.map((item, index) => {
return <li key={index}>{renderObject(item)}</li>;
})}
</ul>);
}
if (typeof obj === 'object') {
return (<ul>
{Object.keys(obj).map((key, index) => {
return <li key={index}><strong>{labels[key] || key}</strong>: {renderObject(obj[key])}</li>;
})}
</ul>);
}
return <span>{obj}</span>;
};
const renderObject = (obj, labels = {}) => {
if (Array.isArray(obj)) {
return (<ul>
{obj.map((item, index) => {
return <li key={index}>{renderObject(item)}</li>;
})}
</ul>);
}
if (typeof obj === 'object') {
return (<ul>
{Object.keys(obj).map((key, index) => {
return <li key={index}><strong>{labels[key] || key}</strong>: {renderObject(obj[key])}</li>;
})}
</ul>);
}
return <span>{obj}</span>;
};
const JSONFormatter = ({value, labels = {}}) => {
try {
if (!value) {
return <span>{value}</span>;
}
const json = JSON.parse(value);
if (!json) {
return <span>{value}</span>;
}
return (<PopupContainer>
{renderObject(json, labels)}
</PopupContainer>);
} catch (e) {
return <span>{value}</span>;
}
};
export default JSONFormatter;
registering:
registerFormatter('json', JsonFormatter); // somewhere on init
use (in fields
of a layer):
{
"name": "JSON_ATTRIBUTE",
"alias": "My custom attribute",
"type": "string",
"featureGridFormatter": {
"name": "json",
"directRender": true
}
}
Expected Result
The renderer is used for the column and working
Current Result
The renderer do not work because of the wrapper blocking any action on it.
- Not browser related
Browser info
(use this site: https://www.whatsmybrowser.org/ for non expert users)Browser Affected | Version |
---|---|
Internet Explorer | |
Edge | |
Chrome | |
Firefox | |
Safari |