Sat, 01 Oct 2022 16:16:36 +0200
Upgraded drawing to kicad 6.0.8
/* tslint:disable */ /* eslint-disable */ (function ($) { class DataAdapter { constructor ( config ) { if ( !config ) { config = {}; } const that = Object.assign( this, config ); const generateKey = function () { const S4 = function () { return ( ( ( 1 + Math.random() ) * 0x10000 ) | 0 ).toString( 16 ).substring( 1 ); }; return S4(); }; that.key = generateKey(); that.boundSource = []; that.dataItemById = []; if ( that.allowAdd === undefined ) { that.allowAdd = true; } if ( that.allowRemove === undefined ) { that.allowRemove = true; } if ( that.allowUpdate === undefined ) { that.allowUpdate = true; } if ( config.observable === undefined ) { that.observable = true; } if ( !config.dataSource ) { that.dataSource = []; } if ( !config.dataFields ) { that.dataFields = []; } else { /* if (config.dataSource && config.dataSource.length > 0) { const keys = Object.keys(config.dataSource[0]); // that.dataFields = []; for (let i = 0; i < keys.length; i++) { } } */ } if ( !config.dataSourceType ) { that.dataSourceType = 'array'; } if ( !config.id ) { that.id = null; } if ( !config.autoFetch ) { that.autoFetch = true; } if ( config.dataFields ) { that.dataFields = config.dataFields; } Object.defineProperty( that, 'groupBy', { configurable: false, enumerable: true, get() { if ( !that._groupBy ) { return []; } return that._groupBy; }, set( value ) { const updateGrouping = () => { that.boundHierarchy = null; that.refreshHierarchy(); if ( that.onGroup ) { that.onGroup(); } } that._groupBy = [].concat(value); if ( that.isInitialized ) { updateGrouping(); } } } ); if ( !config.groupBy ) { that.groupBy = []; } else { if ( config.groupBy.toArray ) { that.groupBy = config.groupBy.toArray(); } else { that.groupBy = config.groupBy; } } if ( config && config.autoBind !== false ) { that.dataBind(); } that.isInitialized = true; } get dataFields() { const that = this; return that._dataFields; } set dataFields( value ) { const that = this; that._dataFields = that._getDataFieldObjects( value ); return that._dataFields; } _getDataFieldObjects( dataFields ) { //const that = this; let dataFieldObjects = []; if ( typeof dataFields === 'number' ) { const charCode = 'A'.charCodeAt( 0 ); let prefix = ''; let index = 0; for ( let i = 0; i < dataFields; i++ ) { const letter = String.fromCharCode( charCode + index ); index++; const label = prefix + letter; dataFieldObjects.push( { name: label, dataType: 'string' } ) if ( index >= 26 ) { index = 0; prefix += 'A'; } } } else if ( dataFields.length > 0 ) { for ( let i = 0; i < dataFields.length; i++ ) { const dataField = dataFields[ i ]; if ( typeof dataField === 'string' ) { const dataFieldParts = dataField.split( ':' ); const name = dataFieldParts[ 0 ].trim(); const dataType = dataFieldParts.length > 1 ? dataFieldParts[ 1 ].trim() : 'string'; dataFieldObjects.push( { name: name, dataType: dataType } ); } else { dataFieldObjects.push( dataField ); } } } return dataFieldObjects; } get dataSource() { const that = this; if ( !that._dataSource ) { that._dataSource = []; } return that._dataSource; } set dataSource( value ) { const that = this; that._dataSource = value; if ( that.isInitialized ) { that.boundSource = false === that.observable ? [] : new JQX.ObservableArray(); that.dataItemById = []; that.bindingCompleted = false; that.dataBind(); } } get canNotify() { const that = this; if ( that._canNotify === undefined ) { that._canNotify = true; } return that._canNotify; } set canNotify( value ) { const that = this; that._canNotify = value; } _notify( changeArgs ) { const that = this; if ( !that.canNotify ) { return; } if ( that.notifyFn ) { that.notifyFn( changeArgs ); } } notify( notifyFn ) { const that = this; if ( notifyFn ) { that.notifyFn = notifyFn; } } toArray() { const that = this; return that.boundSource.toArray(); } dataBind() { const that = this; that.clear(); const completed = () => { that._onBindingComplete(); } if ( typeof that.dataSource === 'string' && ( that.dataSource.indexOf( '.json' ) >= 0 ) ) { that.url = that.dataSource; that.dataSourceType = 'json'; new Ajax( that, ( data/*, status*/ ) => { that.dataSource = data; that._bindToJSON(); } ); } else if ( typeof that.dataSource === 'string' && ( that.dataSource.indexOf( '.xlsx' ) >= 0 ) ) { that.url = that.dataSource; that.dataSourceType = 'xlsx'; new Ajax( that, ( data/*, status*/ ) => { if ( !data[ 0 ] ) { data = []; that._bindToArray(); completed(); return; } const keys = Object.keys( data[ 0 ] ); const dataFieldMap = {}; const dataRows = []; if ( that.exportHeader !== false ) { let index = 0; for ( let key in keys ) { const name = keys[ key ]; dataFieldMap[ name ] = that.dataFields[ index++ ].name; } for ( let i = 1; i < data.length; i++ ) { const row = data[ i ]; const dataRow = {}; for ( let key in keys ) { const name = keys[ key ]; dataRow[ dataFieldMap[ name ] ] = row[ name ]; } dataRows.push( dataRow ); } that.dataSource = dataRows; } that._bindToArray(); completed(); } ); } else if ( typeof that.dataSource === 'string' && ( that.dataSource.indexOf( '.csv' ) >= 0 ) ) { that.dataSourceType = 'csv'; new Ajax( that, (/*data, status*/ ) => { that._bindToArray(); } ); } else if ( typeof that.dataSource === 'string' && ( that.dataSource.indexOf( '.tsv' ) >= 0 ) ) { that.dataSourceType = 'tsv'; new Ajax( that, (/*data, status*/ ) => { } ); } else if ( that.dataSourceType === 'array' ) { that._bindToArray(); completed(); } else if ( that.dataSourceType === 'json' ) { that._bindToJSON(); completed(); } } _onBindingComplete() { const that = this; that._buildHierarchy(); if ( that.onBindingComplete ) { that.onBindingComplete( { data: that.boundSource } ); } if ( that._notify ) { that._notify( { action: 'bindingComplete', data: that.boundSource } ); } that.bindingCompleted = true; } refreshHierarchy() { const that = this; that._buildHierarchy(); } find() { const that = this; return that.boundSource.find.apply( that.boundSource, arguments ); } onVirtualDataSourceRequested( requestCallback, details ) { const that = this; let first = details ? details.first : Infinity; let last = details ? details.last : Infinity; let row = details ? details.row : null; if ( undefined === first ) { first = Infinity; } if ( undefined === last ) { last = Infinity; } that.virtualFirstIndex = first; that.virtualLastIndex = last; if ( that.virtualDataSource ) { const getDataSource = function ( ExcelAdapterSettings ) { if ( ExcelAdapterSettings.virtualDataSourceLength !== undefined ) { that.virtualDataSourceLength = ExcelAdapterSettings.virtualDataSourceLength; } new JQX.ExcelAdapter( { dataSource: ExcelAdapterSettings.dataSource, dataFields: ExcelAdapterSettings.dataFields || that.dataFields, data: details, onBindingComplete( event ) { if ( that.virtualDataSourceOnExpand && row ) { if ( event.data && event.data.length > 0 ) { that.add( event.data, row.$.id ); } else { row.leaf = true; } if ( that.onFilter ) { that.onFilter() } requestCallback(); return; } if ( first === Infinity ) { that.add( event.data ); } else { let items = []; let indexes = []; for ( let i = 0; i < event.data.length; i++ ) { const item = event.data[ i ]; if ( first + i <= last ) { items.push( item ); indexes.push( first + i ); } } that.update( indexes, items ); } if ( that.onFilter ) { that.onFilter() } requestCallback(); } } ); } let hasCache = false; const isEmpty = ( obj ) => Object.entries( obj ).length === 0 && ( obj.constructor === Object || obj.constructor === Array ); const canCache = isEmpty( details.sorting ) && isEmpty( details.filtering ) && isEmpty( details.grouping ) && !details.row && ( details.action !== 'filter' && details.action !== 'sort' && details.action !== 'group' ); if ( that.virtualDataSourceCache && first !== Infinity && canCache ) { let cachedCount = 0; for ( let i = first; i < last; i++ ) { if ( !that[ i ].$.isEmpty ) { cachedCount++; } } if ( cachedCount === last - first ) { hasCache = true; } } if ( hasCache ) { requestCallback(); } else { if ( details.action === 'expand' ) { that.virtualDataSourceOnExpand( getDataSource, { first: first, last: last, row: details.row, sorting: details.sorting, filtering: details.filtering, grouping: details.grouping, action: details.action } ); } else { that.virtualDataSource( getDataSource, { first: first, last: last, sorting: details.sorting, filtering: details.filtering, filterOperator: details.filterOperator || 'and', grouping: details.grouping, action: details.action } ); } } } else { requestCallback(); } } add( item, parentId ) { const that = this; if ( !item ) { return; } let result = true; const addItem = function ( item ) { const itemObject = that._getDataItem( item, that.boundSource.length ); that[ that.boundSource.length ] = itemObject; that.dataItemById[ itemObject.$.id ] = itemObject; const pushResult = that.boundSource.push( itemObject ); if ( parentId !== undefined ) { itemObject.$.parentId = parentId; } if ( !pushResult ) { result = false; } return itemObject; } if ( item.length ) { let itemObjects = []; for ( let i = 0; i < item.length; i++ ) { const itemObject = addItem( item[ i ] ); itemObjects.push( itemObject ); } that._notify( { action: 'add', data: itemObjects } ); } else { const itemObject = addItem( item ); that._notify( { action: 'add', data: itemObject } ); } that.refreshHierarchy(); return result; } refreshIndexes() { const that = this; for (let i = 0; i < that.boundSource.length; i++) { that[i] = that.boundSource[i]; that[i].$.index = i; that.dataItemById[that[i].$.id] = that[i]; } let i = that.boundSource.length; while (that[i]) { delete that[i]; i++; } } removeLast() { const that = this; delete that[that.boundSource.length - 1]; const result = that.boundSource.pop(); delete that.dataItemById[result.$.id]; that._notify({ action: 'removeLast', data: result }); that.refreshHierarchy(); return result; } removeAt(index) { const that = this; const item = that.boundSource[index]; if (!item) { throw new Error('Invalid Item Index'); } that.boundSource.splice(index, 1); delete that.dataItemById[item.$.id]; that.refreshIndexes(); that._notify({ action: 'remove', index: index, data: item }); that.refreshHierarchy(); } update( index, dataSourceItem ) { const that = this; if ( JQX.Utilities.Types.isArray( index ) && JQX.Utilities.Types.isArray( dataSourceItem ) ) { if ( index.length === 0 && dataSourceItem.length === 0 ) { that.refreshHierarchy(); return; } } if ( dataSourceItem.length && index.length ) { let itemObjects = []; for ( let i = 0; i < index.length; i++ ) { const itemObject = that._getDataItem( dataSourceItem[ i ], index[ i ] ); const currentIndex = index[ i ]; itemObjects.push( itemObject ); that.boundSource[ currentIndex ] = itemObject; that[ currentIndex ] = that.boundSource[ currentIndex ]; that.dataItemById[ itemObject.$.id ] = that[ currentIndex ]; } that._notify( { action: 'update', index: index, data: itemObjects } ); that.refreshHierarchy(); return; } const itemObject = that._getDataItem( dataSourceItem, index ); that.boundSource[ index ] = itemObject; that[ index ] = that.boundSource[ index ]; that.dataItemById[ itemObject.$.id ] = that[ index ]; that._notify( { action: 'update', index: index, data: itemObject } ); that.refreshHierarchy(); return itemObject; } insert( index, item ) { const that = this; item = that._getDataItem( item, index ); const result = that.boundSource.splice( index, 0, item ); that.refreshIndexes(); that._notify( { action: 'insert', index: index, data: item } ); that.refreshHierarchy(); return result; } move( from, to ) { if ( to > from && to - from === 1 || from === to ) { return; } const that = this, recordToMove = that.boundSource.splice( from, 1 )[ 0 ]; if ( to > from ) { to--; that.boundSource.splice( to, 0, recordToMove ); } else { that.boundSource.splice( to, 0, recordToMove ); } that.refreshIndexes(); that._notify( { action: 'move', index: to, data: that.boundSource[ to ] } ); that.refreshHierarchy(); } indexOf( item ) { const that = this; const index = that.boundSource.indexOf( item ); return index; } get length() { const that = this; if ( that.virtualDataSourceLength !== undefined ) { return that.virtualDataSourceLength; } if ( that.dataSourceLength ) { return that.dataSourceLength; } if ( typeof ( that.dataSource ) === 'number' ) { return that.dataSource; } if ( that.bindingCompleted ) { return that.boundSource.length; } if ( that.dataSource && typeof that.dataSource !== 'string' && that.dataSource.length ) { return that.dataSource.length; } return that.boundSource.length; } clear() { const that = this; if ( !that.isInitialized ) { that._cachedValues = []; that.dataItemById = []; return; } for ( let i = 0; i < that.boundSource.length; i++ ) { delete that[ i ]; } that._cachedValues = []; that.boundSource = that.observable ? new JQX.ObservableArray() : []; that.dataItemById = []; that.refreshHierarchy(); } _getId( id, item, index ) { if ( id !== null && id.name !== undefined ) { if ( id.name && item.getAttribute ) { let result = item.getAttribute( id.name ); if ( result !== null && result.toString().length > 0 ) { return result; } else if ( id.map ) { try { let result = item.getAttribute( id.map ); if ( result !== null && result.toString().length > 0 ) { return result; } } catch ( error ) { return index; } } return; } } if ( id ) { if ( id.toString().length > 0 && item.getAttribute ) { let result = item.getAttribute( id ); if ( result !== null && result.toString().length > 0 ) { return result.trim().split( ' ' ).join( '' ).replace( /([ #;?%&,.+*~\':'!^$[\]()=>|\/@])/g, '' ); } else { let splitMap = id.split( this.mapChar ); if ( splitMap.length > 1 ) { let d = item; for ( let p = 0; p < splitMap.length; p++ ) { if ( d !== undefined ) { d = d[ splitMap[ p ] ]; } } if ( d !== undefined ) { return d; } } else { if ( item[ id ] !== undefined ) { return item[ id ]; } } } } } return index; } _buildHierarchy() { const that = this; if ( !that.reservedNames ) { that.reservedNames = { leaf: 'leaf', parent: 'parent', expanded: 'expanded', checked: 'checked', selected: 'selected', level: 'level', icon: 'icon', data: 'data' } } else { const names = that.reservedNames; if ( !names.leaf ) { names.leaf = 'leaf'; } if ( !names.parent ) { names.parent = 'parent'; } if ( !names.expanded ) { names.expanded = 'expanded'; } if ( !names.checked ) { names.checked = 'checked'; } if ( !names.selected ) { names.selected = 'selected'; } if ( !names.level ) { names.level = 'level'; } if ( !names.data ) { names.data = 'data'; } } const names = that.reservedNames; if ( that.childrenDataField ) { const hierarchy = []; for ( let i = 0; i < that.boundSource.length; i++ ) { const item = Object.assign( {}, that.boundSource[ i ] ); if ( !item ) { continue; } hierarchy.push( item ); const addItems = function ( item ) { const splitMap = that.childrenDataField.split( that.mapChar ); let children = null; if ( splitMap.length > 1 ) { let data = item; for ( let p = 0; p < splitMap.length; p++ ) { if ( data !== undefined ) { data = data[ splitMap[ p ] ]; } } children = data; } else { children = item[ 'children' ]; } item[ 'children' ] = children; if ( item[ 'children' ] === null || item[ 'children' ] === undefined || ( item[ 'children' ] && item[ 'children' ].length === 0 ) ) { item[ names.leaf ] = true; } } addItems( item ); item[ names.level ] = 0; if ( !item.$ ) { item.$ = {}; } item[ names.parent ] = null; item[ names.data ] = item; if ( item[ names.expanded ] === undefined ) { item[ names.expanded ] = false; } const drillThrough = function ( parent, children ) { if ( !children ) { parent[ 'children' ] = new Array(); return; } for ( let i = 0; i < children.length; i++ ) { let item = that._getDataItem( children[ i ], i ); if ( !item ) { continue; } addItems( item ); item[ names.level ] = parent[ names.level ] + 1; item[ names.parent ] = parent; item[ names.data ] = item; if ( parent ) { parent[ 'children' ][ i ] = item; } if ( item[ names.expanded ] === undefined ) { item[ names.expanded ] = false; } drillThrough( item, item[ 'children' ] ); } } drillThrough( item, item[ 'children' ] ); } that.boundHierarchy = hierarchy; if ( !that._boundSourceUpdate ) { for ( let i = 0; i < that.boundHierarchy.length; i++ ) { const item = that.boundHierarchy[ i ]; if ( item.children ) { const drillThrough = function ( item ) { if ( !that.dataItemById[ item.$.id ] ) { that.boundSource.canNotify = false; that.dataItemById[ item.$.id ] = item; that[ that.boundSource.length ] = item; that.boundSource.push( item ); that.boundSource.canNotify = true; } if ( item.children ) { for ( let i = 0; i < item.children.length; i++ ) { const child = item.children[ i ]; if ( child.children ) { drillThrough( child ); } } } } drillThrough( item ); } } that._boundSourceUpdate = true; } } if ( that.xmlRoot && that.dataSourceType === 'xml' ) { that.boundHierarchy = this._getHierarchy( 'uid', '_parentuid', 'children', null, that.boundSource ); } if ( that.keyDataField && that.parentDataField ) { that.boundHierarchy = this._getHierarchy( that.keyDataField, that.parentDataField, 'children', null, that.boundSource ); } if ( that.groupBy && that.groupBy.length > 0 ) { that.boundHierarchy = this._getGroupHierarchy( that.groupBy, 'children', 'label', null, 'data', null, 'parent', that.boundSource ); } if ( that.virtualDataSourceOnExpand ) { that.boundHierarchy = this._getHierarchy( 'id', 'parentId', 'children', null, that.boundSource ); } } _getGroupHierarchy( groups, collectionName, groupName, mappingFields, itemName, valueName, parentName, data, startIndex ) { let that = this; if ( !startIndex ) { startIndex = 0; } let names = that.reservedNames; const guid = function () { function s4() { return Math.floor( ( 1 + Math.random() ) * 0x10000 ) .toString( 16 ) .substring( 1 ); } return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4(); } let groupHashCodes = new Array(); for ( let iGroupColumn = 0; iGroupColumn < groups.length; iGroupColumn++ ) { groupHashCodes[ iGroupColumn ] = guid(); } if ( !collectionName ) { collectionName = 'children'; } if ( !groupName ) { groupName = 'group'; } if ( !itemName ) { itemName = 'item'; } if ( !parentName ) { parentName = 'parent'; } if ( undefined === valueName ) { valueName = 'value'; } const groupboundSource = new Array(); const hashItemGroups = new Array(); let groupboundSourceIndex = 0; const getItem = function ( item ) { let itemObj = item; if ( mappingFields ) { for ( let mappingField in mappingFields ) { const mappingObject = mappingFields[ mappingField ]; if ( mappingObject.name && mappingObject.map ) { itemObj[ mappingObject.map ] = itemObj[ mappingObject.name ]; } } } return itemObj; } for ( let obj = 0; obj < data.length; obj++ ) { let item = Object.assign( {}, getItem( data[ obj ] ) ); item[ names.leaf ] = false; let itemKeysHierarchy = new Array(); let keys = 0; for ( let iGroupColumn = 0; iGroupColumn < groups.length; iGroupColumn++ ) { const group = groups[ iGroupColumn ]; const value = item[ group ]; if ( null === value ) { continue; } itemKeysHierarchy[ keys++ ] = { value: value, group: group, hash: groupHashCodes[ iGroupColumn ] }; } if ( itemKeysHierarchy.length !== groups.length ) { break; } let parentItem = null; let lookupKey = ''; for ( let q = 0; q < itemKeysHierarchy.length; q++ ) { const itemKey = itemKeysHierarchy[ q ].value; const groupDataField = itemKeysHierarchy[ q ].group; const columnHash = itemKeysHierarchy[ q ].hash; lookupKey = lookupKey + '_' + columnHash + '_' + itemKey; if ( hashItemGroups[ lookupKey ] !== undefined && hashItemGroups[ lookupKey ] !== null ) { parentItem = hashItemGroups[ lookupKey ]; continue; } if ( parentItem === null ) { parentItem = { $: {} }; parentItem[ names.level ] = 0; parentItem[ names.leaf ] = false; parentItem[ parentName ] = null; parentItem[ groupName ] = itemKey; parentItem[ itemName ] = item; parentItem[ 'groupDataField' ] = groupDataField; if ( !parentItem[ groupDataField ] ) { parentItem[ groupDataField ] = parentItem.data[ groupDataField ]; } if ( item[ names.expanded ] !== undefined ) { parentItem[ names.expanded ] = item[ names.expanded ]; } else { parentItem[ names.expanded ] = false; } if ( valueName ) { parentItem[ valueName ] = item[ valueName ]; } parentItem[ collectionName ] = new Array(); let uid = groupboundSource.length + startIndex; if ( !this.id || typeof item.$.id === 'number' || isFinite( item.$.id ) ) { uid = 'Item' + uid; } if ( parentItem.$.id === undefined ) { parentItem.$.id = uid; } groupboundSource[ groupboundSourceIndex++ ] = parentItem; } else { const subItem = { $: {} }; subItem[ names.level ] = parentItem[ names.level ] + 1; subItem[ parentName ] = parentItem; subItem[ groupName ] = itemKey; subItem[ collectionName ] = new Array(); subItem[ itemName ] = item; subItem[ 'groupDataField' ] = groupDataField; subItem[ names.leaf ] = false; if ( !subItem[ groupDataField ] ) { subItem[ groupDataField ] = subItem.data[ groupDataField ]; } if ( item[ names.expanded ] !== undefined ) { subItem[ names.expanded ] = item[ names.expanded ]; } else { subItem[ names.expanded ] = false; } if ( valueName ) { subItem[ valueName ] = item[ valueName ]; } if ( subItem.$.id === undefined ) { subItem.$.id = parentItem.$.id + '_' + parentItem[ collectionName ].length; } parentItem[ collectionName ][ parentItem[ collectionName ].length ] = subItem; parentItem = subItem; } hashItemGroups[ lookupKey ] = parentItem; } if ( item ) { item[ names.leaf ] = true; } if ( parentItem !== null ) { if ( this.id === null ) { if ( undefined === item.$.id ) { item.$.id = parentItem.$.id + '_' + parentItem[ collectionName ].length; } } else { if ( undefined === item.$.id ) { if ( item.$.id.toString().indexOf( parentItem.$.id ) === -1 ) { item.$.id = parentItem.$.id + '_' + item.$.id; } } } item[ parentName ] = parentItem; item[ names.level ] = parentItem[ names.level ] + 1; parentItem[ collectionName ][ parentItem[ collectionName ].length ] = item; } else { if ( undefined === item.$.id ) { item.$.id = guid(); } } } return groupboundSource; } _getHierarchy( fieldName, parentFieldName, collectionName, mappingFields, boundSource ) { const that = this; const databoundHierarchy = new Array(); let flatData = this.boundSource; if ( boundSource ) { flatData = boundSource; } if ( this.boundSource.length === 0 ) return null; const childrenName = collectionName !== null ? collectionName : 'children'; let items = new Array(); let data = flatData; let dataLength = data.length; let names = that.reservedNames; const getItem = function ( item ) { let itemObj = item; if ( mappingFields ) { for ( let mappingField in mappingFields ) { const mappingObject = mappingFields[ mappingField ]; if ( mappingObject.name && mappingObject.map ) { itemObj[ mappingObject.map ] = itemObj[ mappingObject.name ]; } } } return itemObj; } // build hierarchical source. for ( let i = 0; i < dataLength; i++ ) { let item = data[ i ]; let parentId = item[ parentFieldName ]; let id = item[ fieldName ]; if ( parentFieldName === 'parentId' ) { parentId = item.$.parentId; } if ( fieldName === 'id' ) { id = item.$.id; } item[ childrenName ] = new Array(); items[ id ] = { parentId: parentId, item: item }; } for ( let i = 0; i < dataLength; i++ ) { const item = data[ i ]; let parentId = item[ parentFieldName ]; let id = item[ fieldName ]; if ( parentFieldName === 'parentId' ) { parentId = item.$.parentId; } if ( fieldName === 'id' ) { id = item.$.id; } if ( items[ parentId ] !== undefined ) { let item = { parentId: parentId, item: items[ id ].item }; let parentItem = items[ parentId ].item; if ( !parentItem[ childrenName ] ) { parentItem[ childrenName ] = new Array(); } let length = parentItem[ childrenName ].length; item = item.item; if ( !names ) { if ( item.parent === undefined ) { item.parent = parentItem; } } else { if ( item[ names.parent ] === undefined ) { item[ names.parent ] = parentItem; } } const itemObj = getItem( item ); parentItem[ childrenName ][ length ] = itemObj; items[ parentId ].item = parentItem; items[ id ].item = item; } else { let item = items[ id ].item; if ( !names ) { if ( item.parent === undefined ) { item.parent = null; } } else { if ( item[ names.parent ] === undefined ) { item[ names.parent ] = null; } } const itemObj = getItem( item ); if ( !names ) { itemObj.level = 0; } else { itemObj[ names.level ] = 0; } databoundHierarchy[ databoundHierarchy.length ] = itemObj; } } if ( databoundHierarchy.length !== 0 ) { let updateLevels = function ( level, children ) { for ( let i = 0; i < children.length; i++ ) { const child = children[ i ]; if ( !names ) { child.level = level; } else { child[ names.level ] = level; } const childChildren = child[ childrenName ]; if ( childChildren ) { if ( childChildren.length > 0 ) { updateLevels( level + 1, childChildren ); } else { if ( that.virtualDataSourceOnExpand ) { if ( child.leaf === undefined ) { child.leaf = false; } } else { if ( !names ) { child.leaf = true; } else { child[ names.leaf ] = true; } } } } else { if ( that.virtualDataSourceOnExpand ) { if ( child.leaf === undefined ) { child.leaf = false; } } else { if ( !names ) { child.leaf = true; } else { child[ names.leaf ] = true; } } } } }; updateLevels( 0, databoundHierarchy ); } return databoundHierarchy; } summarize( summaryItems, boundSource ) { const that = this; if ( !Array.isArray( summaryItems ) ) { summaryItems = [ summaryItems ]; } let tempSummaryItems = []; for ( let i = 0; i < summaryItems.length; i++ ) { const summaryItem = summaryItems[ i ]; for ( let name in summaryItem ) { const functions = summaryItem[ name ]; tempSummaryItems.push( { dataField: name, functions: functions } ) } } summaryItems = tempSummaryItems; let data = {}; let summaryByDataField = new Array(); if ( !boundSource ) { boundSource = that.boundSource; } let length = boundSource.length; if ( length === 0 ) { return; } if ( length === undefined ) { return; } for ( let i = 0; i < length; i++ ) { let dataItem = boundSource[ i ]; for ( let j = 0; j < summaryItems.length; j++ ) { const summaryItem = summaryItems[ j ]; let value = dataItem[ summaryItem.dataField ]; if ( summaryItem.functions ) { data[ summaryItem.dataField ] = data[ summaryItem.dataField ] || {}; summaryByDataField[ summaryItem.dataField ] = summaryByDataField[ summaryItem.dataField ] || 0; summaryByDataField[ summaryItem.dataField ]++; const _summaryItemFunction = function ( summaryItemObject ) { for ( let name in summaryItemObject ) { let oldValue = data[ summaryItem.dataField ][ name ]; if ( oldValue === null || oldValue === undefined ) { data[ summaryItem.dataField ][ name ] = 0; oldValue = 0; } if ( typeof summaryItemObject[ name ] === 'function' ) { oldValue = summaryItemObject[ name ]( oldValue, value, summaryItem.dataField, dataItem ); } data[ summaryItem.dataField ][ name ] = oldValue; } } let canParse = parseFloat( value ); if ( isNaN( canParse ) ) { canParse = false; } else { canParse = true; } if ( canParse ) { value = parseFloat( value ); } if ( typeof value === 'number' && isFinite( value ) ) { summaryItem.functions.forEach( function ( summaryItemFunction ) { let oldValue = data[ summaryItem.dataField ][ summaryItemFunction ]; if ( oldValue === null || oldValue === undefined ) { oldValue = 0; if ( summaryItemFunction === 'min' ) { oldValue = 9999999999999; } if ( summaryItemFunction === 'max' ) { oldValue = -9999999999999; } if (summaryItemFunction === 'median') { oldValue = []; } } if ( summaryItemFunction === 'sum' || summaryItemFunction === 'avg' || summaryItemFunction === 'stdev' || summaryItemFunction === 'stdevp' || summaryItemFunction === 'var' || summaryItemFunction === 'varp' ) { oldValue += parseFloat( value ); } else if ( summaryItemFunction === 'product' ) { if ( i === 0 ) oldValue = parseFloat( value ); else oldValue *= parseFloat( value ); } else if ( summaryItemFunction === 'min' ) { oldValue = Math.min( oldValue, parseFloat( value ) ); } else if ( summaryItemFunction === 'max' ) { oldValue = Math.max( oldValue, parseFloat( value ) ); } else if ( summaryItemFunction === 'count' ) { oldValue++; } else if (summaryItemFunction === 'median') { oldValue.push(parseFloat(value)); } else if ( typeof ( summaryItemFunction ) === 'object' ) { _summaryItemFunction( summaryItemFunction ); return; } data[ summaryItem.dataField ][ summaryItemFunction ] = oldValue; } ); } else { summaryItem.functions.forEach( function ( summaryItemFunction ) { if ( summaryItemFunction === 'min' || summaryItemFunction === 'max' || summaryItemFunction === 'count' || summaryItemFunction === 'product' || summaryItemFunction === 'sum' || summaryItemFunction === 'avg' || summaryItemFunction === 'stdev' || summaryItemFunction === 'stdevp' || summaryItemFunction === 'var' || summaryItemFunction === 'varp' ) { if ( value === null ) { return true; } let oldValue = data[ summaryItem.dataField ][ summaryItemFunction ]; if ( oldValue === null || oldValue === undefined ) { oldValue = 0; } data[ summaryItem.dataField ][ summaryItemFunction ] = oldValue; return true; } if ( typeof ( summaryItemFunction ) === 'object' ) { _summaryItemFunction( summaryItemFunction ); } } ); } } } } for ( let j = 0; j < summaryItems.length; j++ ) { const summaryItem = summaryItems[ j ]; if ( !summaryItem.functions ) { continue; } if ( !data[ summaryItem.dataField ] ) { data[ summaryItem.dataField ] = {}; summaryItem.functions.forEach( function ( summaryItemFunction ) { data[ summaryItem.dataField ][ summaryItemFunction ] = 0; } ); } if ( data[ summaryItem.dataField ][ 'avg' ] !== undefined ) { const value = data[ summaryItem.dataField ][ 'avg' ]; const dataValues = summaryByDataField[ summaryItem.dataField ]; if ( dataValues === 0 || dataValues === undefined ) { data[ summaryItem.dataField ][ 'avg' ] = 0; } else { data[ summaryItem.dataField ][ 'avg' ] = value / dataValues; } } else if ( data[ summaryItem.dataField ][ 'count' ] !== undefined ) { data[ summaryItem.dataField ][ 'count' ] = length; } else if (data[summaryItem.dataField]['median'] !== undefined) { let population = data[summaryItem.dataField]['median']; population.sort(function (a, b) { return a - b; }); data[summaryItem.dataField]['median'] = 0.5 * (population[Math.floor((population.length + 1) / 2) - 1] + population[Math.ceil((population.length + 1) / 2) - 1]); } // stdev, stdevp, var, varp. // stdev - Standard deviation on a sample. // varp - Variance on an entire population. // let - Variance on a sample. if ( data[ summaryItem.dataField ][ 'stdev' ] || data[ summaryItem.dataField ][ 'stdevp' ] || data[ summaryItem.dataField ][ 'var' ] || data[ summaryItem.dataField ][ 'varp' ] ) { summaryItem.functions.forEach( function ( summaryItemFunction ) { if ( summaryItemFunction === 'stdev' || summaryItemFunction === 'var' || summaryItemFunction === 'varp' || summaryItemFunction === 'stdevp' ) { const value = data[ summaryItem.dataField ][ summaryItemFunction ]; const count = length; const average = ( value / length ); let sumSq = 0.0; for ( let i = 0; i < length; i++ ) { let dataItem = boundSource[ i ]; let value = dataItem[ summaryItem.dataField ]; sumSq += ( value - average ) * ( value - average ); } let denominator = ( summaryItemFunction === 'stdevp' || summaryItemFunction === 'varp' ) ? count : count - 1; if ( denominator === 0 ) { denominator = 1; } if ( summaryItemFunction === 'var' || summaryItemFunction === 'varp' ) { data[ summaryItem.dataField ][ summaryItemFunction ] = sumSq / denominator; } else if ( summaryItemFunction === 'stdevp' || summaryItemFunction === 'stdev' ) { data[ summaryItem.dataField ][ summaryItemFunction ] = Math.sqrt( sumSq / denominator ); } } } ); } } return data; } deserialize(stringValue, type, nullable) { const nullValue = stringValue === 'null'; if (stringValue === undefined || (nullValue && !nullable)) { return undefined; } if (nullValue && nullable) { return null; } if (type === 'boolean' || type === 'bool') { if (stringValue === null) { return false; } // Boolean properties are set based on the presence of the attribute: if the attribute exists at all, the value is true. return true; } else if (type === 'number' || type === 'float') { if (stringValue === 'NaN') { return NaN; } if (stringValue === 'Infinity') { return Infinity; } if (stringValue === '-Infinity') { return -Infinity; } return parseFloat(stringValue); } else if (type === 'int' || type === 'integer') { if (stringValue === 'NaN') { return NaN; } if (stringValue === 'Infinity') { return Infinity; } if (stringValue === '-Infinity') { return -Infinity; } return parseInt(stringValue); } else if (type === 'string') { return stringValue; } else if (type === 'any') { return stringValue; } else if (type === 'date') { return new Date(stringValue); } else if (type === 'function') { if (typeof window[stringValue] === 'function') { return window[stringValue]; } } else if (type === 'array' || type === 'object') { try { const jsonObject = JSON.parse(stringValue); if (jsonObject) { return jsonObject; } } catch (er) { if (window[stringValue] && (typeof window[stringValue] === 'object')) { return window[stringValue]; } else if (type === 'array' && stringValue.indexOf('[') >= 0) { if (stringValue.indexOf('{') >= 0) { let array = stringValue.replace(/{/ig, '').replace('[', '').replace(']', '').replace(/'/ig, '').replace(/"/ig, '').trim(); array = array.split('},'); for (let i = 0; i < array.length; i++) { let parsedObject = { }; let parts = array[i].trim().split(','); for (let j = 0; j < parts.length; j++) { const key = parts[j].split(':')[0].trim(); const value = parts[j].split(':')[1].trim(); parsedObject[key] = value; } array[i] = parsedObject; } return array; } const array = stringValue.replace('[', '').replace(']', '').replace(/'/ig, '').replace(/"/ig, '').trim().split(','); return array; } } } return undefined; } _getDataItem( dataSourceItem, index ) { const that = this; const itemObject = {}; const unboundMode = typeof ( that.dataSource ) === 'number' || that.dataSourceLength; if ( !dataSourceItem ) { return { $: { id: index, isEmpty: true, index: index } } } if ( typeof dataSourceItem === 'string' ) { dataSourceItem = { '': dataSourceItem }; } if ( unboundMode ) { for ( let j = 0; j < that.dataFields.length; j++ ) { const dataField = that.dataFields ? that.dataFields[ j ] : {}; itemObject[ dataField.name ] = ''; } itemObject.$ = {}; itemObject.$.id = index; itemObject.$.index = index; return itemObject; } const dataItem = dataSourceItem; if ( dataItem.expanded !== undefined ) { itemObject.expanded = dataItem.expanded; if ( dataItem.expanded === 'true' || dataItem.expanded === true || dataItem.expanded === 1 ) { itemObject.expanded = true; } else { itemObject.expanded = false; } } if ( that.childrenDataField ) { if ( dataItem[ that.childrenDataField ] !== undefined ) { itemObject.children = dataItem[ that.childrenDataField ]; } } else { if ( dataItem.children !== undefined ) { itemObject.children = dataItem.children; } else if ( dataItem.items !== undefined ) { itemObject.children = dataItem.items; } } if ( dataItem.leaf !== undefined ) { itemObject.leaf = dataItem.leaf; } if ( dataItem.level !== undefined ) { itemObject.level = dataItem.level; } if ( that.keyDataField ) { if ( dataItem[ that.keyDataField ] !== undefined ) { itemObject[ that.keyDataField ] = dataItem[ that.keyDataField ]; } } if ( that.parentDataField ) { if ( dataItem[ that.parentDataField ] !== undefined ) { itemObject[ that.parentDataField ] = dataItem[ that.parentDataField ]; } } if ( that.dataFields.length === 0 ) { const names = Object.getOwnPropertyNames( dataSourceItem ); for ( let i = 0; i < names.length; i++ ) { if ( names[ i ] === '$' ) { continue; } that.dataFields.push( { name: names[ i ], dataType: 'string' } ); } } for ( let j = 0; j < that.dataFields.length; j++ ) { const dataField = that.dataFields ? that.dataFields[ j ] : {}; let value = ''; dataField.dataType = dataField.type; if ( undefined === dataField || dataField === null ) { continue; } if ( dataSourceItem.length ) { value = dataSourceItem[ j ]; } if ( dataField.map ) { let splitMap = dataField.map.split( that.mapChar ); if ( splitMap.length > 0 ) { let dataMappedItem = dataItem; for ( let p = 0; p < splitMap.length; p++ ) { if ( !dataItem ) { continue; } dataMappedItem = dataMappedItem[ splitMap[ p ] ]; } value = dataMappedItem; } else { value = dataItem[ dataField.map ]; } } if ( value !== undefined && value !== null ) { value = value.toString(); } else { if ( value === undefined && value !== null ) { value = ''; } } let isEmptyString = false; // searches by both selectors when necessary. if ( value === '' ) { isEmptyString = true; value = dataSourceItem[ dataField.name ]; if ( value !== undefined && value !== null ) { if ( dataField.dataType !== 'array' ) { if ( dataField.dataType !== 'date' ) { value = value.toString(); } } } else { value = ''; } } if ( value === '[object Object]' && dataField.map && isEmptyString ) { value = ''; } if ( that._cachedValues[ '' + value + '_' + dataField.dataType ] ) { value = that._cachedValues[ '' + value + '_' + dataField.dataType ]; } else { if ( dataField.dataType === 'bool' || dataField.dataType === 'boolean' ) { if ( value === 'true' || value === '1' ) { value = true; } else if ( value === 'false' || value === '0' ) { value = false; } } else { value = that.deserialize( '' + value, dataField.dataType, true ); } that._cachedValues[ value + '_' + dataField.dataType ] = value; } if ( dataField.dataType !== 'string' && dataField.dataType !== 'boolean' && dataField.dataType !== 'bool' ) { if ( isNaN( value ) || value === -Infinity || value === Infinity ) { value = 0; } } itemObject[ dataField.name ] = value; } let itemObjectId = index; if ( that.id ) { itemObjectId = dataItem[ that.id ]; if ( typeof ( itemObjectId ) === 'object' ) { itemObjectId = index; } } else if ( !that.virtualDataSource && that.dataItemById && that.dataItemById[ itemObjectId ] ) { itemObjectId = that.length; } if ( !itemObject.$ ) { itemObject.$ = {}; } itemObject.$.id = itemObjectId; itemObject.$.index = index; return new Object( itemObject ); } _bindToArray() { const that = this; const unboundMode = typeof ( that.dataSource ) === 'number' || that.dataSourceLength; const dataArray = []; that.boundSource.canNotify = false; for ( let i = 0; i < that.length; i++ ) { const dataSourceItem = unboundMode ? {} : that.dataSource[ i ]; const itemObject = that._getDataItem( dataSourceItem, i ); dataArray.push( itemObject ); } if ( unboundMode && that.dataSourceLength && that.dataSource.length > 0 ) { for ( let i = 0; i < that.dataSource.length; i++ ) { const cell = that.dataSource[ i ].cell; const value = that.dataSource[ i ].value; const row = cell.replace( /[^0-9]/g, '' ); const dataField = cell.replace( /[0-9]/g, '' ); dataArray[ row - 1 ][ dataField ] = value; } } that.boundSource = dataArray; for ( let i = 0; i < that.length; i++ ) { that[ i ] = that.boundSource[ i ]; that.dataItemById[ that[ i ].$.id ] = that[ i ]; } that.boundSource.canNotify = true; } _bindToJSON() { const that = this; const dataArray = []; const dataEntries = Object.entries( that.dataSource ); that.boundSource.canNotify = false; for ( let i = 0; i < dataEntries.length; i++ ) { const dataSourceItem = dataEntries[ i ]; const itemObject = that._getDataItem( dataSourceItem, i ); dataArray.push( itemObject ); } that.boundSource = false === that.observable ? dataArray : new JQX.ObservableArray( dataArray ); for ( let i = 0; i < that.length; i++ ) { that[ i ] = that.boundSource[ i ]; that.dataItemById[ that[ i ].$.id ] = that[ i ]; } that.boundSource.canNotify = true; } sortBy( dataField, dataType, orderBy ) { const that = this; if ( !dataType ) { for ( let i = 0; i < that.dataFields.length; i++ ) { const field = that.dataFields[ i ]; if ( field.name === dataField ) { dataType = field.dataType; break; } } } if ( that.boundHierarchy ) { if ( ( !dataField || dataField.length === 0 ) && that.groupBy.length > 0 ) { that.refreshHierarchy(); return; } const sortBy = function ( hierarchy ) { that._sort( hierarchy, dataField, orderBy, dataType ); for ( let i = 0; i < hierarchy.length; i++ ) { const item = hierarchy[ i ]; if ( item[ 'children' ] ) { sortBy( item[ 'children' ], dataField, orderBy, dataType ); } } } sortBy( that.boundHierarchy ); } else { that._sort( that.boundSource, dataField, orderBy, dataType ); } } _createFilter( dataType, filterExpressions ) { const filterOperators = { '=': 'EQUAL', '<>': 'NOT_EQUAL', '<': 'LESS_THAN', '>': 'GREATER_THAN', '<=': 'LESS_THAN_OR_EQUAL', '>=': 'GREATER_THAN_OR_EQUAL', 'equal': 'EQUAL', 'not equal': 'NOT_EQUAL', 'less than': 'LESS_THAN', 'greater than': 'GREATER_THAN', 'greater than or equal': 'GREATER_THAN_OR_EQUAL', 'less than or equal': 'LESS_THAN_OR_EQUAL', 'starts with': 'STARTS_WITH', 'ends with': 'ENDS_WITH', 'null': 'null', '': 'EMPTY', 'isblank': 'EMPTY', 'isnotblank': 'NOT_EMPTY', 'contains': 'CONTAINS', 'notcontains': 'DOES_NOT_CONTAIN', 'startswith': 'STARTS_WITH', 'endswith': 'ENDS_WITH', 'NULL': 'NULL', 'NOT_NULL': 'NOT_NULL' }; let filterExpressionsArray = []; for ( let i = 0; i < filterExpressions.length; i++ ) { const filterExpression = filterExpressions[ i ]; const filterExpressionParts = filterExpression.indexOf( '"' ) === -1 ? filterExpression.split( ' ' ) : filterExpression.split( '"' ); let filter = []; for ( let j = 0; j < filterExpressionParts.length; j++ ) { const part = filterExpressionParts[ j ]; if ( part !== '' ) { filter.push( part.trim() ); } } filterExpressionsArray.push( filter ); } const filterGroup = new JQX.FilterGroup(); const filterGroupOperators = []; const filterSubGroups = []; for ( let i = 0; i < filterExpressionsArray.length; i++ ) { const filterExpression = filterExpressionsArray[ i ]; if ( filterExpression.length > 1 ) { const filterSubGroup = new JQX.FilterGroup(); let operator = 'and'; let filterExpressionPartsCounter = 0; for ( let j = 0; j < filterExpression.length; j++ ) { const value = filterExpression[ j ]; if ( value === 'and' || value === 'or' ) { operator = value; continue; } filterExpressionPartsCounter++; if ( filterExpressionPartsCounter === 2 ) { const filter = filterSubGroup.createFilter( dataType, value, filterOperators[ filterExpression[ j - 1 ] ] ); filterExpressionPartsCounter = 0; if ( operator ) { filterSubGroup.addFilter( operator, filter ); } } } filterSubGroups.push( filterSubGroup ); } else { const filterGroupOperator = filterExpression[ 0 ]; if ( filterGroupOperator !== 'and' && filterGroupOperator !== 'or' ) { throw new Error( 'Filter Exprresion expects "AND" or "OR", but the token is: ' + filterGroupOperator ); } filterGroupOperators.push( filterGroupOperator ); } } let operatorsCounter = 0; if ( filterSubGroups.length === 1 ) { return filterSubGroups[ 0 ]; } for ( let i = 0; i < filterSubGroups.length; i++ ) { let operator = filterGroupOperators[ operatorsCounter ]; if ( ( i + 1 ) % 2 === 0 ) { operatorsCounter++; } if ( !operator ) { operator = 'and'; } filterGroup.addFilter( operator, filterSubGroups[ i ] ); } return filterGroup; } filterBy( dataField, ...filterExpressions ) { const that = this; const dataType = ( () => { for ( let i = 0; i < that.dataFields.length; i++ ) { const field = that.dataFields[ i ]; if ( field.name === dataField ) { return field.dataType; } } } )(); const filterGroup = that._createFilter( dataType, filterExpressions ); let filteredData = that.boundSource.filter( ( value ) => { const evaluation = filterGroup.evaluate( value[ dataField ] ); return evaluation; } ); return filteredData; } _filter( filters, operator = 'and' ) { const that = this; const filterGroups = []; const dataFields = []; if ( filters.length === 0 ) { that.clearFilter(); return; } const dataType = ( dataField ) => { for ( let i = 0; i < that.dataFields.length; i++ ) { const field = that.dataFields[ i ]; if ( field.name === dataField ) { return field.dataType; } } }; let defaultResult, operatorSpecificEval; if ( operator === 'and' ) { defaultResult = true; operatorSpecificEval = function ( result, filterGroup, row ) { return result && filterGroup.evaluate( row[ filterGroup.dataField ] ); }; } else { defaultResult = false; operatorSpecificEval = function ( result, filterGroup, row ) { return result || filterGroup.evaluate( row[ filterGroup.dataField ] ); }; } for ( let i = 0; i < filters.length; i++ ) { const filter = filters[ i ]; const dataField = filter[ 0 ]; let filterGroup = null; if ( filter[ 1 ] instanceof JQX.FilterGroup ) { filterGroup = filter[ 1 ]; } else { filterGroup = that._createFilter( dataType( dataField ), filter.splice( 1 ) ); } if ( filterGroup ) { dataFields.push( dataField ); filterGroup.dataField = dataField; filterGroups.push( filterGroup ); } } if ( that.boundHierarchy ) { const filter = function ( row ) { let result = defaultResult; for ( let j = 0; j < filterGroups.length; j++ ) { const filterGroup = filterGroups[ j ]; result = operatorSpecificEval( result, filterGroup, row ); } row.$.filtered = result; return result; } const filterBy = function ( hierarchy, parentItem, root ) { let filteredCount = 0; for ( let i = 0; i < hierarchy.length; i++ ) { const item = hierarchy[ i ]; filter( item ); if ( item.$.filtered ) { filteredCount++; } if ( item[ 'children' ] ) { filterBy( item[ 'children' ], item, parentItem ); } } if ( filteredCount > 0 && that.groupBy.length > 0 && parentItem ) { parentItem.$.filtered = true; if ( root && !root.$.filtered ) { root.$.filtered = true; } } else { if ( filteredCount > 0 && filteredCount !== hierarchy.length && parentItem ) { parentItem.$.filtered = null; if ( root && !root.$.filtered ) { root.$.filtered = null; } } } } filterBy( that.boundHierarchy, null, null ); } else { for ( let i = 0; i < that.boundSource.length; i++ ) { const row = that.boundSource[ i ]; let result = defaultResult; for ( let j = 0; j < filterGroups.length; j++ ) { const filterGroup = filterGroups[ j ]; result = operatorSpecificEval( result, filterGroup, row ); } row.$.filtered = result; } } if ( that.onFilter ) { that.onFilter() } } clearGroup() { const that = this; that.groupBy = []; that.boundHierarchy = null; that.refreshHierarchy(); if ( that.onGroup ) { that.onGroup() } } clearFilter() { const that = this; for ( let i = 0; i < that.boundSource.length; i++ ) { const row = that.boundSource[ i ]; row.$.filtered = true; } if ( that.boundHierarchy ) { const filterBy = function ( hierarchy, parentItem, root ) { //let filteredCount = 0; for ( let i = 0; i < hierarchy.length; i++ ) { const item = hierarchy[ i ]; item.$.filtered = true; if ( item.$.filtered ) { //filteredCount++; } if ( item[ 'children' ] ) { filterBy( item[ 'children' ], item, parentItem ); } } if ( parentItem ) { parentItem.$.filtered = true; if ( root && !root.$.filtered ) { root.$.filtered = true; } } } filterBy( that.boundHierarchy, null, null ); } if ( that.onFilter ) { that.onFilter() } } clearSort() { const that = this; that._sort( that.boundSource, [], [], [] ); } _sort( dataSource, sortColumns, directions, dataTypes, customSortingCallback ) { const that = this; let isObservableArray = false; if ( dataSource.length === 0 ) { return; } if ( dataSource && dataSource.constructor && dataSource instanceof JQX.ObservableArray ) { isObservableArray = true; } if ( !dataSource || !( Array.isArray( dataSource ) ) || dataSource.length === 0 || !sortColumns || Array.isArray( sortColumns ) && sortColumns.length === 0 ) { if ( !isObservableArray && !that.boundHierarchy ) { throw new Error( 'sort: Missing or Invalid arguments!' ); } } if ( typeof sortColumns === 'string' ) { sortColumns = [ sortColumns ]; } const directionCoefficients = [], compareFunctions = []; if ( directions === undefined ) { directions = []; } const getCompareFunction = function ( a, knownDataType ) { // gets data type of column (not necessary if the Grid provides this information) const dataType = knownDataType || typeof a; let compareFunction; switch ( dataType ) { case 'string': compareFunction = new Intl.Collator().compare; break; case 'number': compareFunction = function ( a, b ) { return a - b; }; break; case 'boolean': case 'bool': compareFunction = function ( a, b ) { if ( a === b ) { return 0; } else if ( a === false ) { return -1; } else { return 1; } }; break; case 'date': case 'time': case 'dateTime': if ( a instanceof Date ) { compareFunction = function ( a, b ) { return a.getTime() - b.getTime(); }; } else if ( a instanceof JQX.Utilities.DateTime || a instanceof JQX.Utilities.BigNumber ) { compareFunction = function ( a, b ) { return a.compare( b ); }; } break; case 'object': if ( a instanceof Date ) { compareFunction = function ( a, b ) { return a.getTime() - b.getTime(); }; } else if ( a instanceof JQX.Utilities.DateTime || a instanceof JQX.Utilities.BigNumber ) { compareFunction = function ( a, b ) { return a.compare( b ); }; } else if ( a instanceof JQX.Utilities.Complex || ( window.NIComplex && a instanceof window.NIComplex ) ) { const complexNumericProcessor = new JQX.Utilities.ComplexNumericProcessor(); compareFunction = function ( a, b ) { return complexNumericProcessor.compareComplexNumbers( a, b ); } } break; } return compareFunction; } for ( let i = 0; i < sortColumns.length; i++ ) { if ( directions[ i ] === undefined || directions[ i ] === 'asc' || directions[ i ] === 'ascending' ) { directionCoefficients[ i ] = 1; } else { directionCoefficients[ i ] = -1; } const value = dataSource[ 0 ][ sortColumns[ i ] ]; compareFunctions[ i ] = getCompareFunction( value, dataTypes[ i ] ); } if ( customSortingCallback ) { customSortingCallback( dataSource, sortColumns, directions, compareFunctions ); return; } dataSource.sort( function ( a, b ) { for ( let i = 0; i < sortColumns.length; i++ ) { const result = compareFunctions[ i ]( a[ sortColumns[ i ] ], b[ sortColumns[ i ] ] ); if ( result === 0 ) { if ( sortColumns[ i + 1 ] ) { continue; } else if ( a._index !== undefined ) { // makes sorting stable return ( a._index - b._index ) * directionCoefficients[ i ]; } return 0; } return result * directionCoefficients[ i ]; } if ( sortColumns.length === 0 ) { if ( a.$.index < b.$.index ) { return -1; } if ( a.$.index > b.$.index ) { return 1; } return 0; } } ); for ( let i = 0; i < dataSource.length; i++ ) { that[ i ] = dataSource[ i ]; } } static Filter( dataSource, filterColumns, filterGroups, customFilteringCallback, operator = 'and' ) { let defaultResult, operatorSpecificEval; if ( operator === 'and' ) { defaultResult = true; operatorSpecificEval = function ( result, dataItem, filterColumn, filterGroup ) { if ( customFilteringCallback ) { return result && customFilteringCallback( dataItem, filterColumn, filterGroup ); } return result && filterGroup.evaluate( dataItem[ filterColumn ] ); }; } else { defaultResult = false; operatorSpecificEval = function ( result, dataItem, filterColumn, filterGroup ) { if ( customFilteringCallback ) { return result || customFilteringCallback( dataItem, filterColumn, filterGroup ); } return result || filterGroup.evaluate( dataItem[ filterColumn ] ); }; } const filteredData = dataSource.filter( ( dataItem ) => { let result = defaultResult; for ( let i = 0; i < filterGroups.length; i++ ) { const filterGroup = filterGroups[ i ]; const filterColumn = filterColumns[ i ]; result = operatorSpecificEval( result, dataItem, filterColumn, filterGroup ); } return result; } ); return filteredData; } filter( filterColumns, filterGroups, customFilteringCallback ) { JQX.ExcelAdapter.Filter( this.boundSource, filterColumns, filterGroups, customFilteringCallback ); } sort( sortColumns, directions, customSortingCallback ) { JQX.ExcelAdapter.Sort( this.boundSource, sortColumns, directions, customSortingCallback ); } static Sort( dataSource, sortColumns, directions, customSortingCallback ) { const getCompareFunction = function ( a ) { // gets data type of column (not necessary if the Grid provides this information) const dataType = typeof a; let compareFunction; switch ( dataType ) { case 'string': compareFunction = new Intl.Collator().compare; break; case 'number': compareFunction = function ( a, b ) { return a - b; }; break; case 'boolean': compareFunction = function ( a, b ) { if ( a === b ) { return 0; } else if ( a === false ) { return -1; } else { return 1; } }; break; case 'object': if ( a instanceof Date ) { compareFunction = function ( a, b ) { return a.getTime() - b.getTime(); }; } else if ( a instanceof JQX.Utilities.DateTime || a instanceof BigNumberNG ) { compareFunction = function ( a, b ) { return a.compare( b ); }; } else if ( a instanceof JQX.Utilities.Complex || ( window.NIComplex && a instanceof window.NIComplex ) ) { const complexNumericProcessor = new JQX.Utilities.ComplexNumericProcessor(); compareFunction = function ( a, b ) { return complexNumericProcessor.compareComplexNumbers( a, b ); } } break; } return compareFunction; } if ( !dataSource || !( Array.isArray( dataSource ) ) || dataSource.length === 0 || !sortColumns || Array.isArray( sortColumns ) && sortColumns.length === 0 ) { return; } if ( typeof sortColumns === 'string' ) { sortColumns = [ sortColumns ]; } const directionCoefficients = [], compareFunctions = []; if ( directions === undefined ) { directions = []; } for ( let i = 0; i < sortColumns.length; i++ ) { if ( directions[ i ] === undefined || directions[ i ] === 'asc' || directions[ i ] === 'ascending' ) { directionCoefficients[ i ] = 1; } else { directionCoefficients[ i ] = -1; } compareFunctions[ i ] = getCompareFunction( dataSource[ 0 ][ sortColumns[ i ] ] ); } if ( customSortingCallback ) { customSortingCallback( dataSource, sortColumns, directions, compareFunctions ); return; } const sortedData = dataSource.slice( 0 ); sortedData.sort( function ( a, b ) { for ( let i = 0; i < sortColumns.length; i++ ) { const result = compareFunctions[ i ]( a[ sortColumns[ i ] ], b[ sortColumns[ i ] ] ); if ( result === 0 ) { if ( sortColumns[ i + 1 ] ) { continue; } else if ( a._index !== undefined ) { // makes sorting stable return ( a._index - b._index ) * directionCoefficients[ i ]; } return 0; } return result * directionCoefficients[ i ]; } } ); return sortedData; } } window.jqxDataSource = DataAdapter; class Ajax { constructor ( config, callback ) { const that = this; that.config = config; that.callback = callback; if ( config.autoFetch === false ) { return; } that.call( config ); } call( config ) { const that = this; if ( !config ) { config = that.config; } let method = 'GET', url = config.url, body = null, async = true; if ( config.type ) { method = config.type; } if ( config.data ) { if ( method === 'GET' ) { url += '?'; for ( let prop in config.data ) { if ( config.data.hasOwnProperty( prop ) ) { url += encodeURI( prop + '=' + config.data[ prop ] + '&' ); } } if ( url.charAt( url.length - 1 ) === '&' ) { url = url.slice( 0, url.length - 1 ); } } else if ( method === 'POST' ) { body = JSON.stringify( config.data ); } } if ( config && config.async === false && config.dataSourceType !== 'xlsx' ) { async = false; } if ( window.fetch !== undefined && async ) { that.ajaxFetch( config, method, url, body ); } else { that.ajaxXMLHttpRequest( config, method, url, body, async ); } } ajaxFetch( config, method, url, body ) { // prepare fetch config const that = this; const fetchInit = { method: method }; let parseMethod; switch ( config.dataSourceType ) { case 'json': parseMethod = 'json'; break; case 'xlsx': parseMethod = 'arrayBuffer'; break; default: parseMethod = 'text'; } if ( config ) { if ( config.contentType ) { fetchInit.headers = new Headers( { 'Content-Type': config.contentType } ); } } if ( body !== null ) { fetchInit.body = body; } let status, fetchTimeout, timeouted; if ( config.timeout ) { fetchTimeout = setTimeout( function () { timeouted = true; }, config.timeout ); } if ( config.beforeSend ) { const beforeSendResult = config.beforeSend( fetchInit, config ); if ( beforeSendResult === false ) { return; } } // fetch resource fetch( url, fetchInit ) .then( function ( response ) { if ( timeouted ) { status = 408; throw new Error( 'timeout' ); } if ( fetchTimeout ) { clearTimeout( fetchTimeout ); } status = response.status; if ( !response.ok ) { throw new Error( response.statusText ); } return response[ parseMethod ](); } ) .then( function ( data ) { if ( parseMethod === 'arrayBuffer' ) { return JSZip.loadAsync( data ).then( function ( zipData ) { // "data" represents the whole XLSX/ZIP file return zipData.files[ 'xl/worksheets/sheet1.xml' ].async( 'text' ).then( function ( sheet1 ) { return zipData.files[ 'xl/sharedStrings.xml' ].async( 'text' ).then( function ( sharedStrings ) { const parsedData = that.parseXLSXData( sheet1, sharedStrings ); that.ajaxComplete( config, parsedData, status ); } ); } ); } ); } else { that.ajaxComplete( config, data, status ); } } ) .catch( function ( error ) { if ( error.message === 'JSZip is not defined' ) { error.message = 'JSZip is not defined. Please include a reference to JSZip to be able to load data from XLSX files.'; } if ( config && config.loadError ) { config.loadError( status, error ); } if ( that.callback ) { that.callback( error, status ); } } ); } ajaxXMLHttpRequest( config, method, url, body, async ) { const request = new XMLHttpRequest(); const that = this; request.open( method, url, async ); request.ontimeout = function () { if ( config && config.loadError ) { config.loadError( 408, 'timeout' ); } }; request.onload = function () { if ( request.readyState === 4 ) { const status = request.status; let data = request.response; if ( status >= 200 && status <= 299 ) { if ( config.dataSourceType === 'json' ) { data = JSON.parse( data ); } that.ajaxComplete( config, data, status ); } else if ( config && config.loadError ) { config.loadError( status, data ); } } }; request.onerror = function () { if ( config && config.loadError ) { config.loadError( request.status, request.response ); } }; if ( config && config.contentType ) { request.setRequestHeader( 'Content-Type', config.contentType ); } if ( async && config.timeout ) { request.timeout = config.timeout; } if ( config.beforeSend ) { const beforeSendResult = config.beforeSend( request, config ); if ( beforeSendResult === false ) { return; } } request.send( body ); } ajaxComplete( config, data, status ) { if ( !config ) { return; } if ( config.beforeLoadComplete ) { const processedData = config.beforeLoadComplete( data ); if ( processedData ) { data = processedData; } } if ( config.loadComplete ) { config.loadComplete( data, status ); } if ( this.callback ) { this.callback( data, status ); } } parseXLSXData( sheet1, sharedStrings ) { const parser = new DOMParser(), sharedStringsDocument = parser.parseFromString( sharedStrings, 'text/xml' ), sharedStringsContainers = Array.from( sharedStringsDocument.getElementsByTagName( 'si' ) ), sharedStringsCollection = [], sheet1Document = parser.parseFromString( sheet1, 'text/xml' ), rows = Array.from( sheet1Document.getElementsByTagName( 'row' ) ), parsedData = []; sharedStringsContainers.forEach( function ( si ) { let texts = si.getElementsByTagName( 't' ); if ( texts.length === 1 ) { sharedStringsCollection.push( texts[ 0 ].innerHTML ); } else { let text = ''; texts = Array.from( texts ); texts.forEach( function ( t ) { text += t.innerHTML; } ); sharedStringsCollection.push( text ); } } ); rows.forEach( function ( row ) { const rowObject = {}, cells = Array.from( row.getElementsByTagName( 'c' ) ); cells.forEach( function ( cell/*, index*/ ) { const column = cell.getAttribute( 'r' ).match( /\D+/ )[ 0 ], type = cell.getAttribute( 't' ), xmlValue = cell.getElementsByTagName( 'v' )[ 0 ].innerHTML; let value; switch ( type ) { case 's': // string value = sharedStringsCollection[ parseFloat( xmlValue ) ]; break; case 'b': // boolean value = parseFloat( xmlValue ) === 1; break; default: // number or date value = parseFloat( xmlValue ); } rowObject[ column ] = value; } ); parsedData.push( rowObject ); } ); return parsedData; } } if ($.jqx && $.jqx.dataAdapter) { $.jqx.dataAdapter.Importer = DataAdapter; } })(jqxBaseFramework);