(function (global, p5VendorJs) { if (!p5VendorJs.React) throw "Missing React" if (!p5VendorJs.ReactDOM) throw "Missing ReactDOM" if (!p5VendorJs.createReactClass) throw "Missing createReactClass" var DBG = DBG || 0; var DBG1 = 1; /** * Loads props.url after mount. * If props.url changed: clear, start loding new url. * If props.url is empty: clear. * * Clear: show props.emptyUrlContent || '' * * @usage: * ReactDOM.render( * h(P5UI__AjaxContent, { * url: '', * }), * document.getElementById(HTML_ID) * ) * * props.url: url | null * props.loading: html | null * props.emptyContent: html | null - TODO: show when url is not defined * */ // var React = window.p5VendorJs.React; var createReactClass = window.p5VendorJs.createReactClass; var h = window.p5VendorJs.React.createElement; // componentDidMount: function () { console.log('MyWidget::componentDidMount...'); }, // componentWillReceiveProps: function (nextProps) { console.log('MyWidget::componentWillReceiveProps(nextProps)...', nextProps); }, // shouldComponentUpdate: function (nextProps, nextState) { console.log('MyWidget::shouldComponentUpdate(nextProps, nextState)...', nextProps, nextState); }, // componentWillUpdate: function (nextProps, nextState) { console.log('MyWidget::componentWillUpdate(nextProps, nextState)...', nextProps, nextState); }, // componentDidUpdate: function (prevProps, prevState) { console.log('MyWidget::componentDidUpdate(prevProps, prevState)...', prevProps, prevState); }, // componentWillUnmount: function () { console.log('MyWidget::componentWillUnmount...'); }, var P5UI__AjaxContent = createReactClass({ _refContentEl: null, setContentElRef: function (el) { this._refContentEl = el; }, getInitialState: function () { return { isLoading: false, postData: null, // if method = 'POST' response_type: null, response_msg: null, response_body: null, }; }, componentDidMount() { if (this.props.url) this._fetchContent(); }, componentDidUpdate(prevProps, prevState) { if (prevProps.url !== this.props.url) { this._fetchContent(); } }, _fetchContent: function () { this.setState({ isLoading: true }); // var _setState = this.setState.bind(this); var _handleFetchResponseSuccess = this._handleFetchResponseSuccess.bind(this); var _handleFetchResponseFail = this._handleFetchResponseFail.bind(this); var _handleFetchResponseJson = this._handleFetchResponseJson.bind(this); window.fetch(this.props.url, (!this.props.postData) ? { method: 'GET', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin', } : { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin', body: this.props.postData, // JSON.stringify(this.props.postData) } ).then(function (response) { DBG1 && console.log("DBG:response", { status: response.status, response: response }); response.text() .then(response.ok ? _handleFetchResponseSuccess : _handleFetchResponseFail) .catch(function (err) { _handleFetchResponseJson({ response_type: 'error', response_msg: "" + err, response_body: null, }) }) }).then(function (data) { DBG1 && console.warn("DBG:response data", { data }); }).catch(function (err) { DBG1 && console.log("Response Error #2:") DBG1 && console.error(err) }) }, _handleFetchResponseFail: function (responseText) { DBG1 && console.warn("DBG:response fail responseText", { responseText }); if (!responseText) throw "Error"; this._handleFetchResponseText(false, responseText) }, _handleFetchResponseSuccess: function (responseText) { DBG1 && console.warn("DBG:response success responseText", { responseText }); this._handleFetchResponseText(true, responseText) }, _handleFetchResponseText: function (isOk, responseText) { DBG1 && console.warn("DBG:response _handleFetchResponseText", { isOk, responseText }); if ('{' !== responseText.substr(0, 1)) throw "Response Parse Error: Expected json."; try { var jsonResponse = JSON.parse(responseText); if (!jsonResponse.msg) throw "Response Parse Error: Expected json with msg."; if (!isOk) throw jsonResponse.msg; // TODO: throw or just show alert for user this._handleFetchResponseJson(jsonResponse) } catch (err) { throw "Response Parse Error: " + err; } }, _handleFetchResponseJson: function (jsonResponse) { DBG1 && console.warn("DBG:response _handleFetchResponseJson", { jsonResponse }); this.setState({ isLoading: false, response_type: jsonResponse.type, response_msg: jsonResponse.msg, response_body: jsonResponse.body, }) }, shouldComponentUpdate: function (nextProps, nextState) { DBG1 && console.warn("DBG:response shouldComponentUpdate", { props: this.props, nextProps, state: this.state, nextState, }); if (!this.state.isLoading && nextState.isLoading) { doShowLoading(this.props, this._refContentEl); } if (!nextState.isLoading && nextState.response_type) { doParseResponseBody(nextState.response_type, nextState.response_msg, nextState.response_body, this._refContentEl); } return false; // render only once! }, render: function () { DBG1 && console.log('DBG:render (TODO: render only once!)', { options: this.state.options }); return h('div', { ref: this.setContentElRef, // dangerouslySetInnerHTML: { __html: this.renderContentHtml() } }); } }); function doParseResponseBody(type, msg, body, rootNode) { switch (type) { case 'error': return doNotify('error', (msg || "Wystąpił błąd"), rootNode); case 'success': return doShowContent(body, rootNode); default: return doNotify('warning', msg, rootNode); } } function doShowLoading(props, rootNode) { DBG1 && console.log('DBG:doShowLoading', { rootNode }); if (!rootNode) return; rootNode.innerHTML = props.loading || '
Loading ...
'; // DBG && rootNode.innerHTML += "\n" + '' + "props: " + JSON.stringify(props, null, 4) + ''; } function doShowContent(body, rootNode) { DBG1 && console.log('DBG:doShowContent', { rootNode }); if (!rootNode) return; if (body.reactNode) return p5UI__buildDom(body.reactNode, rootNode); if (body.html) return doShowHtmlContent(body.html, rootNode); if (typeof body === 'string' || body instanceof String) return doShowHtmlContent(body, rootNode); else { // TODO: if DBG rootNode.innerHTML = '
' + JSON.stringify(body, null, 4) + ''; } } function doShowHtmlContent(htmlContent, node) { node.innerHTML = htmlContent; } function doNotify(type, msg, rootNode) { // TODO: if (NOTIFY_USER_MODE) // 'inline' | 'notify' type = ('error' == type) ? 'danger' : type; rootNode.innerHTML = '