scripts/django_cradmin/components/CradminHtmlList.jsx
import React from "react";
import ReactDOM from "react-dom";
export default class CradminHtmlList extends React.Component {
static get defaultProps() {
return {
className: 'selectable-list',
keyAttribute: 'id',
signalNameSpace: null,
htmlAttribute: 'html',
wrapContentsHtmlTagName: 'div',
loadMoreTreshold: 3
}
}
constructor(props) {
super(props);
this._name = `django_cradmin.components.CradminHtmlList.${this.props.signalNameSpace}`;
this.logger = new window.ievv_jsbase_core.LoggerSingleton().getLogger(
'django_cradmin.components.CradminHtmlList');
if(this.props.signalNameSpace == null) {
throw new Error('The signalNameSpace prop is required.');
}
this._onDataChangeSignal = this._onDataChangeSignal.bind(this);
this.state = {
dataList: [],
hasMorePages: false,
};
this.initializeSignalHandlers();
}
initializeSignalHandlers() {
new window.ievv_jsbase_core.SignalHandlerSingleton().addReceiver(
`${this.props.signalNameSpace}.DataChange`,
this._name,
this._onDataChangeSignal
);
}
componentWillUnmount() {
new window.ievv_jsbase_core.SignalHandlerSingleton()
.removeAllSignalsFromReceiver(this._name);
}
render() {
return <div className={this.props.className}>
{this.renderItems()}
</div>;
}
_loadMoreIfNeeded() {
if(this.state.hasMorePages && this.state.dataList.length < this.props.loadMoreTreshold) {
this.logger.debug('Automatically sending the LoadMore signal because we are below the loadMoreTreshold');
new window.ievv_jsbase_core.SignalHandlerSingleton().send(
`${this.props.signalNameSpace}.LoadMore`);
}
}
_onDataChangeSignal(receivedSignalInfo) {
if(this.logger.isDebug) {
this.logger.debug(receivedSignalInfo.toString(), receivedSignalInfo.data);
}
const dataList = receivedSignalInfo.data.results;
this.setState({
dataList: dataList,
hasMorePages: receivedSignalInfo.data.next != null
});
this._loadMoreIfNeeded();
}
renderItem(itemKey, itemData) {
return React.createElement(
this.props.wrapContentsHtmlTagName,
{
key: itemKey,
className: this.props.itemClassName,
dangerouslySetInnerHTML: {__html: itemData[this.props.htmlAttribute]}
}
);
}
renderItems() {
const items = [];
for(let itemData of this.state.dataList) {
let itemKey = itemData[this.props.keyAttribute];
items.push(this.renderItem(itemKey, itemData));
}
return items;
}
}