| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- (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 || '<p>Loading ...</p>';
- // DBG && rootNode.innerHTML += "\n" + '<pre>' + "props: " + JSON.stringify(props, null, 4) + '</pre>';
- }
- 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 = '<pre>' + JSON.stringify(body, null, 4) + '</pre>';
- }
- }
- 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 = '<div class="alert alert-' + type + '" style="margin-bottom:0">' + msg + '</div>';
- }
- global.P5UI__AjaxContent = P5UI__AjaxContent;
- })(window, window.p5VendorJs);
|