buildDom.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. (function (global, p5VendorJs) {
  2. if (!p5VendorJs.React) throw "Missing React"
  3. if (!p5VendorJs.ReactDOM) throw "Missing ReactDOM"
  4. if (!p5VendorJs.createReactClass) throw "Missing createReactClass"
  5. var React = p5VendorJs.React
  6. var ReactDOM = p5VendorJs.ReactDOM
  7. var createReactClass = p5VendorJs.createReactClass
  8. var h = React.createElement
  9. var DBG = 0
  10. // global.p5VendorJs['P5UI__MyWidget'] = createReactClass({
  11. // componentWillMount: function () { console.log('MyWidget::componentWillMount...'); },
  12. // render: function () {
  13. // console.log('MyWidget::render... state, props', this.state, this.props);
  14. // var defaultProps = {}
  15. // return h('div', Object.assign(defaultProps, {
  16. // ref: function (node) { this.rootNode = node; }.bind(this),
  17. // // onSubmit: this.submit.bind(this)
  18. // }), this.props.children)
  19. // },
  20. // componentDidMount: function () { console.log('MyWidget::componentDidMount...'); },
  21. // componentWillReceiveProps: function (nextProps) { console.log('MyWidget::componentWillReceiveProps(nextProps)...', nextProps); },
  22. // shouldComponentUpdate: function (nextProps, nextState) { console.log('MyWidget::shouldComponentUpdate(nextProps, nextState)...', nextProps, nextState); },
  23. // componentWillUpdate: function (nextProps, nextState) { console.log('MyWidget::componentWillUpdate(nextProps, nextState)...', nextProps, nextState); },
  24. // componentDidUpdate: function (prevProps, prevState) { console.log('MyWidget::componentDidUpdate(prevProps, prevState)...', prevProps, prevState); },
  25. // componentWillUnmount: function () { console.log('MyWidget::componentWillUnmount...'); },
  26. // })
  27. var P5UI__RawHtml = createReactClass({
  28. componentDidMount: function () {
  29. if (this.props.rawHtml) {
  30. this.rootNode.innerHTML = this.props.rawHtml
  31. }
  32. },
  33. render: function () {
  34. return h('div', {
  35. ref: function (node) { this.rootNode = node; }.bind(this),
  36. })
  37. }
  38. })
  39. global.p5VendorJs['P5UI__RawHtml'] = P5UI__RawHtml
  40. var P5UI__FeatureEditForm = createReactClass({
  41. componentDidMount: function () {
  42. if(DBG)console.warn('P5UI__FeatureEditForm::componentDidMount this.rootNode', this.rootNode)
  43. jQuery(this.rootNode).find('textarea').autosize();
  44. jQuery(this.rootNode).find('.frm-help').popover({trigger:'hover'});
  45. jQuery(this.rootNode).find('.show-last-value input').on('input', function(e) {
  46. var input, btn, btnIco;
  47. input = jQuery(e.target);
  48. btn = input.next('.button-appendBack');
  49. btnIco = btn.find('.glyphicon');
  50. if (btn.attr('title') != input.val()) {
  51. btnIco.show();
  52. } else {
  53. btnIco.hide();
  54. }
  55. });
  56. jQuery(this.rootNode).find('.show-last-value').find('.button-appendBack').on('click', function(e) {
  57. var input, btn, btnIco;
  58. btn = jQuery(this);
  59. btnIco = btn.find('.glyphicon');
  60. input = btn.prev();
  61. if (input.is('input')) {
  62. if (btn.attr('title') != input.val()) {
  63. input.val(btn.attr('title'));
  64. btnIco.hide();
  65. }
  66. }
  67. });
  68. },
  69. submit: function (e) {
  70. if(DBG)console.warn('P5UI__FeatureEditForm::submit this.rootNode', this.rootNode)
  71. e.preventDefault()
  72. var formData = {};
  73. jQuery(this.rootNode).serializeArray().map(function(i) { formData[i.name] = i.value; });// TODO: edit Widget - send only updated fields
  74. // TODO: change Edit btn to return to edit record with fields -> show form
  75. var taskCont = jQuery(this.rootNode).parents('.AjaxTableTaskCnt').parent(); // jQuery('#{$this->_htmlID}_task').parent();
  76. //taskCont.empty();
  77. taskCont.children().fadeOut('slow');
  78. var alertCntWrap = jQuery('<div class="AjaxTableAlert AjaxTable-loading"></div>').prependTo(taskCont)
  79. , alertCnt = jQuery('<div class="container"></div>').prependTo(alertCntWrap);
  80. jQuery('<div class="alert alert-info"><div style="padding:0 0 0 20px; background:url(./icon/loading.gif) no-repeat left top;"> zapisywanie ... </div></div>').appendTo(alertCnt);
  81. function notifyAjaxCallback(data) {
  82. var notify = {}, outMsg = '';
  83. notify.type = (data && data.type)? data.type : '';
  84. notify.msg = (data && data.msg)? data.msg : '';
  85. switch (notify.type) {
  86. case 'success':
  87. if (!notify.msg) notify.msg = 'Dane poprawnie zaktualizowane';
  88. break;
  89. case 'info':
  90. if (!notify.msg) notify.msg = 'Nie wprowadzono żadnych zmian';
  91. break;
  92. case 'error':
  93. if (!notify.msg) notify.msg = 'Wystąpiły błędy';
  94. break;
  95. case 'warning':
  96. notify.type = 'warn';
  97. if (!notify.msg) notify.msg = 'Wystąpiły błędy';
  98. break;
  99. default:
  100. notify.msg = 'Nieznany błąd';
  101. if (data && data.errorCode) notify.msg += ' ' + data.errorCode;
  102. notify.type = '';
  103. }
  104. jQuery.notify(notify.msg, notify.type);
  105. var alertType = ('error' == data.type) ? 'danger' : data.type;
  106. outMsg = '<div class="alert alert-' + alertType + '">' + notify.msg + '</div>';
  107. return outMsg;
  108. }
  109. var idRecord = this.props.idRecord
  110. var tableLabelHtml = this.props.tableLabelHtml
  111. superagent
  112. .post(this.props.ajaxSaveUrl)
  113. .type('json') // header ĺapplication/x-www-form-urlencoded' requires type('form');
  114. .send({
  115. namespace: this.props.namespace,
  116. primaryKey: this.props.idRecord,
  117. form: formData
  118. })
  119. .set('Accept', 'application/json')
  120. .end(function(err, res) {
  121. var payload;
  122. if (err || !res.ok || 'application/json' !== res.type) {
  123. payload = {type: 'warning', msg: res.body.msg || 'Wystąpiły błędy', body: res.body};
  124. } else {
  125. payload = {type: 'success', msg: res.body.msg || '', body: res.body};
  126. }
  127. var data = res.body;
  128. alertCntWrap.removeClass('AjaxTable-loading');
  129. alertCnt.empty();
  130. if (false === ['success', 'info'].indexOf(payload.type)) {
  131. jQuery(errorTxt).appendTo(alertCnt);
  132. var errLinks = jQuery('<div class="breadcrumb"></div>').appendTo(alertCnt);
  133. jQuery('<a href="#" onclick="return tableAjaxBackToTable();"> <i class="icon-arrow-left"></i> Wróć do tabeli '+tableLabelHtml+'</a>').appendTo(errLinks);
  134. var backToEditBtn = jQuery('<a href="#EDIT/'+idRecord+'/' + Math.random(1).toString().substr(2) + '" class="btn btn-link btn-small"> <i class="icon-pencil"></i> Popraw dane '+idRecord+'</a>').appendTo(errLinks);
  135. backToEditBtn.on('click', function(){
  136. alertCnt.remove();
  137. taskCont.children().fadeIn('slow');
  138. return false;
  139. });
  140. } else {
  141. var outMsg = notifyAjaxCallback(payload);
  142. var out = '';
  143. out += outMsg;
  144. out += '<div class="breadcrumb">' +
  145. ' <a href="#" onclick="return tableAjaxBackToTable();" class="btn btn-link btn-sm"> <i class="glyphicon glyphicon-arrow-left"></i> Wróć do tabeli '+tableLabelHtml+'</a>' +
  146. ' <a href="#EDIT/'+idRecord+'/' + Math.random(1).toString().substr(2) + '" class="btn btn-link btn-sm"> <i class="glyphicon glyphicon-pencil"></i> Edytuj rekord '+idRecord+'</a>' +
  147. '</div>';
  148. jQuery(out).appendTo(alertCnt);
  149. // add rowFunctions from response
  150. if (data && data.rowFunctions && data.primaryKey) {
  151. var rowFunWrapNode = $('<div class="container"></div>').insertAfter(alertCnt);
  152. var rowFunListNode = $('<ul></ul>').appendTo(rowFunWrapNode);
  153. var keys = Object.keys(data.rowFunctions),
  154. total = keys.length,
  155. moreFuncBtnNode,
  156. moreFunctions = [],
  157. idx
  158. ;
  159. moreFunctions = keys.splice(3);
  160. keys.forEach(function(key) {
  161. var cellNode = $('<li></li>');
  162. var funObj = data.rowFunctions[key],
  163. funcNode = p5UI_TableAjax_generateFunctionNode(funObj, data.primaryKey, {ico: true, label: true})
  164. ;
  165. funcNode.appendTo(cellNode);
  166. cellNode.appendTo(rowFunListNode);
  167. });
  168. }
  169. }
  170. })
  171. },
  172. render: function () {
  173. if(DBG)console.warn('P5UI__FeatureEditForm::render this.props', this.props)
  174. var formProps = Object.assign({}, this.props)
  175. delete formProps.children
  176. return h('form', Object.assign(formProps, {
  177. ref: function (node) { this.rootNode = node; }.bind(this),
  178. onSubmit: this.submit.bind(this)
  179. }), this.props.children)
  180. }
  181. })
  182. global.p5VendorJs['P5UI__FeatureEditForm'] = P5UI__FeatureEditForm
  183. var P5UI__Typespecial = createReactClass({
  184. componentDidMount: function () {
  185. if(DBG)console.log('TS::componentDidMount (['+this.props.idField+'] '+this.props.fieldNamespace+') ...')
  186. // console.log('TS::componentDidMount (['+this.props.idField+'] '+this.props.fieldNamespace+') this.rootNode', this.rootNode) // OK
  187. var fldNode = jQuery(document.getElementById(this.props.fieldName)) // jQuery('#{$fName}')
  188. var tsNode = jQuery(this.rootNode) // jQuery('#ts-{$fName}')
  189. var ajaxDataUrlBase = this.props.ajaxDataUrlBase
  190. if (!fldNode && !tsNode) {
  191. console.log("BUG Missing fldNode or tsNode in P5UI__Typespecial")
  192. return;
  193. }
  194. if (!ajaxDataUrlBase) {
  195. console.log("BUG Missing ajaxDataUrlBase in P5UI__Typespecial")
  196. return;
  197. }
  198. fldNode.attr('name', '');
  199. fldNode.hide();
  200. if (fldNode.parent().hasClass('show-last-value')) {
  201. fldNode.parent().hide();
  202. }
  203. tsNode.attr('name', this.props.frmFldName)
  204. tsNode.attr('tabindex', fldNode.attr('tabindex'))
  205. var getFetchCallback = ('TypespecialVariable' === this.props.type)
  206. ? function (query, callback) {
  207. return function(res) {
  208. for (var i in res) {
  209. if (!res[i].name || res[i].id != res[i].name) {
  210. res[i].name = res[i].id + ': ' + res[i].name;
  211. }
  212. }
  213. callback(res);
  214. }
  215. }
  216. : function (query, callback) {
  217. return function(res) {
  218. var i, prefix, prefixLen;
  219. for (i in res) {
  220. prefix = '' + res[i].id;
  221. prefixLen = prefix.length;
  222. if (prefixLen > 0 && prefix !== res[i].name.substr(0, prefixLen)) {
  223. res[i].name = res[i].id + ': ' + res[i].name;
  224. }
  225. res[i]['\$order'] = 1 + (parseInt(i) || 0); // set order from request
  226. }
  227. callback(res);
  228. }
  229. }
  230. ;
  231. var scoreCallback = ('TypespecialVariable' === this.props.type)
  232. ? function(search) {
  233. var score = this.getScoreFunction(search);
  234. return function(item) {
  235. // console.log('score:item:', item, ', score:', score(item));
  236. if (search && search == item.id) {
  237. return 1;
  238. } else {
  239. return score(item);// score(item) * (1 + Math.min(item.watchers / 100, 1));
  240. }
  241. };
  242. }
  243. : function(query) {
  244. // console.log('Typespecial({$fName})::score: q(', query, ')');
  245. var score = this.getScoreFunction(query);
  246. return function(item) {
  247. var retScore = 0, lName = ('' + item.name).toLowerCase(), lQuery = query.toLowerCase();
  248. if (query.search(' ') > -1) {
  249. retScore = score(item);
  250. }
  251. else {
  252. if (lQuery + ':' == lName.substr(0, lQuery.length + 1)) {
  253. retScore = 100;
  254. } else if (lName.search(lQuery) > -1) {
  255. retScore = 90 - lName.search(lQuery);
  256. } else {
  257. retScore = 0;
  258. }
  259. }
  260. // console.log('Typespecial({$fName})::score: q(', lQuery, ') , retScore(', retScore, '), score(', score(item), '), item.name(', item.name, ') item.id:', item.id);
  261. return retScore;
  262. };
  263. }
  264. ;
  265. tsNode.selectize({
  266. theme: 'typespecial',
  267. valueField: 'id',
  268. labelField: 'id',
  269. searchField: 'name',
  270. sortField: ('TypespecialVariable' === this.props.type) ? 'name' : '$order', // TODO: skip in Typespecial - default sort field is '$order'
  271. create: this.props.create,
  272. delimiter: ';',
  273. dataAttr: 'typespecial',
  274. preload: this.props.preload || false,
  275. options: this.props.options,
  276. render: {
  277. item: function(item, escape) {
  278. return '<div>' +
  279. '<span class=\"name\">' + escape(item.name || item.id) + '</span>' +
  280. '</div>';
  281. },
  282. option: function(item, escape) {
  283. return '<div>' +
  284. '<span class=\"title\">' +
  285. escape(item.name || item.id) +
  286. '</span>' +
  287. '</div>';
  288. }
  289. },
  290. onItemAdd: function(value, item) {// Invoked when an item is selected.
  291. var curSel = this.options[value] || null, fieldExport;
  292. if (curSel && curSel.exports) {
  293. for (var i in curSel.exports) {
  294. fieldExport = jQuery('#ts-f' + i);
  295. if (fieldExport.length) {
  296. //console.log('--- onItemAdd fieldExport.selectize(',fieldExport.selectize,')', fieldExport);
  297. if (fieldExport.get(0).selectize) {
  298. fieldExport.get(0).selectize.addOption({id:curSel.exports[i], name:curSel.exports[i]});
  299. fieldExport.get(0).selectize.setValue(curSel.exports[i]);
  300. } else {
  301. //jQuery('#f' + i).val(curSel.exports[i]);
  302. }
  303. } else {
  304. fieldExport = jQuery('#f' + i);
  305. if (fieldExport.is('input')) {
  306. jQuery('#f' + i).val(curSel.exports[i]);
  307. } else if (fieldExport.is('select')) {
  308. //TODO: add option and select //jQuery('#f' + i).val(curSel.exports[i]);
  309. }
  310. }
  311. }
  312. }
  313. },
  314. score: scoreCallback,
  315. load: function(query, callback) {
  316. // if (!query.length) return callback(); // empty query at preload action
  317. $.ajax({
  318. url: ajaxDataUrlBase,
  319. data: 'q=' + encodeURIComponent(query),
  320. type: 'POST',
  321. error: function() {
  322. callback();
  323. },
  324. success: getFetchCallback(query, callback),
  325. });
  326. }
  327. });
  328. },
  329. render: function () {
  330. if(DBG)console.log('TS::render (['+this.props.idField+'] '+this.props.fieldNamespace+') props', this.props)
  331. return h('div', {
  332. 'className': "typespecial",
  333. 'style': { 'max-width': '366px' }
  334. }, [
  335. h('select', {
  336. 'ref': function (node) { this.rootNode = node; }.bind(this),
  337. }, this.props.children)
  338. ])
  339. }
  340. })
  341. global.p5VendorJs['P5UI__Typespecial'] = P5UI__Typespecial
  342. var P5UI__FeatureRowFunctions = createReactClass({
  343. componentDidMount: function () {
  344. if(DBG)console.warn('P5UI__FeatureRowFunctions::componentDidMount this.rootNode', this.rootNode)
  345. if (this.props.rawHtml) {
  346. if(DBG)console.warn('P5UI__FeatureRowFunctions::componentDidMount this.props.rawHtml', this.props.rawHtml)
  347. this.rootNode.innerHTML = this.props.rawHtml
  348. }
  349. },
  350. render: function () {
  351. var showLabels = this.props.showLabels || false
  352. var functions = this.props.functions || {}
  353. if (!this.props.id) return h('div', { 'className': 'alert alert-danger' }, "Missing ID")
  354. if(DBG)console.warn('P5UI__FeatureRowFunctions::render this.props', this.props)
  355. return h('div', {
  356. ref: function (node) { this.rootNode = node; }.bind(this),
  357. }, [
  358. ('hist' in functions)
  359. ? h('a', { className: "btn btn-xs btn-link", href: functions.hist.href.replace("{0}", this.props.id), title: functions.hist.title }, [ h('span', { className: functions.hist.ico }), h('span', { style: {'padding': '0 6px'} }, functions.hist.title) ])
  360. : null
  361. ,
  362. ('files' in functions)
  363. ? h('a', { className: "btn btn-xs btn-link", href: functions.files.href.replace("{0}", this.props.id), title: functions.files.title }, [ h('span', { className: functions.files.ico }), h('span', { style: {'padding': '0 6px'} }, functions.files.title) ])
  364. : null
  365. ,
  366. ('msgs' in functions)
  367. ? h('a', { className: "btn btn-xs btn-link", href: functions.msgs.href.replace("{0}", this.props.id), title: functions.msgs.title }, [ h('span', { className: functions.msgs.ico }), h('span', { style: {'padding': '0 6px'} }, functions.msgs.title) ])
  368. : null
  369. ,
  370. (this.props.viewMoreDropdown)
  371. ? h(P5UI__MoreFunctionsDropdownAjax, this.props.viewMoreDropdown)
  372. : null
  373. ,
  374. ])
  375. }
  376. })
  377. global.p5VendorJs['P5UI__FeatureRowFunctions'] = P5UI__FeatureRowFunctions
  378. var P5UI__MoreFunctionsDropdownAjax = createReactClass({
  379. componentDidMount: function () {
  380. jQuery(this.rootNode).popover({
  381. container: 'body',
  382. placement: 'bottom',
  383. trigger: 'click',
  384. // title: e.data.col + '<a href="#" class="glyphicon glyphicon-remove pull-right" onclick="return hidePopover();"></a>',
  385. title: 'Więcej funkcji dla rekordu nr ' + this.props.primaryKey, // '<div style="display:block;position:relative;padding:0 20px 0 0;">' + (this.props.friendly || colName) + ' <button type="button" class="close" onclick="return hidePopover();" style="position:absolute;right:0;top:0;">&times;</button>' + '</div>',
  386. html: true,
  387. content: 'TODO: list...', // this.renderListToString.bind(this),
  388. template: '' +
  389. '<div class="popover" role="tooltip" style="max-width:600px;width:400px;">' +
  390. '<div class="arrow"></div>' +
  391. '<div style="display:block;position:relative;">' +
  392. '<div class="popover-title">' +
  393. '</div>' +
  394. '</div>' +
  395. '<div class="popover-content"></div>' +
  396. '</div>'
  397. })
  398. this.setState({ 'isOpen': false })
  399. },
  400. componentWillUnmount: function () {
  401. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::componentWillUnmount")
  402. jQuery(this.rootNode).popover('destroy')
  403. },
  404. componentWillMount: function() {
  405. this._closeDropdownIfClickedOutside = function (event) {
  406. if (!this.state.isOpen) return;
  407. var idHtmlPopover = jQuery(this.rootNode).attr('aria-describedby')
  408. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::_closeDropdownIfClickedOutside idHtmlPopover:", idHtmlPopover)
  409. if (!idHtmlPopover) return;
  410. var popoverNode = document.getElementById(idHtmlPopover)
  411. var isClickedOutside = p5UI__clickedOutsideElement(popoverNode, event)
  412. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::_closeDropdownIfClickedOutside isClickedOutside:", isClickedOutside, 'this.rootNode', this.rootNode)
  413. if (isClickedOutside) {
  414. if (jQuery(this.rootNode).data("bs.popover")) {
  415. jQuery(this.rootNode).popover('hide')
  416. } else {
  417. popoverNode.parentNode.removeChild(popoverNode) // DOM removed before 'hide'
  418. }
  419. this.setState({
  420. isOpen: false
  421. }, this._unbindCloseDropdownIfClickedOutside.bind(this));
  422. }
  423. }.bind(this);
  424. this._bindCloseDropdownIfClickedOutside = function () {
  425. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::_bindCloseDropdownIfClickedOutside", this._closeDropdownIfClickedOutside)
  426. if (!document.addEventListener && document.attachEvent) {
  427. document.attachEvent('onclick', this._closeDropdownIfClickedOutside);
  428. } else {
  429. document.addEventListener('click', this._closeDropdownIfClickedOutside);
  430. }
  431. }.bind(this);
  432. this._unbindCloseDropdownIfClickedOutside = function () {
  433. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::_unbindCloseDropdownIfClickedOutside", this._closeDropdownIfClickedOutside)
  434. if (!document.removeEventListener && document.detachEvent) {
  435. document.detachEvent('onclick', this._closeDropdownIfClickedOutside);
  436. } else {
  437. document.removeEventListener('click', this._closeDropdownIfClickedOutside);
  438. }
  439. }.bind(this);
  440. },
  441. shouldComponentUpdate: function (nextProps, nextState) {
  442. if (!nextState) return false
  443. if (!this.state) return false
  444. if (this.state.rowFunctions !== nextState.rowFunctions) {
  445. var idHtmlPopover = jQuery(this.rootNode).attr('aria-describedby')
  446. if(DBG)console.warn("P5UI__MoreFunctionsDropdownAjax::shouldComponentUpdate idHtmlPopover:", idHtmlPopover, 'nextState.rowFunctions', nextState.rowFunctions)
  447. if (idHtmlPopover && nextState.rowFunctions && nextState.rowFunctions.length) {
  448. jQuery(document.getElementById(idHtmlPopover)).find('.popover-content').html(this.renderListToString(nextState.rowFunctions))
  449. } else {
  450. jQuery(document.getElementById(idHtmlPopover)).find('.popover-content').html('<p class="text-muted">Brak dodatkowych funkcji</p>')
  451. }
  452. }
  453. return false
  454. },
  455. renderListToString: function (list) {
  456. if(DBG)console.warn('P5UI__MoreFunctionsDropdownAjax::renderListToString - this.state:', this.state)
  457. var primaryKey = this.props.id
  458. var out = '<ul class="list-unstyled">' + list.map(function (fun) {
  459. return '<li><a href="'+fun.href.replace('{0}', primaryKey)+'" style="margin:0 2px;" title="'+fun.title+'">' +
  460. (fun.ico ? '<span class="'+fun.ico+'"></span> ' : '') +
  461. (fun.label || fun.title) +
  462. '</a></li>'
  463. }).join('') + '</ul>'
  464. if(DBG)console.warn('P5UI__MoreFunctionsDropdownAjax::renderListToString - out:', out)
  465. return out
  466. },
  467. onAjaxFetch: function (data) {
  468. this.setState({ rowFunctions: data.rowFunctions })
  469. },
  470. handleClick: function (e) {
  471. e.preventDefault()
  472. if (!this.props.uri) throw "Missing uri in P5UI__MoreFunctionsDropdownAjax"
  473. if (this.state.isOpen) {
  474. jQuery(this.rootNode).popover('hide')
  475. } else {
  476. jQuery(this.rootNode).popover('show')
  477. var idHtmlPopover = jQuery(this.rootNode).attr('aria-describedby')
  478. if (idHtmlPopover) {
  479. jQuery(document.getElementById(idHtmlPopover)).find('.popover-content').html('<p>Loading...</p>')
  480. }
  481. // global.fetch()
  482. // setTimeout(this.onAjaxFetch.bind(this, { msg: "Funkcje", type: "success", rowFunctions: [
  483. // { id: "msgs", ico: "glyphicon glyphicon-envelope", href: "index.php?_route=TableMsgs&_task=tableRow&idTable=13051&idRow=83", label: 'Wiadomości <span class="badge">0</badge>', title: "Wiadomości (0)" },
  484. // { ico: "glyphicon glyphicon-file", href: "https://biuro.biall-net.pl/dev-pl/se-master/index.php?_route=UrlAction_Ant&typeName=default_db:TEST_PERMS&primaryKey=83", label: 'Druki', title: "Druki" },
  485. // ] }), 1000)
  486. _popoverCellAjaxXhr = jQuery.ajax({
  487. type: 'GET',
  488. url: this.props.uri,
  489. dataType: 'json',
  490. contentType: "application/json; charset=utf-8",
  491. })
  492. .done(function(data, textStatus, jqXHR){
  493. if (data && 'success' === data.type) {
  494. var rowFunctions = (data.rowFunctions && data.rowFunctions.length > 0)
  495. ? data.rowFunctions
  496. : [];
  497. this.setState({ rowFunctions: data.rowFunctions })
  498. }
  499. }.bind(this))
  500. if (this.state.isOpen) this.setState({ 'isOpen': false })
  501. else this.setState({ 'isOpen': true }, this._bindCloseDropdownIfClickedOutside)
  502. }
  503. },
  504. render: function () {
  505. if(DBG)console.warn('P5UI__MoreFunctionsDropdownAjax::render this.props', this.props)
  506. return h('button', {
  507. className: 'btn btn-xs btn-link',
  508. ref: function (node) { this.rootNode = node; }.bind(this),
  509. onClick: this.handleClick.bind(this)
  510. }, [
  511. h('span', {'className':"glyphicon glyphicon-menu-hamburger"}),
  512. " Więcej "
  513. ]);
  514. }
  515. })
  516. global.p5VendorJs['P5UI__MoreFunctionsDropdownAjax'] = P5UI__MoreFunctionsDropdownAjax
  517. function buildDom(dom, target) {
  518. ReactDOM.render(buildReactNodeRec(dom), target)
  519. }
  520. function buildReactNodeRec(dom) {
  521. if (null === dom) return null
  522. if ('string' === typeof dom) return dom
  523. var nodeReactType = dom[0]
  524. if ('P5UI__' === nodeReactType.substr(0, 'P5UI__'.length)) {
  525. if (nodeReactType in global.p5VendorJs) nodeReactType = global.p5VendorJs[nodeReactType]
  526. }
  527. return h(nodeReactType,
  528. convertAttrsToReact(dom[0], dom[1]),
  529. (dom[2] && 'function' === typeof dom[2].map)
  530. ? dom[2].map(buildReactNodeRec)
  531. : dom[2]
  532. )
  533. }
  534. function convertAttrsToReact(tagName, attrs) {
  535. if (!attrs) return null
  536. if(DBG)console.log('todo convertAttrsToReact typeof attrs ('+ typeof attrs +') toString('+ attrs.toString() +')');
  537. if (!attrs.toString()) return null
  538. if ('class' in attrs) {
  539. attrs['className'] = attrs['class']
  540. delete attrs['class']
  541. }
  542. if ('input' === tagName && 'value' in attrs) { // fix input to uncontrolled
  543. attrs['defaultValue'] = attrs['value']
  544. delete attrs['value']
  545. }
  546. if ('input' === tagName && 'maxlength' in attrs) { // fix input to uncontrolled
  547. attrs['maxLength'] = attrs['maxlength']
  548. delete attrs['maxlength']
  549. }
  550. return attrs
  551. }
  552. global.p5UI__buildDom = buildDom
  553. })(window, window.p5VendorJs);