if (!URI_BASE) throw "Missing URI_BASE"; // => Request::getPathUri() if (!URI_WPS) throw "Missing URI_WPS"; if (!global.jQuery) throw "Missing jQuery" var $ = global.jQuery var RENDER_AS_REACT = Boolean(RENDER_AS_REACT) || false var DBG = DBG || false; var DBG1 = true; if (!global.p5VendorJs) throw "Missing p5 Vendor js libs"; if (!global.p5VendorJs.Redux) throw "Missing p5 Vendor js lib: Redux"; if (!global.createTableFiltersStateObject) throw "Missing createTableFiltersStateObject"; if (!global.createTableSelectedStateObject) throw "Missing createTableSelectedStateObject"; if (!global.createTableDataStateObject) throw "Missing createTableDataStateObject"; var createReactClass = global.p5VendorJs.createReactClass; var h = global.p5VendorJs.React.createElement; var ReactDOM = global.p5VendorJs.ReactDOM; var Redux = global.p5VendorJs.Redux; var ReduxThunk = global.p5VendorJs.ReduxThunk; var createStoreWithThunkMiddleware = Redux.applyMiddleware(ReduxThunk)(Redux.createStore); // TODO: to vendor.js var p5UI__FieldCheckboxSearch = global.p5VendorJs['p5UI__FieldCheckboxSearch']; var p5UI__FieldCheckboxLoading = global.p5VendorJs['p5UI__FieldCheckboxLoading']; var p5UI__TableAjaxWidget = global.p5VendorJs['p5UI__TableAjax']; var P5UI__TableAjaxSortableLabel = global.p5VendorJs['P5UI__TableAjaxSortableLabel']; var P5UI__TableAjaxRowCheckbox = global.p5VendorJs['P5UI__TableAjaxRowCheckbox']; var P5UI__TableAjaxSelectedInfo = global.p5VendorJs['P5UI__TableAjaxSelectedInfo']; if (!String.prototype.startsWith) { // TODO: to global js utils String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; }; } p5WfsRefFilter = (function () { // convert GET param key ogc filter for ref return { parse: function (filterKey) { if (filterKey.startsWith('Ref_From_')) return { type: 'From', idInstance: filterKey.substr('Ref_From_'.length) }; if (filterKey.startsWith('Ref_To_')) return { type: 'To', idInstance: filterKey.substr('Ref_To_'.length) }; return null; } }; })(); function p5Utils__mapToQuery(map, callback) { var mapCallback = ('function' === typeof callback) ? callback : function (key) { return '' + key + '=' + encodeURIComponent(map.get(key)); }; return Array.from(map.keys()).sort() .map(mapCallback) .join('&') } function p5Utils__mapToQueryWithKeyPrefix(map, keyPrefix, callback) { var mapCallback = ('function' === typeof callback) ? callback : function (key) { return '' + (keyPrefix || '') + key + '=' + encodeURIComponent(map.get(key)); }; return p5Utils__mapToQuery(map, mapCallback) } function p5Utils__objectToQueryWithKeyPrefix(obj, prefix, callback) { if (!obj) return ''; var mapCallback = ('function' === typeof callback) ? callback : function (key) { return '' + key + '=' + encodeURIComponent(obj[key]); }; return Object.keys(obj).sort() .map(mapCallback) .join('&') } global['P5UI__TableAjaxSpecialFilter'] = createReactClass({ // props.store: Redux store with state: { isLoading bool, selected array of strings } // props.actions: Redux store actions // props.name: PropTypes.string.isRequired // props.values: PropTypes.array.isRequired // props.icon: PropTypes.string.isRequired // props.label: PropTypes.string getStateFromStore: function () { var state = this.props.store.getState(); DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected: state.specialFilter.get(this.props.name) }); return { selected: state.specialFilter.get(this.props.name), }; }, getInitialState: function () { return this.getStateFromStore(); }, componentDidMount: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::componentDidMount (name:'+this.props.name+')'); this.unsubscribe = this.props.store.subscribe(this.storeUpdated) }, componentWillUnmount: function () { this.unsubscribe() }, storeUpdated: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::storeUpdated (name:'+this.props.name+')'); this.setState(this.getStateFromStore()) }, shouldComponentUpdate: function (nextProps, nextState) { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::shouldComponentUpdate (name:'+this.props.name+')', { state: this.state, nextState}); return ( this.state.selected !== nextState.selected ); }, handleRemoveFilter: function (event) { this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, '') ); }, handleSetFilter: function (value) { this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, value) ); }, renderButton: function (buttonKey) { var option = buttonKey; var props = this.props.values[option]; var value = props.value || ''; var state = this.props.store.getState(); DBG && console.warn('DBG:renderButton state', { state, props, value }); var active = (value === this.state.selected); return h('button', { className: "btn btn-xs btn-default" + ( active ? " active" : "" ), onClick: function (event) { DBG && console.warn('DBG:renderButton click', { value }); this.handleSetFilter(value); }.bind(this), }, option); }, render: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::render (name:'+this.props.name+')', { state: this.state, props: this.props }); var label = this.props.label || this.props.name; return h('div', { className: "btn-group", style: { margin: '0 4px 0 0' } }, [ h('button', { className: "btn btn-xs btn-default", title: label, }, [ h('i', { className: this.props.icon }) ]) ].concat( Object.keys(this.props.values).map(this.renderButton) ).concat( [ h('button', { className: "btn btn-xs btn-default", title: "Kasuj filtr", disabled: !this.state.selected, onClick: this.handleRemoveFilter, style: { color: !this.state.selected ? '#bbb' : '#f00' } }, [ h('i', { className: "glyphicon glyphicon-remove" }) ]) ] ) ); } }); global['P5UI__TableAjaxSpecialFilterRelations'] = createReactClass({ // props.store: Redux store with state: { isLoading bool, selected array of strings } // props.actions: Redux store actions // props.name: PropTypes.string.isRequired // props.values: PropTypes.array.isRequired // props.icon: PropTypes.string.isRequired // props.label: PropTypes.string // props.availableBackRefs: PropTypes.array.isRequired // array of objects { id, namespace, label } // props.availableChildRefs: PropTypes.array.isRequired // array of objects { id, namespace, label } getStateFromStore: function () { var state = this.props.store.getState(); DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected: state.specialFilter.get(this.props.name) }); var selected = []; // Array of { idInstance, primaryKey } state.specialFilter.forEach(function (value, key) { var refInfo = p5WfsRefFilter.parse(key); // null | { type: 'From' | 'To', idInstance: int } if (refInfo) { selected.push(Object.assign(refInfo, { primaryKey: value, filterKey: key })) } }) DBG && console.log('TODO: DBG::P5UI__TableAjaxSpecialFilterRelations::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected }); return { selected: selected, }; }, getInitialState: function () { return this.getStateFromStore(); }, componentDidMount: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::componentDidMount (name:'+this.props.name+')'); this.unsubscribe = this.props.store.subscribe(this.storeUpdated) }, componentWillUnmount: function () { this.unsubscribe() }, storeUpdated: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::storeUpdated (name:'+this.props.name+')'); this.setState(this.getStateFromStore()) }, shouldComponentUpdate: function (nextProps, nextState) { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::shouldComponentUpdate (name:'+this.props.name+')', { state: this.state, nextState}); return ( this.state.selected !== nextState.selected ); }, handleRemoveFilter: function (event) { this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, '') ); }, handleSetFilter: function (value) { this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, value) ); }, handleCreate: function () { // TODO: save swal reference to variable to avoid open twice? var inputOptions = {}; if (this.props.availableBackRefs) this.props.availableBackRefs.forEach(function (instanceInfo) { inputOptions[ 'From_' + instanceInfo.id ] = "z " + instanceInfo.label || instanceInfo.namespace; }); if (this.props.availableChildRefs) this.props.availableChildRefs.forEach(function (instanceInfo) { inputOptions[ 'To_' + instanceInfo.id ] = "do " + instanceInfo.label || instanceInfo.namespace; }); swal({ title: "Wybierz rodzaj relacji", input: 'select', inputOptions: inputOptions, inputPlaceholder: "Wybierz", showCancelButton: true, cancelButtonText: "Anuluj", animation: false, inputValidator: function (value) { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::inputValidator', value); return new Promise(function (resolve) { if (!value) { resolve('Nie wybrano obiektu'); } else { resolve(); } }); }, }).then(this.handleInstanceCreate) // args: { value: ... } }, handleInstanceCreate: function (result) { if (!result.value) return; // cancel when result = { dismiss: "cancel" } var idInstance = ''; var type = ''; var instanceLabel = ''; if ('From_' === result.value.substr(0, 'From_'.length)) { type = 'From'; idInstance = result.value.substr('From_'.length); if (this.props.availableBackRefs) this.props.availableBackRefs.forEach(function (instanceInfo) { if (idInstance == instanceInfo.id) instanceLabel = instanceInfo.label || instanceInfo.namespace; }); } else if ('To_' === result.value.substr(0, 'To_'.length)) { type = 'To'; idInstance = result.value.substr('To_'.length); if (this.props.availableChildRefs) this.props.availableChildRefs.forEach(function (instanceInfo) { if (idInstance == instanceInfo.id) instanceLabel = instanceInfo.label || instanceInfo.namespace; }); } DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::handleInstanceCreate (name:'+this.props.name+') selected instance('+idInstance+')', { result: result, state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs }); swal({ title: "Wybierz obiekt", html: (instanceLabel) ? "typu: " + instanceLabel : "", input: 'text', inputPlaceholder: "Wybierz obiekt", showCancelButton: true, cancelButtonText: "Anuluj", animation: false, inputValidator: function (value) { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::inputValidator', value); return new Promise(function (resolve) { if (!value) { resolve('Nie podano obiektu'); } else { resolve(); } }); }, preConfirm: function (value) { return { type: type, idInstance: idInstance, primaryKey: value, } } }).then(this.handleInstancePrimaryKeySelected) // args: { value: { idInstance, primaryKey } } }, handleInstancePrimaryKeySelected: function (result) { if (!result.value) return; // cancel when result = { dismiss: "cancel" } var type = result.value.type; var idInstance = result.value.idInstance; var primaryKey = result.value.primaryKey; DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::handleInstancePrimaryKeySelected (name:'+this.props.name+') selected featureID('+idInstance+'.'+primaryKey+')', { result: result, state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs }); this.props.store.dispatch( this.props.actions.setSpecialFilter('Ref_' + type + '_' + idInstance, primaryKey) ); }, renderButton: function (buttonKey) { var option = buttonKey; var props = this.props.values[option]; var value = props.value || ''; var state = this.props.store.getState(); DBG && console.warn('DBG:renderButton state', { state, props, value }); var active = (value === this.state.selected); return h('button', { className: "btn btn-xs btn-default" + ( active ? " active" : "" ), onClick: function (event) { DBG && console.warn('DBG:renderButton click', { value }); this.handleSetFilter(value); }.bind(this), }, option); }, renderLabel: function () { var label = this.props.label || this.props.name; return h('button', { className: "btn btn-xs btn-default", title: label, style: { color: '#31708f', backgroundColor: '#d9edf7', } }, [ h('i', { className: this.props.icon }), " Filtr relacji: ", ]); }, renderListSelected: function () { // @return array of react nodes DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::this.props.availableBackRefs (name:'+this.props.name+')', { state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs }); return this.state.selected.map(this.renderSelected); }, renderSelected: function (selected) { // @selected: { type: 'From' | 'To', filterKey, idInstance, primaryKey }, @return react node var filterKey = selected.filterKey; var type = selected.type; // From | To - backRef | childRef var idInstance = selected.idInstance; var primaryKey = selected.primaryKey; var namespace = idInstance; var label = "" + idInstance + "." + primaryKey + ""; if ('From' === type) { var foundInstanceInfo = this.props.availableBackRefs.filter(function (instanceInfo) { return ( parseInt(idInstance) === parseInt(instanceInfo.id) ); }); if (foundInstanceInfo.length > 0) label = 'z ' + foundInstanceInfo[0].label + "." + primaryKey; if (foundInstanceInfo.length > 0) namespace = foundInstanceInfo[0].namespace; } else if ('To' === type) { var foundInstanceInfo = this.props.availableChildRefs.filter(function (instanceInfo) { return ( parseInt(idInstance) === parseInt(instanceInfo.id) ); }); if (foundInstanceInfo.length > 0) label = 'do ' + foundInstanceInfo[0].label + "." + primaryKey; if (foundInstanceInfo.length > 0) namespace = foundInstanceInfo[0].namespace; } return h(P5UI__TableAjaxSpecialFilterRelationFrom, { filterKey: filterKey, label: label, namespace: namespace, primaryKey: primaryKey, store: this.props.store, actions: this.props.actions, }); }, renderBackRef: function () { // @return react node - button with dropdown to select primaryKey from parent instance + remove button if selected return null; }, renderCreateButton: function () { return h('button', { className: "btn btn-xs btn-default", title: "Dodaj nowy filtr relacji", onClick: this.handleCreate, }, [ h('i', { className: 'glyphicon glyphicon-plus' }) ]); }, render: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::render (name:'+this.props.name+')', { state: this.state, props: this.props }); return h('div', { className: "btn-group", style: { margin: '0 4px 0 0' } }, [ this.renderLabel(), ].concat( this.renderListSelected() ).concat([ this.renderCreateButton() ]) // Object.keys(this.props.values).map(this.renderButton) // ).concat( // [ // h('button', { // className: "btn btn-xs btn-default", // title: "Kasuj filtr", // disabled: !this.state.selected, // onClick: this.handleRemoveFilter, // style: { color: !this.state.selected ? '#bbb' : '#f00' } // }, [ // h('i', { className: "glyphicon glyphicon-remove" }) // ]) // ] ); } }); global['P5UI__TableAjaxSpecialFilterRelationFrom'] = createReactClass({ handleRemoveFilter: function (event) { this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.filterKey, '') ); }, render: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelationFrom::render (filterKey:'+this.props.filterKey+')', { state: this.state, props: this.props }); var refInfo = p5WfsRefFilter.parse(this.props.filterKey); // null | { type: 'From' | 'To', idInstance: int } return h('button', { className: "btn btn-xs btn-default active", title: "Powiązane" + ( 'From' === refInfo.type ? " z " : " do " ) + this.props.namespace + " " + this.props.primaryKey, // onClick: this.handleUpdate, // TODO: paste param }, [ this.props.label, h('i', { className: 'glyphicon glyphicon-remove', style: { color: '#f00', opacity: 0.5, marginLeft: "3px", }, onClick: this.handleRemoveFilter, }) ]); } }); global['P5UI__TableAjaxSpecialFilters'] = createReactClass({ // props.store: Redux store with state: { isLoading bool, selected array of strings } // props.actions: Redux store actions // props.namespace: PropTypes.string.isRequired // props.specialFilters: PropTypes.object.isRequired // props.specialFilters: // [Msgs] => stdClass Object // [icon] => glyphicon glyphicon-envelope // [label] => Wiadomości // [btns] => Array: // [WIADOMOSCI] => stdClass Object // [value] => HAS_MSGS // [NOWE] => stdClass Object // [value] => NEW_MSGS // [BRAK_WIAD.] => stdClass Object // [value] => NO_MSGS // [Status] => stdClass Object // [icon] => glyphicon glyphicon-question-sign // [btns] => Array: // [OCZEKUJACY] => stdClass Object // [value] => WAITING // [AKTYWNI] => stdClass Object // [value] => AKTYWNI // handleClick: function (event) { // DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::handleChange (ns:'+this.props.namespace+')', { checked: checked }); // this.props.store.dispatch( this.props.actions.unselectAll( this.props.namespace ) ) // }, renderSpecialFilter: function (key) { var props = this.props.specialFilters[key]; DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::renderSpecialFilter (ns:'+this.props.namespace+')', { key: key, props, state: this.state }); if ('RELATIONS' === props.type) { DBG && console.warn('DBG::P5UI__TableAjaxSpecialFilters::renderSpecialFilter TODO render RELATIONS filter (ns:'+this.props.namespace+')', { props, state: this.state }); return h(P5UI__TableAjaxSpecialFilterRelations, { store: this.props.store, actions: this.props.actions, name: key, icon: props.icon, label: props.label, availableBackRefs: props.availableBackRefs, availableChildRefs: props.availableChildRefs, }); } return h(P5UI__TableAjaxSpecialFilter, { store: this.props.store, actions: this.props.actions, name: key, icon: props.icon, label: props.label, values: props.btns, }); }, render: function () { DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::render (ns:'+this.props.namespace+')', { props: this.props, state: this.state }); return h('div', {}, Object.keys(this.props.specialFilters).map(this.renderSpecialFilter)) } }); global['P5UI__TableAjaxFieldCheckboxSearch'] = createReactClass({ // props.namespace: PropTypes.string.isRequired // props.fieldName: PropTypes.string.isRequired // props.store: Redux store with state: { isLoading bool, selected array of strings } // props.actions: Redux store actions getStateFromStore: function () { var state = this.props.store.getState(); // selected = || 2 // 0 - unchecked, 1 - checked, 2 - indeterminate var selected = ''; if (state.filter.has(this.props.fieldName)) { selected = state.filter.get(this.props.fieldName) } return { disabled: this.props.disabled ? true : false, selected: selected, active: ('YES' === selected || 'NO' === selected), // isLoading: (-1 !== state.loading.indexOf(this.props.fieldName)), // checked: (-1 !== state.selected.indexOf(this.props.fieldName)) }; }, getInitialState: function() { return this.getStateFromStore(); }, componentDidMount: function () { DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::componentDidMount (f:'+this.props.fieldName+')'); this.unsubscribe = this.props.store.subscribe(this.storeUpdated) }, componentWillUnmount: function () { this.unsubscribe() }, storeUpdated: function () { DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore()); this.setState(this.getStateFromStore()) }, shouldComponentUpdate: function (nextProps, nextState) { DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState}); return ( this.state.disabled !== nextState.disabled || this.state.selected !== nextState.selected ); }, handleChange: function (selected) { // selected: 0 - not checked, 1 - checked, 2 - indeterminate DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::handleChange (f:'+this.props.fieldName+')', { selected: selected, state: this.state }); if (0 === selected) { this.props.store.dispatch( this.props.actions.setFilter(this.props.fieldName, 'NO') ); } else if (1 === selected) { this.props.store.dispatch( this.props.actions.setFilter(this.props.fieldName, 'YES') ); } else if (2 === selected) { this.props.store.dispatch( this.props.actions.setFilter(this.props.fieldName, '') ); } }, mapSelectedToValue: function (selected) { switch (selected) { case 'YES': return 1; case 'NO': return 0; default: return 2; } }, render: function () { DBG && console.log('DBG::P5UI__TableAjaxFieldCheckboxSearch::render (f:'+this.props.fieldName+')', { props: this.props, state: this.state, state_sel: this.state.selected, sel: this.mapSelectedToValue(this.state.selected) }); return h('div', { style: { boxSizing: 'border-box', width: '100%', height: '21px', padding: '0 5px', borderTop: 0, borderBottom: '2px solid ' + ( this.state.active ? '#00ACCC' : 'transparent' ), }, }, [ h(p5UI__FieldCheckboxSearch, { size: 19, color: '#888', staticLabel: ["Pokaż:", "wszystkie,", "wybrane,", "niewybrane"].join("\n"), fieldName: this.props.fieldName, selected: this.mapSelectedToValue(this.state.selected), onChange: this.handleChange // checked: this.state.checked, // disabled: this.state.disabled, // isLoading: this.state.isLoading, }), ] ); } }); global['p5UI__FieldInputFilterSearch'] = createReactClass({ // props.fieldName: PropTypes.string.isRequired // props.type: PropTypes.string.isRequired // props.store: Redux store with state: { } // props.actions: Redux store actions // props.disabled: PropTypes.bool // props.lagacyProps: PropTypes.object getStateFromStore: function () { var storeState = this.props.store.getState(); return { value: storeState.filter.get(this.props.fieldName) || '', active: storeState.filter.has(this.props.fieldName) }; }, getInitialState: function() { return this.getStateFromStore(); }, componentDidMount: function () { DBG && console.log('DBG::p5UI__FieldInputFilterSearch::componentDidMount (f:'+this.props.fieldName+')'); this.unsubscribe = this.props.store.subscribe(this.storeUpdated) }, componentWillUnmount: function () { this.unsubscribe() }, storeUpdated: function () { DBG && console.log('DBG::p5UI__FieldInputFilterSearch::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore()); this.setState(this.getStateFromStore()) }, shouldComponentUpdate: function (nextProps, nextState) { DBG && console.log('DBG::p5UI__FieldInputFilterSearch::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState}); return ( this.state.value !== nextState.value || this.state.active !== nextState.active ); }, handleChange: function (event) { // handleChange: function (event) { var value = event.target.value; DBG && console.log('DBG::p5UI__FieldInputFilterSearch::handleChange (f:'+this.props.fieldName+')', { value }); this.setState({ value: value }); this.props.onChange(this.props.fieldName, value); // this.props.store.dispatch( this.props.actions.toggle( this.props.namespace, this.props.primaryKey, checked ) ) }, render: function () { DBG1 && console.log('DBG::p5UI__FieldInputFilterSearch::render (f:'+this.props.fieldName+',v:'+this.state.value+')', { props: this.props, state: this.state }); switch (this.props.type) { case "number": case "date": case "bool": case "p5:price": case "p5:www_link": case "p5:string": case "string": return this.renderInput(); case "special": return this.renderEmpty(); case "simpleLink": return this.renderEmpty(); case "geom": return this.renderInput(); case "none": return this.renderEmpty(); case "ref": return this.renderEmpty(); default: return this.renderEmpty(); } }, renderEmpty: function () { return h('div', {}, " "); }, renderInput: function () { return h('input', { className: "filter", // + ( this.state.active ? " filter-active" : "" ), placeholder: !this.props.disabled ? "%" : "", type: "text", disabled: this.props.disabled || false, style: { boxSizing: 'border-box', width: '100%', height: '21px', borderTop: 0, borderBottom: '2px solid ' + ( this.state.active ? '#00ACCC' : 'transparent' ), }, value: this.state.value, onChange: this.handleChange }); } }); global['p5UI__TableAjaxClearAllFilters'] = createReactClass({ // props.store: Redux store with state: { } // props.actions: Redux store actions getStateFromStore: function () { var storeState = this.props.store.getState(); return { isFiltersEmpty: ( 0 === storeState.filter.size && 0 === storeState.specialFilter.size ) }; }, getInitialState: function() { return this.getStateFromStore(); }, componentDidMount: function () { DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::componentDidMount (f:'+this.props.fieldName+')'); this.unsubscribe = this.props.store.subscribe(this.storeUpdated) }, componentWillUnmount: function () { this.unsubscribe() }, storeUpdated: function () { DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::storeUpdated (f:'+this.props.fieldName+')', this.getStateFromStore()); this.setState(this.getStateFromStore()) }, // shouldComponentUpdate: function (nextProps, nextState) { // DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::shouldComponentUpdate (f:'+this.props.fieldName+')', { state: this.state, nextState}); // return ( // this.state.value !== nextState.value // || this.state.active !== nextState.active // ); // }, handleClick: function (event) { DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::handleClick (clearAllFilters)'); this.props.store.dispatch( this.props.actions.clearAllFilters() ) }, render: function () { DBG && console.log('DBG::p5UI__TableAjaxClearAllFilters::render (clearAllFilters)', { props: this.props, state: this.state }); return h('i', { title: this.props.title || "Kasuj wszystkie filtry", className: "glyphicon glyphicon-remove", style: Object.assign( { opacity: '0.5', lineHeight: '20px', padding: '0 3px', cursor: 'pointer', }, this.state.isFiltersEmpty ? { color: '#777' } : { color: '#f00' } ), onClick: this.handleClick }); } }); var TableAjax = function() { var priv = {}; //private api var publ = {}; //public api priv.options = {}; var defaults = { namespace: '', url: '', //webservice url urlPost: false, //use POST instead of GET selectAllByFilterUrl: '', getCsvTheGeomAjaxUrl: '', removeTheGeomAjaxUrl: '', moreFunctionsCellAjaxUrl: '', editInlineSaveUrl: '', theGeomSaveUrl: '', pageSizeSave: '', hiddenColsSaveUrl: '', editInlineUrl: '', addUserTableFilterAjaxUrl: '', rmUserTableFilterAjaxUrl: '', hasAdditionalLayers: 0, labelHtml: '', debug: false, //prints debug info to console filter: false, //show filter row filterInit: false,// init filters data forceFilterInit: false, columnPicker: false, //show columnpicker checkboxes: false, //show body checkboxes actions: '', //holds action links pageSize: 10, //current pagesize pageSizes: [10, 20, 30, 40, 50, 'All'], //available pagesizes hidePagerOnEmpty: false, //removes pager if no rows types: { //type specific options string: {}, number: {}, bool: {}, date: {} }, rowFunctions: false, tblFunctions: false, specialFilterFunctions: false, filtersClean: false, router: false, longDesc: false, exportFields: [], mapEditor: false, // mapEditor visible or not mapEditorContainer: 'window' // 'window' or 'dock' }; var _reactUITableNode; // TODO: react table node var _uiNodeCont; // container holding table var _uiNodeSelectedInfo; var _uiNodeSpecialFilters; var _uiNodeFooterInfo; var _uiNode$Table; // the table node var _head; // table header var _headSort; // table header sorting row var _headFilter; // table header columns filter row var _headSpecialFilter; // table header special filter row var _bodyNode; // table body var _body; // TODO: table body need render? var _foot; // table footer var _inlineEditBox; // inline edit box with form var _popoverCell; // inline popover cell var _popoverCellCurrent; // inline popover cell var _popoverCellAjaxXhr; var _mapEditor; // map editor node var _mapEditorWrap; // map editor wrapper node var _mapEditorDialog; // map editor jquery ui dialog node var _state = {};// state - to replace variables below (date, ...) var _data; //columns and rows var _totalPages; // total pages var _currDpOp; // clicked datetimepicker operator var _filterTimeout; // timer for delayed filtering var _checkToggleChecked = false; // check-all toggle state var _exportFieldsSelect = {}; var _tableWidth; var _fieldWidgets = {}; /* initialize the plugin. */ priv.init = function() { _uiNodeCont = priv.options.id; //
1) { for (var i=1; i
').appendTo(_uiNodeCont); _head = $('').prependTo(_uiNode$Table); _headSort = $('').prependTo(_head); _headFilter = $('').appendTo(_head); _bodyNode = $('').insertAfter(_head); $('').insertAfter(_bodyNode); _foot = $('').insertAfter(_uiNodeCont); var footToolbar = $('').appendTo(_foot); _uiNodeFooterInfo = document.createElement('div') // .tblAjax__head__specialFilter _uiNodeFooterInfo.setAttribute('class', "tblAjax__footer__toolbar__info foot-info"); _uiNodeFooterInfo.style.float = "left"; _uiNodeFooterInfo.style.padding = "0 20px 0 0"; $(_uiNodeFooterInfo).appendTo(footToolbar); $('').appendTo(footToolbar); $('').appendTo(footToolbar); $('').appendTo(footToolbar); $('').appendTo(footToolbar); $('').appendTo(footToolbar); _mapEditorWrap = $('').insertAfter(_foot); _mapEditor = $('
').appendTo(_mapEditorWrap); _popoverCell = $('').insertAfter(_foot); $('
').insertAfter(_foot); _uiNodeSelectedInfo = document.createElement('div') _uiNodeSpecialFilters = document.createElement('div') // .tblAjax__head__specialFilter var topWrap = document.createElement('div') var topWrapLeft = document.createElement('div') var topWrapRight = document.createElement('div') topWrap.appendChild(topWrapLeft) topWrap.appendChild(topWrapRight) topWrapLeft.style.width = '' + priv.getStickyColsSumWidth() + 'px' topWrapLeft.style.padding = '4px' topWrapLeft.style.float = 'left' topWrapLeft.style.fontSize = '12px' topWrapLeft.style.lineHeight = '22px' topWrapRight.style.float = 'left' topWrapRight.style.padding = '4px' topWrapLeft.appendChild(_uiNodeSelectedInfo) topWrapRight.appendChild(_uiNodeSpecialFilters) _uiNodeCont.parentNode.insertBefore(topWrap, _uiNodeCont) priv.renderInlineEditBox();// .tblAjax__inlineEditBox _foot = undefined; _head = undefined; _body = undefined; _headSort = undefined; _headFilter = undefined;// TODO: refactor }; priv.renderTable = function() { if (!_state.colsSorted) return; DBG && console.warn('DBG:renderTable: ', { _head, _headSort, _headFilter, _headSpecialFilter }); if (!_head) { _headSort = undefined; _headFilter = undefined; _headSpecialFilter = undefined; _head = _uiNode$Table.find('thead'); } if (!_headSort) { priv.renderTableTheadSort(); _headSort = true; } if (!_headFilter && priv.options.filter) { priv.renderTableTheadFilter(); _headFilter = true; } if (!_headSpecialFilter && priv.options.specialFilterFunctions) { priv.renderHeadSpecialFilters(); _headSpecialFilter = true; } if (!_body) { DBG && console.log('DBG:renderTable !_body', { _bodyNode }) // _uiNode$Table.find('tbody').remove(); // _bodyNode = $('').insertAfter(_head); // _uiNode$Table.find('tbody > tr').remove(); _bodyNode.find('tr').remove(); // find out what rows to show next... var rowsAdded = 0; // slice out the chunk of data we need and create rows $.each(_data.rows, function(index, props) { var rowNode = priv.renderRow(props); if (rowNode) rowNode.appendTo(_bodyNode); rowsAdded++; if (rowsAdded >= priv.options.pageSize) { // enough rows created return false; } }); if (_state.page == 1) { _totalPages = Math.ceil(_data.total / priv.options.pageSize); } if (_state.page == _totalPages) { // pad with empty rows if we're at last page. while (rowsAdded < priv.options.pageSize) { var rowNode = priv.renderRowEmptyNode(); if (rowNode) rowNode.appendTo(_bodyNode); rowsAdded++; } } } if (!_foot) { priv.renderTableTfoot(); priv.renderFooter(); } _foot = $(_uiNodeCont).next('.foot'); priv.uiFixStickyCols(); if (_data.total == 0 && priv.options.hidePagerOnEmpty) { $('.btn-toolbar', _foot).remove(); } if (priv.options.debug || DBG) console.log('table created'); if (typeof priv.options.tableCreated == 'function') { priv.options.tableCreated.call(_uiNode$Table.get(0), {table: _uiNode$Table.get(0)}); } }; // TODO: priv.renderFieldWidget_InlineEdit = function(fldName, value) {} // TODO: priv.renderFieldWidget_FormField = function(fldName, value) {} // @usage: priv.renderFieldWidget_TableCell(fldName, val, rowPK, row) priv.renderFieldWidget_TableCell = function(fldName, value, rowPK, row) { var renderFieldAsTableCell = priv.getFieldWidget_TableCell(fldName); if (!renderFieldAsTableCell) return null; return renderFieldAsTableCell(value, rowPK, row); }; priv.registerFieldWidget = function(type, fldName, fieldProps) { var fieldWidget = null; switch (type) { case "date":// @return Element - TODO: not used yet fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps; // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); return val; } }(fldName, fieldProps)); break; case "bool":// @return Element - TODO: not used yet fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps; // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); fldNode = document.createElement('input'); fldNode.setAttribute('type', 'checkbox'); if (val) fldNode.setAttribute('checked', 'checked'); fldNode.setAttribute('disabled', 'disabled'); fldNode.appendChild(document.createTextNode(val)); return fldNode; } }(fldName, fieldProps)); break; case "number":// @return String - TODO: not used yet fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps, _fractionDigits = _.get(_fieldProps, 'fractionDigits', 2); // console.log('FieldWidget: generate function to render field('+_fieldName+') _fractionDigits('+_fractionDigits+')', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); if ('' === val) return ''; // is nullable if ('*****' === val) return val; // enumeration // fractionDigits // maxExclusive // maxInclusive // minExclusive // minInclusive // pattern // totalDigits // whiteSpace val = Number(val); return ((val || 0) % 1 === 0)? val : val.toFixed(_fractionDigits); } }(fldName, fieldProps)); break; case "string":// @return String fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps, _format = _.get(_fieldProps, 'format', '{0}'); // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); return p5Utils__format(_format, [val]); } }(fldName, fieldProps)); break; case "p5:price":// @return String fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps, _format = _.get(_fieldProps, 'format', '{0}'); // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); return p5Utils__format(_format, [val]); } }(fldName, fieldProps)); break; case "p5:string":// @return String fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName; var _fieldProps = fieldProps; var _formatDefault = _.get(_fieldProps, 'format', null); var _formatByValue = _.get(_fieldProps, 'formatByValue', null); var _formatEmpty = _.get(_fieldProps, 'formatEmpty', null); var _aliasMap = _.get(_fieldProps, 'aliasMap', null); return function(val, fieldPK, row) { var outValue = ''; if (_formatByValue && val in _formatByValue) { outValue = p5Utils__format(_formatByValue[val], [val]) } else if (val && _formatDefault) { outValue = p5Utils__format(_formatDefault, [val]) } else if (!val && _formatEmpty) { outValue = p5Utils__format(_formatEmpty, []) } // console.log('p5:string value', val, '_aliasMap', _aliasMap) if (_aliasMap) { Object.keys(_aliasMap).map(function (mapKey) { var mapField = _aliasMap[mapKey] if (undefined !== row[mapField]) { outValue = outValue.replace(new RegExp('\{' + mapKey + '\}', 'g'), row[mapField]); } }) } return outValue; } }(fldName, fieldProps)); break; case "p5:www_link":// @return Element fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps; // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); var link = '', a = null, dbg = false; if (!val.length) return ''; if ('index.php' == val.substr(0, 9) || 'procesy5.php' == val.substr(0, 12)) { link = window.location.protocol + '//' + window.location.hostname link += window.location.pathname.split('/').slice(0, -1).join('/') link += '/' + val } else { if ('http' == val.substr(0, 4)) link = val //else if ('ftp' == val.substr(0, 3)) else link = 'http://' + val } var linkErrors = validate({www_link: link}, {www_link: {url: true}}); if (linkErrors) { // if(dbg)console.log('linkErrors for (' + link +')', linkErrors); return val; } fldNode = document.createElement('a'); fldNode.setAttribute('href', link); fldNode.setAttribute('target', '_blank'); fldNode.appendChild(document.createTextNode(val)); return fldNode; } }(fldName, fieldProps)); break; case "special": fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName; var _fieldProps = fieldProps; var _format = _.get(_fieldProps, 'format', '{0}'); var _aliasMap = _.get(_fieldProps, 'aliasMap', null); // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps, 'row', row); var format = _format; if (_aliasMap) { Object.keys(_aliasMap).map(function (mapKey) { var mapField = _aliasMap[mapKey] if (undefined !== row[mapField]) { format = format.replace(new RegExp('\{' + mapKey + '\}', 'g'), row[mapField]); } // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') _aliasMap:', _aliasMap, 'row['+mapField+']', row[mapField], 'converted val:', val); }) } return p5Utils__format(format, [val]); } }(fldName, fieldProps)); break; case "simpleLink": fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps, _format = _.get(_fieldProps, 'format', '{0}'); // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value('+val+') ', fieldProps); var valLink = String(val); if (undefined !== _fieldProps._tsRetId && (0 === _fieldProps._tsRetId || '0' === _fieldProps._tsRetId || null === _fieldProps._tsRetId) && undefined !== _fieldProps._tsSimpleLink) { valLink = _fieldProps._tsSimpleLink.format; $.each(_fieldProps._tsSimpleLink.aliasMap, function(i, v) { // console.log('simpleLink aliasMap fldName:', fldName, 'i:', i, 'v:', v, 'row['+v+']', row[v], 'val', val, 'typeof val', typeof val); if (undefined !== row[v]) { var _itemValue = row[v]; if (fldName == 'LINK_PROBLEMS' && row[v]) _itemValue = _itemValue.replace(/"/g, '%22').replace(/&/g, '%26'); valLink = valLink.replace(new RegExp('\{' + i + '\}', 'g'), _itemValue); } }); } return p5Utils__format(_format, [valLink]); } }(fldName, fieldProps)); break; case "gml:PolygonPropertyType": case "gml:LineStringPropertyType": case "gml:PointPropertyType": case "p5Type:polygon": case "p5Type:lineString": case "p5Type:point": case "geom": fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps, _format = _.get(_fieldProps, 'format', '{0}'); // console.log('FieldWidget: generate function to render field('+_fieldName+') ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: run function to render field('+_fieldName+') with value('+val+') ', fieldProps); // console.log('FieldWidget: test priv', priv); var node = jQuery(''); node.TableAjaxGeomField({ recordID: fieldPK, fieldValue: val, hasValueClassName: 'cell-mapfld-hasValue', linkClassNamePrefix: 'cell-mapfld', linkSelectClassName: 'select', linkSelectAddClassNames: 'glyphicon glyphicon-map-marker', getCsvUrl: priv.options.getCsvTheGeomAjaxUrl, linkGetCsvAddClassNames: 'glyphicon glyphicon-download', linkRemoveClassName: 'remove', linkRemoveAddClassNames: 'glyphicon glyphicon-remove', onSelect: function(recordID, geomShape) { if (priv.options.debug || DBG) console.log('recordID:', recordID, 'geomShape:', geomShape); priv.mapEditorShow(); _mapEditor.TableAjaxMapSelectRecord(recordID, geomShape); }, onRemove: function(geomField, recordID, geomShape) { if (confirm('Czy usunąć obiekt z mapy dla rekordu ' + recordID + '?')) { if (!recordID) return; var selectedRecordId = recordID; superagent .post(priv.options.removeTheGeomAjaxUrl) .type('json') // header ĺapplication/x-www-form-urlencoded' requires type('form'); .send({ ID: recordID, namespace: priv.options.namespace }) .set('Accept', 'application/json') .end(function(err, res) { if(priv.options.debug)console.log('DBG: res:', res, 'res.body:', res.body); var payload; if (err || !res.ok || 'application/json' !== res.type) { payload = {type: 'warning', msg: res.body.msg || 'Wystąpiły błędy', body: res.body}; } else { payload = {type: 'success', msg: res.body.msg || '', body: res.body}; } p5UI__notifyAjaxCallback(payload); var data = res.body; if (data && data.record && data.record.the_geom) { if (priv.options.debug || DBG) console.log('data.record.the_geom:2:', data.record.the_geom); geomField.setValue(data.record.the_geom); } else if (data && data.record) { if (priv.options.debug || DBG) console.log('data.record.the_geom:2:', data.record.the_geom); geomField.setValue(data.record.the_geom); } _mapEditor.TableAjaxMapRefresh(); }); } } }); return node; } }(fldName, fieldProps)); break; case "ref": fieldWidget = (function(fldName, fieldProps) { var _fieldName = fldName, _fieldProps = fieldProps; // console.log('FieldWidget: generate function to render field('+_fieldName+') fieldProps: ', fieldProps); return function(val, fieldPK, row) { // console.log('FieldWidget: pk('+fieldPK+') run function to render field('+_fieldName+') with value: ', val, ', fieldProps: ', fieldProps); // if (val.length > 5) return '('+val.length+')' + printFirst5 + '...' => open more info return _.map(val, function(v) { if (!v || !v.xlink) return ''; var idRemote = v.xlink.split('.').pop() var nsRemote = v.xlink.split(':').pop().split('.').shift() var seLink = URI_BASE + 'index.php?_route=ViewTableAjax&namespace=' + fieldProps.xsdRefNsPrefix.replace(/__x3A__/g, '/') + '/' + nsRemote + '#EDIT/' + idRemote; var wfsLink = fieldProps.xsdRefUri + '#' + fieldProps.xsdRefType + '.' + idRemote; return '' + idRemote + ''; }).join(' '); } }(fldName, fieldProps)); break; } _fieldWidgets[fldName] = fieldWidget; }; priv.getFieldWidget_TableCell = function(fieldName) { var props = _data.cols[fieldName], type = null, renderFieldAsTableCell = null; if (!props) return null; type = _.get(props, 'type'); if (!type) type = 'string';// TODO: throw Exception? / default string renderFieldAsTableCell = _.get(_fieldWidgets, fieldName); if (renderFieldAsTableCell) return renderFieldAsTableCell; priv.registerFieldWidget(type, fieldName, props); renderFieldAsTableCell = _.get(_fieldWidgets, fieldName); if (!renderFieldAsTableCell) throw "Field type '" + type + "' not implemented"; return renderFieldAsTableCell; }; priv.renderRow = function(props) { var rowNode = $(''); var rowPK = (_state.primaryKey in props) ? props[_state.primaryKey] : null; var cellNode; var columnName, columnProps, val, cellCnt, format, showTooltip, fldWidgetNode; var dbg = (priv.options.debug || DBG); // ondrop="drop_handler(event);" ondragover="dragover_handler(event);" ondragend="dragend_handler(event);" rowNode.attr('ondrop', "p5TA_onDrop(event, '"+rowPK+"', '"+priv.options.namespace+"')") rowNode.attr('ondragover', "p5TA_onDragOver(event, this, '"+rowPK+"', '"+priv.options.namespace+"')") rowNode.attr('ondragend', "p5TA_onDragEnd(event, this, '"+rowPK+"', '"+priv.options.namespace+"')") if (priv.options.rowFunctions || priv.options.filtersClean) { cellNode = priv.renderCellRowFunctions(priv.options.rowFunctions, rowPK, props); cellNode.addClass('text-right stickyCol stickyCol1'); cellNode.appendTo(rowNode); } //create checkbox if (_state.primaryKey && priv.options.checkboxes) { // row checkbox cell var checkable = props['checkable'] === false ? 'disabled' : ''; cellNode = $('').appendTo(rowNode); ReactDOM.render( h(P5UI__TableAjaxRowCheckbox, { namespace: priv.options.namespace, primaryKey: rowPK, store: priv.options.selectedStore, actions: priv.options.selectedActions }), cellNode.get(0) ); } if (_state.primaryKey) rowNode.data('unique', rowPK); //create cells for (var i = 0; i < _state.colsSorted.length; i++) { columnName = _state.colsSorted[i]; columnProps = _data.cols[columnName]; val = ''; if (!columnProps) continue; if (columnProps.hidden) continue;// TODO: "unique" is hidden showTooltip = true; val = props[columnName]; cellNode = $('').appendTo(rowNode); if (i === 1) cellNode.addClass('stickyCol stickyCol3');// primaryKey(ID) if (i !== 1) cellNode.on('dblclick', {id:rowPK, col:columnName}, priv.rowDblClicked); cellCnt = (i === 1)? '
' : ''; cellCnt = $(cellCnt).appendTo(cellNode);// fix dblclick for copy cellNode.data('column', columnName); if (val === undefined) continue; format = _.get(columnProps, 'format', '{0}'); // test use field widgets fldWidgetNode = priv.renderFieldWidget_TableCell(columnName, val, rowPK, props); if (fldWidgetNode || fldWidgetNode === 0) { cellCnt.empty(); cellCnt.append(fldWidgetNode); } else if (fldWidgetNode === '') { cellCnt.empty(); } else { console.log('TODO: !FieldWidget for row.pk('+rowPK+') col('+columnName+') typeof fldWidgetNode(' + (typeof fldWidgetNode) + ') columnProps', columnProps, 'fldWidgetNode', fldWidgetNode, 'value', props[columnName]); }// test fld widgets if (columnProps._tsRetId) { showTooltip = false; if (columnProps._tsRetId > 0) { cellCnt.on('click', {id:rowPK, col:columnName, friendly:columnProps.friendly, value:p5Utils__format(format, [val])}, priv.popoverCellTypeSpecial); } } if ('ref' === columnProps.type) showTooltip = false; if ('ref' === columnProps.type) cellNode.css('padding', "3px") if ('ref' === columnProps.type && (priv.options.debug || DBG)) console.log('renderRow rowPK('+rowPK+') columnProps', columnProps) // if ('ref' === columnProps.type) cellNode.html('przeglądaj') if ('ref' === columnProps.type) { cellNode.html('przeglądaj') } if (columnProps.xsdType && 'xsd:base64Binary' === columnProps.xsdType) { cellCnt.empty(); if (val) { cellCnt.append(''+"otwórz"+''); } else { cellCnt.append('N/S;'); } } if (i > 1 && priv.options.longDesc) {// TODO: use better check for columns: functions and pk cellNode.addClass('tbl-short-txt'); if (showTooltip) { cellCnt.tooltip({title: cellCnt.text(), placement: 'left'}); } } } return rowNode; }; priv.renderCellRowFunctions = function(rowFunctions, rowPK, rowProps) { var cellNode = $(''), keys = Object.keys(rowFunctions), total = keys.length, moreFuncBtnNode, moreFunctions = [], idx ; if (priv.options.debug || DBG) console.log('TableAjax::renderCellRowFunctions: rowFunctions', rowFunctions); idx = keys.indexOf('hist'); if (idx !== -1) { histFunc = keys.splice(idx, 1); keys.push('hist'); } moreFunctions = keys.splice(3); keys.forEach(function(key) { var funObj = rowFunctions[key], funcNode = p5UI_TableAjax_generateFunctionNode(funObj, rowPK, {ico: true, label: false}) ; funcNode.appendTo(cellNode); }); moreFuncBtnNode = $(' '); moreFuncBtnNode.on('click', {rowPK: rowPK, rowFunctions: rowFunctions, more: moreFunctions}, priv.popoverCellMoreFunctions); moreFuncBtnNode.appendTo(cellNode); return cellNode; }; priv.popoverCellMoreFunctions = function(e) { e.preventDefault(); e.stopPropagation(); if (!e.data || !e.data.rowPK) { if (priv.options.debug || DBG) console.log('NO data'); return false; } if (priv.options.debug || DBG) console.log('TableAjax::popoverCellMoreFunctions: rowPK', e.data.rowPK, 'moreFunctions', e.data.more, 'rowFunctions', e.data.rowFunctions); var lastId = _popoverCell.data('rowid'); var lastCol = _popoverCell.data('col'); var rowPK = e.data.rowPK; var moreFunctions = e.data.more; var rowFunctions = e.data.rowFunctions; var funcListNode; if (lastId == e.data.rowPK && lastCol == 'moreFunctions') { //_popoverCellCurrent.popover('toggle'); return; } if (_popoverCellCurrent) { _popoverCellCurrent.popover('destroy'); } _popoverCell.data('rowid', rowPK); _popoverCell.data('col', 'rowFunctions'); _popoverCell.empty(); funcListNode = $('').appendTo(_popoverCell); moreFunctions.forEach(function(funcName) { var funcItemNode = $('
  • ').appendTo(funcListNode), funObj = rowFunctions[funcName], funcNode = p5UI_TableAjax_generateFunctionNode(funObj, rowPK, {ico: true, label: true}) ; funcNode.addClass('func_name-' + funcName); funcItemNode.append(funcNode); }); if (3 === priv.options.namespace.split('/').length) { // if namesapce is AntAcl [ and has ref fields or back ref ] var funcItemNode = $('
  • ').appendTo(funcListNode) var funObj = { ico: 'glyphicon glyphicon-random', label: 'Przeglądaj powiązania', href: 'index.php?_route=RefGraph&namespace=' + priv.options.namespace + '&primaryKey=' + rowPK, // onclick: function (e) { // TODO: open in // console.log('TODO: przeglądaj powiązania') // } } var funcNode = p5UI_TableAjax_generateFunctionNode(funObj, rowPK, { ico: true, label: true }) funcItemNode.append(funcNode); } _popoverCell.append('
    '); _popoverCellCurrent = jQuery(e.currentTarget); // title : 'title ' var opts = { container: 'body', placement: 'right', trigger: 'click', template: '', html: true, content: _popoverCell.html() } opts.template += ''; _popoverCellCurrent.popover(opts); _popoverCellCurrent.on('shown.bs.popover', function(e) { if (!_popoverCellCurrent) return; var popoverNodeId = _popoverCellCurrent.attr('aria-describedby'); if (!popoverNodeId) return; var popover$Node = jQuery('#' + popoverNodeId); if (!popover$Node.length) return; var arrow$Node = popover$Node.children('.arrow'); if (arrow$Node.length) { var posTop = parseFloat(arrow$Node.css('top')); arrow$Node.css('top', '' + posTop + 'px') } popover$Node.find('.popoverCellContent').html('

    Pobieranie funkcji...

    '); priv.ajaxLoadMoreFunctionsCell(rowPK); }); _popoverCellCurrent.popover('show'); return; }; priv.ajaxLoadMoreFunctionsCell = function(rowPK) { var dbg = (priv.options.debug || DBG); if (_popoverCellAjaxXhr) { _popoverCellAjaxXhr.abort(); } _popoverCellAjaxXhr = $.ajax({ type: 'GET', url: priv.options.moreFunctionsCellAjaxUrl + '&ID=' + rowPK, dataType: 'json', contentType: "application/json; charset=utf-8", data: '' }) .done(function(data, textStatus, jqXHR){ if (data && 'success' === data.type) { var popoverCellContent, rowFunctions = [], funcNodesToUpdate = [] ; if (data.rowFunctions && data.rowFunctions.length > 0) { rowFunctions = data.rowFunctions; } if (rowFunctions.length > 0) { var popoverCellContent = $('

    '); rowFunctions.forEach(function(funObj) { var funcNode = p5UI_TableAjax_generateFunctionNode(funObj, rowPK, {ico: true, label: true}); if (funObj.id) { funcNodesToUpdate.push({id: funObj.id, node: funcNode}); } else { var funcItemNode = $('
  • ').appendTo(popoverCellContent); funcItemNode.append(funcNode); } }); } else { popoverCellContent = '

    Brak dodatkowych funkcji

    '; } //_popoverCell.append(popoverCellContent);// cache if (_popoverCellCurrent) { var popoverNodeId = _popoverCellCurrent.attr('aria-describedby'); if (popoverNodeId) { var popoverNode = jQuery('#' + popoverNodeId), popoverCntNode = popoverNode.find('.popoverCellContent'), popoverRowFuncNode = popoverNode.find('.popoverRowFunctions'); ; {// fix generated row Functions by loaded from ajax call if(dbg) console.log('popoverRowFunctions. popoverRowFuncNode', popoverRowFuncNode); if(dbg) console.log('popoverRowFunctions. funcNodesToUpdate', funcNodesToUpdate); funcNodesToUpdate.forEach(function(funcNodeInfo) { var className = 'func_name-' + funcNodeInfo.id, foundRowFuncNode = null ; if(dbg) console.log('popoverRowFunctions. funcNodesToUpdate loop:', funcNodeInfo); popoverRowFuncNode.find('li > a').each(function(ind, n) { var n$ = $(n); if(dbg) console.log('popoverRowFunctions loop(',ind,'):', n, 'data(func_name)', n$.data('func_name'), 'data', n$.data()); if (n$.hasClass(className)) { foundRowFuncNode = n$; } }); if (foundRowFuncNode) { foundRowFuncNode.replaceWith(funcNodeInfo.node); } else { var funcItemNode = $('
  • ').appendTo(popoverCellContent); funcItemNode.append(foundRowFuncNode); } }); } popoverCntNode.empty().append(popoverCellContent); if (rowFunctions.length <= 0) { popoverCntNode.find('p.text-muted').delay(600).hide(300); } } } } }); }; priv.renderRowEmptyNode = function() { var rowNode = $(''); if (priv.options.rowFunctions || priv.options.filtersClean) { $(' ').appendTo(rowNode); } if (_state.primaryKey && priv.options.checkboxes) { var cellNode = $('').appendTo(rowNode); } for (var i = 0; i < _state.colsSorted.length; i++) { var columnName = _state.colsSorted[i], columnProps = _data.cols[columnName] ; if (!columnProps) return; if (columnProps.hidden) continue;// "unique" is hidden - TODO: rm "unique" from _state.colsSorted ? if (i == 1) {// TODO: 1 is pk - use better check $(' ').appendTo(rowNode); } else { $(' ').appendTo(rowNode); } } return rowNode; }; priv.renderTableTheadSort = function() { DBG && console.log('DBG:renderTableTheadSort', { '_state._currSortCol': _state._currSortCol, '_state._currSortFlip': _state._currSortFlip }); var nodeClass = 'tblAjax__' + 'head__sort' var currentNode = _uiNode$Table.find('thead').find('.' + nodeClass) var node = $('') if (priv.options.tblFunctions || priv.options.filtersClean) { var headCell = $('').appendTo(node) $.map(priv.options.tblFunctions, function (funObj, funName) { var funHtml = $('') funHtml.attr('href', funObj.href || '#') if (funObj.title) funHtml.attr('title', funObj.title) if (funObj.icon) funHtml.html(' ') if (funObj.method && priv[funObj.method] && typeof priv[funObj.method] == 'function') { funHtml.on('click', priv[funObj.method]) } funHtml.appendTo(headCell) }) } if (_state.primaryKey && priv.options.checkboxes) { var headCell = $('').appendTo(node); ReactDOM.render( h(P5UI__TableAjaxRowCheckbox, { namespace: priv.options.namespace, primaryKey: 'select-all', store: priv.options.selectedStore, actions: priv.options.selectedActions }), headCell.get(0) ); } for (var i = 0; i < _state.colsSorted.length; i++) { var column = _state.colsSorted[i] var props = _data.cols[column] DBG && console.log('DBG:renderTableTheadSort loop', { column, props }); if (props.hidden) continue; var headCell = $('').appendTo(node) if (_state.primaryKey === column) headCell.addClass('stickyCol stickyCol3') ReactDOM.render( h(P5UI__TableAjaxSortableLabel, { namespace: priv.options.namespace, isSortable: (props.type != 'special' && props.type != 'geom' && props.type != "simpleLink" && props.type != "ref"), // TODO: props.isSortable fieldName: column, fieldProps: props, store: priv.options.filterStore, actions: priv.options.filterActions }), headCell.get(0) ); if (column !== _state.primaryKey) { var hideColBtn = $('') hideColBtn.on('click', {column: column}, priv.columnHideClicked) hideColBtn.appendTo(headCell) } } currentNode.replaceWith(node) }; priv.renderHeadSpecialFilters = function() { DBG && console.warn('DBG:priv.renderHeadSpecialFilters...', { 'priv.options.specialFilterFunctions': priv.options.specialFilterFunctions }); if (!priv.options.specialFilterFunctions) { return; } ReactDOM.render( h(P5UI__TableAjaxSpecialFilters, { store: priv.options.filterStore, actions: priv.options.filterActions, specialFilters: priv.options.specialFilterFunctions, namespace: priv.options.namespace, }), _uiNodeSpecialFilters ); }; priv.renderTableTheadFilter = function() { DBG && console.log('DBG::renderTableTheadFilter...'); var nodeClass = 'tblAjax__' + 'head__filter', currentNode = _uiNode$Table.find('thead').find('.' + nodeClass), node; // currentNode.find('i').tooltip('hide'); node = $(''); //_head.find(".filter").remove(); //_headFilter = $('').appendTo(_head); var headCell; var elem; var placeHolder = ''; var tooltip = ''; //create the functions column if (priv.options.rowFunctions || priv.options.filtersClean) { var headCell = $('').appendTo(node); headCell.css({padding: '0'}); if (priv.options.filtersClean) { ReactDOM.render( h(p5UI__TableAjaxClearAllFilters, { store: priv.options.filterStore, actions: priv.options.filterActions }), headCell.get(0) ); } } //create the filter checkbox if (_state.primaryKey && priv.options.checkboxes) { // tooltip = priv.options.types.bool.filterTooltip || 'Pokaż tylko:
    nieokreślony,
    zaznaczony,
    niezaznaczony'; headCell = $('').appendTo(node); ReactDOM.render( h(P5UI__TableAjaxFieldCheckboxSearch, { namespace: priv.options.namespace, fieldName: ( priv.options.checkboxIdContext ? '@sel_' + priv.options.checkboxIdContext : '@selected' ), store: priv.options.filterStore, actions: priv.options.filterActions }), headCell.get(0) ); } //create the column filters for (var i = 0; i < _state.colsSorted.length; i++) { var column = _state.colsSorted[i]; var props = _data.cols[column]; tooltip = props.filterTooltip === true ? undefined : props.filterTooltip === false ? '' : props.filterTooltip; placeHolder = props.placeHolder === true ? undefined : props.placeHolder === false ? '' : props.placeHolder; if (props.hidden) continue; headCell = $('').appendTo(node); headCell.css({padding: '0'}); if (i == 1) headCell.addClass('stickyCol stickyCol3'); ReactDOM.render( h(p5UI__FieldInputFilterSearch, { disabled: (priv.options.forceFilterInit && undefined !== priv.options.forceFilterInit[column]), fieldName: column, type: props.type, lagacyProps: props, // TODO: use ony required like xsdType // xsdType: props.xsdType, store: priv.options.filterStore, onChange: function (fieldName, value) { priv.options.filterStore.dispatch( priv.options.filterActions.delayFilter(fieldName, value) ); } }), headCell.get(0) ); } currentNode.replaceWith(node); }; priv.renderTableTfoot = function() { _uiNode$Table.find('tfoot').remove(); _foot = $('').insertAfter(_bodyNode); //$(_uiNodeCont).next('.foot').replaceWith(_foot); }; priv.renderFooter = function() { priv.renderFooterInfo(); priv.renderFooterPagination(); priv.renderFooterPageSizes(); priv.renderFooterColumnPicker(); priv.renderFooterFunctions(); priv.renderFooterExport(); }; priv.renderFooterInfo = function() { DBG1 && console.log('DBG:TableAjax::renderFooterInfo', { _uiNodeFooterInfo: _uiNodeFooterInfo }); var fromRow = Math.max(_state.page - 1, 0) * _state.pageSize; var total = _data.total; var toRow = Math.min(fromRow + _state.pageSize, total); if (_data.total > 0) { _uiNodeFooterInfo.innerHTML = '
    ' + 'Łącznie wyników: ' + total + '' + '
    ' + '' + p5Utils__format('Wyświetlane wiersze: od {0} do {1}', [fromRow + 1, toRow]) + '' + '
    '; } else { _uiNodeFooterInfo.innerHTML = '

    Brak wierszy pasujących do kryteriów wyszukiwania

    '; } }; priv.renderFooterPagination = function() { var nodeClass = 'tblAjax__' + 'footer__toolbar__pagination', currentNode = $(_uiNodeCont).next('.foot').find('.' + nodeClass), node; var currPage = _state.page; var totalPages = Math.ceil(_data.total / _state.pageSize); if (priv.options.debug || DBG) console.log('Render: ', nodeClass, '_data.total', _data.total, 'currPage', currPage); if (_data.total > 0) { node = $('
    '); var lowerPage = currPage - 2; var upperPage = currPage + 2; if (upperPage > totalPages) { var diff = upperPage - totalPages; upperPage = totalPages; lowerPage -= diff; } if (lowerPage < 1) lowerPage = 1; if (upperPage < 5) upperPage = 5; //$(p5Utils__format('
  • <<
  • ', [currPage == 1 ? 'disabled' : ''])) $(p5Utils__format('', [currPage == 1 ? ' disabled' : ''])) .on('click', {pageIndex: 1}, priv.pageChanged) .appendTo(node); //$(p5Utils__format('
  • <
  • ', [currPage == 1 ? 'disabled' : ''])) $(p5Utils__format('', [currPage == 1 ? ' disabled' : ''])) .on('click', {pageIndex: currPage - 1}, priv.pageChanged) .appendTo(node); for (var i = lowerPage; i <= upperPage; i++) { var link; //if (i != currPage) link = $(p5Utils__format('
  • {0}
  • ', [i, i > totalPages ? 'disabled' : ''])); if (i != currPage) link = $(p5Utils__format('', [i, i > totalPages ? ' disabled' : ''])); //if (i == currPage) link = $(p5Utils__format('
  • {0}
  • ', [i])); if (i == currPage) link = $(p5Utils__format('', [i])); if (link) { link.on('click', {pageIndex: i}, priv.pageChanged); link.appendTo(node); } } //$(p5Utils__format('
  • >
  • ', [currPage == totalPages ? 'disabled' : ''])) $(p5Utils__format('', [currPage == totalPages ? ' disabled' : ''])) .on('click', {pageIndex: currPage + 1}, priv.pageChanged) .appendTo(node); //$(p5Utils__format('
  • >>
  • ', [currPage == totalPages ? 'disabled' : ''])) $(p5Utils__format('', [currPage == totalPages ? ' disabled' : ''])) .on('click', {pageIndex: totalPages}, priv.pageChanged) .appendTo(node); } else { node = $(''); } currentNode.replaceWith(node); }; priv.renderFooterPageSizes = function() { var nodeClass = 'tblAjax__' + 'footer__toolbar__pagesizes', currentNode = $(_uiNodeCont).next('.foot').find('.' + nodeClass), node; if (priv.options.debug || DBG) console.log('Render: ', nodeClass); if (_data.total > 0 && priv.options.pageSizes.length > 0) { node = $('
    '); var btn = $('').appendTo(node); var span = $('').appendTo(btn); var ul = $('