I posted this question on the office-ui-fabric-react
board a few days ago and DZearing got back to me within a few hours of my asking the question.
his response can be found at https://github.com/OfficeDev/office-ui-fabric-react/issues/1847. He recommended adding the following onRenderRow
:
onRenderRow={ (props, defaultRender) => <div onMouseEnter={ () => console.log('hovering over: ' + props.item.title)}>{defaultRender(props)}</div> }
I did not know that the onRenderRow
method got passed the default renderer.
So I created my details list like this:
<DetailsList
layoutMode={DetailsListLayoutMode.fixedColumns}
items={this.state.documents}
onRenderRow={(props, defaultRender) => this.renderDocumentRow(props, defaultRender)}
setKey="id"
selectionMode={SelectionMode.none}
columns={[
{ key: "Edit", onRender: this.rendeDocumentAsLink, name: "", fieldName: "Title", minWidth: 20, },
{ key: "title", name: "Request #", fieldName: "title", minWidth: 80, },
]}
/>
In the renderDocumentRow
method, I wrapped the entire row withini a div
that has mouseenter
and mouserout
events:
public renderDocumentRow(props,defaultRender): JSX.Element {
return (
<div
onMouseEnter={(event) => this.documentRowMouseEnter(props.item, event)}
onMouseOut={(evemt) => this.documentRowMouseOut(props.item, event)}
>
{defaultRender(props)}
</div>);
}
The mousein
and moouseout
methods get the wopiframeurl
for the document hovered over, and set some state variables so that I can render an iframe with the wpoisource:
public documentRowMouseEnter(trdocument: TRDocument, e: any) {
//mode passed to fetchDocumentWopiFrameURL: 0: view, 1: edit, 2: mobileView, 3: interactivePreview
this.props.fetchDocumentWopiFrameURL(trdocument.id, 3).then(url => {
if (!url || url === "") {
url = trdocument.serverRalativeUrl;
}
this.state.documentCalloutIframeUrl=url;
this.state.documentCalloutTarget = e.target;
this.state.documentCalloutVisible = true;
this.setState(this.state);
});
}
public documentRowMouseOut(item: TRDocument, e: any) {
this.state.documentCalloutTarget = null;
this.state.documentCalloutVisible = false;
this.setState(this.state);
console.log("mouse exit for " + item.title);
}
The render method has the list of documents in a left aligned div, and an iframe in a right aligned div . As a user hovers over a row on the left, a preview of the document is displayed on the right:
<tabs.TabPanel>
<div style={{ float: "left" }}>
<DetailsList
layoutMode={DetailsListLayoutMode.fixedColumns}
items={this.state.documents}
onRenderRow={(props, defaultRender) => this.renderDocumentRow(props, defaultRender)}
setKey="id"
selectionMode={SelectionMode.none}
columns={[
{ key: "Edit", onRender: this.rendeDocumentAsLink, name: "", fieldName: "Title", minWidth: 20, },
{ key: "title", name: "Request #", fieldName: "title", minWidth: 80, },
]}
/>
<input type='file' id='uploadfile' onChange={e => { debugger; this.uploadFile(e) }} />
</div>
<div style={{ float: "right" }}>
<DocumentIframe src={this.state.documentCalloutIframeUrl} />
</div>
<div style={{ clear: "both" }}></div>
</tabs.TabPanel>
The display looks like this as I hover over the Office Brand Guidelines file on the left:
It's a little slow to load the document images as I hover over the different documents(especially for larger documents), but it works great, is visually appealing and provides value to the users.
addEventListener
failing on those DOM elements?