angular.module('sba-crud-table', []) .directive("sbaCrudTable", function() { return { restrict: 'E', templateUrl: "/sbadirective/load/sba-crud-table.html", scope: { myTable: '=' }, controller: function($rootScope, $scope, $http, $filter, $q, $interval, $timeout, $window, $sce) { $scope.currentTime = Date.now(); $scope.page = 0; $scope.cntFilteredItems = 0; $scope.cntSubQueriesTodo = 0; $scope.cacheReadOnly = false; $scope.unknownFields = []; $scope.sortRows = []; $scope.loading = true; $scope.panelClass = 'panel-default'; $scope.showFilters = true; $scope.combobox = {}; $scope.checkModalRequired = false; $scope.filteredOptions = {}; if (!$scope.myTable) { console.log('sba-crud-table: my-table attribute needs to be defined'); return; } $scope.baseURL = '/'; if($scope.myTable.baseURL !== undefined){ $scope.baseURL = $scope.myTable.baseURL; } //initiate labels if ($scope.myTable.labels === undefined) { $scope.myTable.labels = []; } $scope.labels = { 'ready': 'Ready', 'processSubFields': 'Process subFields', 'alreadyLoaded': 'already loaded in data.', 'errorInFetching': 'Error in fetching', 'dataAvailable': 'Data already available', 'loading': 'Loading...', 'selectLabel': 'Select an option ...', }; angular.forEach($scope.labels, function(lblLabel, lblName){ if($scope.myTable.labels[lblName] === undefined){ $scope.myTable.labels[lblName] = lblLabel; } }); if (!$scope.myTable.controller) { console.log('sba-crud-table: controller needs to be defined for my-table'); return; } /*---[Summernote config]---*/ $scope.summernoteoptions = { toolbar: [ ['edit',['undo','redo']], ['headline', ['style']], ['style', ['bold', 'italic', 'underline', 'clear']], ['fontface', ['fontname']], ['textsize', ['fontsize']], ['fontclr', ['color']], ['alignment', ['ul', 'ol', 'paragraph', 'lineheight']], ['height', ['height']], ['table', ['table']], ['insert', ['link', 'hr', 'picture']], ['view', ['fullscreen', 'codeview']], ], }; $scope.toTrusted = function(data) { if (typeof data == 'string') { return $sce.trustAsHtml(data); } return data; } /*---[CSV]---*/ $scope.getCSV = function(){ if($scope.myTable.controller){ if ( window.confirm('Do you want a CSV file?') ) { if ( window.confirm('Include the table data?') ) { tmpCSVurl = $scope.myTable.controller + '/' + 'getCSV/true'; if($scope.myTable.getCSVurl){ tmpCSVurl = $scope.myTable.getCSVurl + '/true'; } $window.open($scope.baseURL + tmpCSVurl, '_blank'); }else{ tmpCSVurl = $scope.myTable.controller + '/' + 'getCSV'; if($scope.myTable.getCSVurl){ tmpCSVurl = $scope.myTable.getCSVurl; } $window.open($scope.baseURL + tmpCSVurl, '_blank'); } } } } /*------------------------------------------------------*/ $scope.buttons = { 'C':{ 'id': 'c', // 'name': 'Add Row', 'name': 'Add ' + ($scope.myTable.label ? $scope.myTable.label : ($scope.myTable.name ? $scope.myTable.name : 'Row')), 'confirmName': 'Insert', 'confirmClass': 'success', 'icon': 'fa-plus-square', 'header': true, 'action': 'create', }, 'DA':{ 'id': 'da', // 'name': 'Delete Selected Rows', 'name': 'Delete Selected ' + ($scope.myTable.label ? $scope.myTable.label : ($scope.myTable.name ? $scope.myTable.name : 'Rows')), 'confirmName': 'Delete Selected Rows', 'confirmClass': 'success', 'icon': 'fa-trash', 'header': false, 'inline': false, 'noFields': true, 'action': 'deleteMany', }, 'putCSV':{ 'id': 'putCSV', 'name': 'Upload CSV data', 'confirmName': 'Upload data', 'confirmClass': 'success', 'icon': 'fa-table', 'header': false, 'inline': false, 'noFields': true, 'action': 'putCSV', }, 'R':{ 'id': 'r', // 'name': 'View Row', 'name': 'View ' + ($scope.myTable.label ? $scope.myTable.label : ($scope.myTable.name ? $scope.myTable.name : 'Row')), 'confirmName': 'View', 'confirmClass': 'info', 'inline': true, 'header': false, 'icon': 'fa-search', 'action': 'read', }, 'U':{ 'id': 'u', // 'name': 'Update Row', 'name': 'Update ' + ($scope.myTable.label ? $scope.myTable.label : ($scope.myTable.name ? $scope.myTable.name : 'Row')), 'confirmName': 'Update', 'confirmClass': 'success', 'inline':true, 'icon':'fa-pencil', 'action': 'update', }, 'D':{ 'id': 'd', // 'name': 'Delete Row', 'name': 'Delete ' + ($scope.myTable.label ? $scope.myTable.label : ($scope.myTable.name ? $scope.myTable.name : 'Row')), 'confirmName': 'Delete', 'confirmClass': 'warning', 'inline':true, 'icon':'fa-trash', 'action': 'delete', }, }; /*----[get + put CSV]-----*/ $scope.myTable.enableGetCSV = function(blnSet){ $scope.showCSV = blnSet; } $scope.myTable.enablePutCSV = function(blnSet){ $scope.buttons['putCSV']['header'] = blnSet; } /*---[inline edit]-----*/ $scope.inlineEdit = function($event, row, fieldName){ //check if inline edit enabled if($scope.myTable.inlineEditEnabled){ //old inline document restore if(!$scope.inlineEditValues){ $scope.inlineEditValues = { enabled: true, }; } if($event.currentTarget.id && !$scope.inlineEditValues){ var element = document.getElementById($event.currentTarget.id); $scope.inlineEditValues.value = element.innerHTML; btn = $scope.buttons['U']; $scope.processBtns(btn,row,false); } } } /*----------[ get selected ]----------------------*/ $scope.getSelectedCount = function(){ if($scope.myTable.selectable){ $scope.myTable.selectedItems = $filter('filter')($scope.myTable.data.rows, {'sba_selected': true}); if ($scope.myTable.selectedItems.length !== undefined) { return ' | Selected: ' + $scope.myTable.selectedItems.length; } } } /*----------[ option classes ]------------*/ $scope.getClasses = function(fieldName){ strClasses = ""; if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[fieldName] && $scope.myTable.fieldDetails[fieldName].class){ objClass = $scope.myTable.fieldDetails[fieldName].class; angular.forEach(objClass, function(strClass){ strClasses = strClasses + ' ' + strClass; }); } return strClasses; } $scope.getSelectedOptions = function(fieldName, fieldOptions) { value = $scope.myTable.modal.data[fieldName]; if (!angular.isArray(value)) { return []; } result = $filter('filter')(fieldOptions, function(option) { return value.indexOf(option.id) !== -1; }, true); if (result && result.length) { return result; } else { return []; } } $scope.removeSelectedOption = function(fieldName, fieldOptions, option) { value = $scope.myTable.modal.data[field.name]; if (!angular.isArray(value) || !option || !option.id) { return false; } index = value.indexOf(option.id); if (index !== -1) { value.splice(index, 1); } $scope.myTable.modal.data[field.name] = value; return true; } $scope.selectedOptionFilter = function(field) { value = $scope.myTable.modal.data[field.name]; if (!angular.isArray(value)) { return function(option) { return true; } } return function(option) { return option && option.id && value.indexOf(option.id) === -1; } } /*-------[field Options]----------------*/ $scope.changeFieldTrigger = function(fieldName, fieldValue, eventType){ //update to parent scope if($scope.$parent['sbaCrudTableChange']){ $scope.$parent['sbaCrudTableChange']($scope.myTable.name, fieldName, fieldValue, eventType); } } $scope.myTable.setCombobox = function(fieldName, fieldId) { if($scope.combobox[field.name] !== undefined && fieldName !== undefined && fieldId !== undefined && $scope.myTable.modal.data[fieldName] !== undefined){ searchField = $filter('filter')($scope.myTable.modal.fields, {'name': fieldName}); if(searchField[0] && searchField[0].options){ searchFieldOptions = $filter('filter')(searchField[0].options, {'id': fieldId}); if(searchFieldOptions[0]){ $scope.myTable.modal.data[fieldName] = fieldId; $scope.combobox[fieldName] = searchFieldOptions[0].label; }else{ $scope.myTable.modal.data[fieldName] = null; $scope.combobox[fieldName] = searchField[0].options[0].label; } } } } $scope.checkOptions = function(fieldName, fieldOptions, eventType, multiselect) { if (!multiselect) { multiselect = false; } init = false; if($scope.combobox[fieldName] === undefined){ init = true; $scope.combobox[fieldName] = ""; } //field field = {}; field.options = fieldOptions; field.name = fieldName; field.value = $scope.myTable.modal.data[field.name]; field.label = $scope.getOptionLabel(field); switch(eventType){ case 'delete': if (multiselect) { $scope.myTable.modal.data[field.name] = []; } else { $scope.myTable.modal.data[field.name] = 0; } field.value = 0; $scope.combobox[field.name] = ""; $scope.resetOption(field); //update to parent scope if($scope.$parent['sbaCrudTableChange']){ $scope.$parent['sbaCrudTableChange']($scope.myTable.name, fieldName, null, eventType); } break; case 'checkDelete': //initiate if(init){ $scope.checkOptions(fieldName, fieldOptions, 'init'); } if($scope.combobox[field.name] && $scope.combobox[field.name].length > 0 && field.label){ return true; }else{ return false; } break; case 'click': if(!field.label){ $scope.combobox[field.name] = ""; } break; case 'change': objFilter = $filter('filter')(field.options , {'label': $scope.combobox[field.name]}); if (objFilter.length == 1) { if (multiselect) { // must equal exactly to add if (objFilter[0]['label'] == $scope.combobox[field.name]) { $scope.myTable.modal.data[field.name].push(objFilter[0].id); } } else { $scope.myTable.modal.data[field.name] = objFilter[0].id; } //update to parent scope if($scope.$parent['sbaCrudTableChange']){ $scope.$parent['sbaCrudTableChange']($scope.myTable.name, fieldName, objFilter[0], eventType); } } else { if (!multiselect) { $scope.myTable.modal.data[field.name] = 0; } } $scope.checkRequired(); break; case 'init': if(field.label){ $scope.combobox[field.name] = field.label; }else{ $scope.resetOption(field); } $scope.checkRequired(); break; case 'blur': objFilter = $filter('filter')(field.options , {'label': $scope.combobox[fieldName]}); if (objFilter.length == 1) { if (!multiselect) { $scope.myTable.modal.data[field.name] = objFilter[0].id; } $scope.combobox[fieldName] = objFilter[0].label; } else { if (!multiselect) { $scope.myTable.modal.data[field.name] = 0; } field.value = 0; } $scope.checkRequired(); break; } } $scope.getOptionLabel = function(field) { if(field.value == null || field.value == 0){ return false; } if (angular.isArray(field.value)) { return false; } result = $filter('filter')(field.options, {'id': field.value}, true); if(result && result.length == 1 && result[0] && result[0].label){ return result[0].label; }else{ return false; } } $scope.resetOption = function(field){ //default if(field.value == 0 && field.options[0]){ $scope.combobox[field.name] = field.options[0].label; }else if(!field.value){ $scope.combobox[field.name] = angular.copy($scope.myTable.labels.selectLabel); } } $scope.checkDisabledModal = function(btn, part){ if(btn && btn.id){ switch(part){ case 'confirm': return (btn.id.toLowerCase() == 'r'); break; case 'field': return (btn.id.toLowerCase() == 'r' || btn.id.toLowerCase() == 'd'); break; } } } $scope.optionFilter = function(field) { if (!$scope.myTable.fieldDetails || ($scope.myTable.fieldDetails && !$scope.myTable.fieldDetails[field.name]) || ($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name] &&!$scope.myTable.fieldDetails[field.name].optionFilter)) { return function(item) { return true; }; } return function(item) { var filters = $scope.myTable.fieldDetails[field.name].optionFilter; if (!Array.isArray(filters)) { filters = [filters]; } var show = true; angular.forEach(filters, function(filter) { if (filter.ffield === undefined || filter.lfield === undefined || filter.controller === undefined || $scope.myTable.data[filter.controller] === undefined) { return; } //lfield - > subtable field //ffield - > current row filterValue = {}; filterValue[filter.lfield] = $scope.myTable.modal.data[filter.ffield]; filterValue['id'] = item.id; fltOptions = $filter('filter')($scope.myTable.data[filter.controller], filterValue, true); show = show && (fltOptions && fltOptions[0]); }); return show; } } /*--------------buttons----------------*/ $scope.checkRequired = function(){ if(!$scope.myTable.modal.btn){ return ; } blnSubmit = false; angular.forEach($scope.myTable.modal.fields, function(field) { if (blnSubmit) { return; } if(!$scope.myTable.fieldDetails){ $scope.myTable.fieldDetails = {}; } if(!$scope.myTable.modal.data){ $scope.myTable.modal.data = {}; } if (field.required && ($scope.myTable.modal.data[field.name] === undefined || ($scope.myTable.modal.data[field.name] !== undefined && ($scope.myTable.modal.data[field.name] == null || $scope.myTable.modal.data[field.name] == "" || $scope.myTable.modal.data[field.name] == 0 || (field.type == 'number' && isNaN($scope.myTable.modal.data[field.name])))))) { $scope.myTable.modal.btn.description = '(warning) Field ' + field.label + ' is required.'; blnSubmit = true; } }); if(!blnSubmit){ $scope.myTable.modal.btn.description = ''; } $scope.checkModalRequired = blnSubmit; } $scope.closeModal = function(){ $scope.myTable.showModal = !$scope.myTable.showModal; if($scope.$parent['modalClose']){ $scope.$parent['modalClose']($scope.myTable.name); } } $scope.doBtn = function(btn, row, blnSubmit){ if(!blnSubmit){ blnSubmit = false; } if(!row){ row = {}; } if(btn && btn.action){ if(btn.parentScope){ $scope.$parent[btn.action](btn, row, blnSubmit); }else if($scope[btn.action]){ $scope[btn.action](btn, row, blnSubmit); } } } $scope.btnWhere = function(btn, row){ if(btn.where && btn.whereField){ tmpWhere = btn.where; tmpWhereField = btn.whereField; //array of 2 parts if(angular.isObject(tmpWhere)){ blnResult = false; angular.forEach(tmpWhere, function(right, compare){ if(!btn.whereOnChangeTo && row['original_' + tmpWhereField]){ left = row['original_' + tmpWhereField]; }else{ left = row[tmpWhereField]; } if(doCompare(left,compare,right)){ blnResult = true; } }); return blnResult; } }else{ return true; } } $scope.putCSV = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.update = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.create = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.read = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.delete = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.deleteMany = function(btn, row, blnSubmit){ $scope.processBtns(btn,row,blnSubmit) } $scope.myTable.toggleButton = function(btn, row, blnSubmit){ $scope.processBtns(btn, row, blnSubmit); } $scope.processBtns = function(btn, row, blnSubmit){ if(!blnSubmit){ $scope.myTable.showModal = true; $scope.myTable.modal = {}; $scope.myTable.modal.fields = []; $scope.myTable.modal.data = []; if(!btn.noFields){ $scope.myTable.modal.fields = $scope.myTable.data.fields; $scope.myTable.modal.data = $scope.restoreOriginals(angular.copy(row)); } options = $scope.getAllOptions(); angular.forEach($scope.myTable.modal.fields, function(field){ if (options[field.name]) { if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name] && $scope.myTable.fieldDetails[field.name].type && $scope.myTable.fieldDetails[field.name].type != 'number'){ field.type = $scope.myTable.fieldDetails[field.name].type; }else{ field.type = 'combobox'; } field.options = options[field.name]; if (!$scope.myTable.modal.data[field.name]) { if ($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name] && $scope.myTable.fieldDetails[field.name].link) { $scope.myTable.modal.data[field.name] = []; } else if ($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name] && $scope.myTable.fieldDetails[field.name].default) { $scope.myTable.modal.data[field.name] = $scope.myTable.fieldDetails[field.name].default; } else { $scope.myTable.modal.data[field.name] = 0; } } if ($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name]) { fieldDetails = $scope.myTable.fieldDetails[field.name]; //required value if(fieldDetails.required !== undefined && !fieldDetails.hideEdit){ field.required = fieldDetails.required; } //label value if(fieldDetails.label !== undefined){ field.label = fieldDetails.label; }else{ field.label = field.name; } } } else if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field.name] && $scope.myTable.fieldDetails[field.name].type) { fieldDetails = $scope.myTable.fieldDetails[field.name]; //required value if(fieldDetails.required !== undefined && !fieldDetails.hideEdit){ field.required = fieldDetails.required; } //label value if(fieldDetails.label !== undefined){ field.label = fieldDetails.label; }else{ field.label = field.name; } //datetime convertion if(fieldDetails.type == 'datetime'){ field.type = fieldDetails.type; //datetime if($scope.myTable.modal.data[field.name] && $scope.myTable.modal.data[field.name] =="0000-00-00 00:00:00"){ $scope.myTable.modal.data[field.name] = null; } if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = new Date(fieldDetails.default); }else if(!$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = null; } }else if(fieldDetails.type == 'date'){ //date field field.type = fieldDetails.type; //date if($scope.myTable.modal.data[field.name] && $scope.myTable.modal.data[field.name] =="0000-00-00"){ $scope.myTable.modal.data[field.name] = null; } if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = new Date(fieldDetails.default); }else if(!$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = null; } }else if(fieldDetails.type == 'time'){ //time field field.type = fieldDetails.type; //default if($scope.myTable.modal.data[field.name] && ($scope.myTable.modal.data[field.name] =="00:00:00" || $scope.myTable.modal.data[field.name] =="00:00")){ $scope.myTable.modal.data[field.name] = null; } if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; }else if(!$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = null; } }else if(fieldDetails.type == 'boolean' && fieldDetails.booleanOn !== undefined && fieldDetails.booleanOff !== undefined){ if(!$scope.myTable.modal.data[field.name] || ($scope.myTable.modal.data[field.name] != fieldDetails.booleanOff && $scope.myTable.modal.data[field.name] != fieldDetails.booleanOn)){ //default if(fieldDetails.default && (fieldDetails.default == fieldDetails.booleanOff || fieldDetails.default == fieldDetails.booleanOn)){ $scope.myTable.modal.data[field.name] = fieldDetails.default; }else{ $scope.myTable.modal.data[field.name] = false; } }else if($scope.myTable.modal.data[field.name] == fieldDetails.booleanOn){ $scope.myTable.modal.data[field.name] = true; }else if($scope.myTable.modal.data[field.name] == fieldDetails.booleanOff){ $scope.myTable.modal.data[field.name] = false; } field.type = fieldDetails.type; field.booleanOn = fieldDetails.booleanOn; field.booleanOff = fieldDetails.booleanOff; }else if(fieldDetails.type == 'textarea'){ field.type = fieldDetails.type; //check for wysiwyg if (fieldDetails.wysiwyg) { field.wysiwyg = fieldDetails.wysiwyg; } //default if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; } }else if(fieldDetails.type == 'number'){ field.type = fieldDetails.type; $scope.myTable.modal.data[field.name] = parseFloat($scope.myTable.modal.data[field.name]); //default if(fieldDetails.default !== undefined && !isNaN(fieldDetails.default) && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; } }else if(fieldDetails.type == 'password'){ field.type = fieldDetails.type; $scope.myTable.modal.data[field.name] = ''; //default if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; } //placeholder if(fieldDetails.placeholder){ field.placeholder = fieldDetails.placeholder; } }else if(fieldDetails.type == 'enum' && fieldDetails.options && fieldDetails.options.length){ field.type = fieldDetails.type; //default if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; } }else if(fieldDetails.type == 'file' && fieldDetails.uploadFileUrl !== undefined && fieldDetails.uploadFileUrl){ field.type = fieldDetails.type; // reset error message field.uploadFileError = ''; // set description if (fieldDetails.dropzoneDescription !== undefined && fieldDetails.dropzoneDescription) { field.dropzoneDescription = fieldDetails.dropzoneDescription; } // set upload url if (fieldDetails.uploadFileUrl !== undefined && fieldDetails.uploadFileUrl) { field.uploadFileUrl = fieldDetails.uploadFileUrl; } // set multiple if (fieldDetails.multiple !== undefined) { field.multiple = fieldDetails.multiple; } // set fetch url if (fieldDetails.fetchFileUrl !== undefined && fieldDetails.fetchFileUrl) { field.fetchFileUrl = fieldDetails.fetchFileUrl; } //default if (fieldDetails.default && !$scope.myTable.modal.data[field.name]) { $scope.myTable.modal.data[field.name] = fieldDetails.default; } else if (!$scope.myTable.modal.data[field.name] || !Array.isArray($scope.myTable.modal.data[field.name])) { if (fieldDetails.multiple) { $scope.myTable.modal.data[field.name] = []; } } }else{ field.type = 'text'; //default if(fieldDetails.default && !$scope.myTable.modal.data[field.name]){ $scope.myTable.modal.data[field.name] = fieldDetails.default; } //placeholder if(fieldDetails.placeholder){ field.placeholder = fieldDetails.placeholder; } } } }); $scope.myTable.modal.btn = btn; $scope.combobox = {}; //check modal for required fields $scope.checkRequired(); //parent function if($scope.$parent['modalReady']){ $scope.$parent['modalReady']($scope.myTable.name); } }else{ copyRow = angular.copy(row); if($scope.myTable.modal !== undefined && $scope.myTable.modal.fields !== undefined){ angular.forEach($scope.myTable.modal.fields, function(field){ switch(field.type) { case 'password': if(copyRow[field.name] == ''){ delete copyRow[field.name]; } break; case 'file': if (copyRow[field.name] && (field.multiple == undefined || field.multiple == 1)){ copyRow[field.name] = JSON.stringify(copyRow[field.name]); } break; case 'boolean': if (copyRow[field.name]) { copyRow[field.name] = field.booleanOn; }else{ copyRow[field.name] = field.booleanOff; } break; case 'datetime': if(copyRow[field.name]){ copyRow[field.name] = $scope.convertDateObjToJS(copyRow[field.name], true, field.type); }else{ copyRow[field.name] = null; } break; case 'date': if(copyRow[field.name]){ copyRow[field.name] = $scope.convertDateObjToJS(copyRow[field.name], true, field.type); }else{ copyRow[field.name] = null; } break; case 'time': if(copyRow[field.name]){ copyRow[field.name] = $scope.convertDateObjToJS(copyRow[field.name], true, field.type); }else{ copyRow[field.name] = null; } break; default: break; } }); } //btn actions switch(btn.action){ case "deleteMany": //delete all $scope.showModalMessage('Sending delete data', 0); postIds = ''; angular.forEach($scope.myTable.selectedItems, function(selectedItem){ postIds = postIds + selectedItem.id + '-'; }); $http.get($scope.baseURL + $scope.myTable.controller + '/deleteMany/' + postIds).then( function(response){ if(response.data.status){ $scope.showModalMessage('Delete OK'); angular.forEach($scope.myTable.selectedItems, function(selectedItem){ searchRow = $filter('filter')($scope.myTable.data.rows, {'id': selectedItem.id}); if(searchRow[0]){ searchRowIndex = $scope.myTable.data.rows.indexOf(searchRow[0]); } $scope.myTable.data.rows.splice(searchRowIndex, 1); }); }else{ if(response.data.message){ $scope.showModalMessage(response.data.message, 0); }else{ $scope.showModalMessage('Delete Not OK', 0); } } }, function(response){ $scope.showModalMessage('Error in fetching', 0); } ); break; case "putCSV": //upload csv if(document.getElementById('csv_file').files[0]){ $scope.showModalMessage('Sending CSV', 0); var data = new FormData(); data.append("file", document.getElementById('csv_file').files[0]); tmpCSVurl = $scope.myTable.controller + '/putCSV'; if($scope.myTable.putCSVurl){ tmpCSVurl = $scope.myTable.putCSVurl; } $http( { url: $scope.baseURL + tmpCSVurl, data: data, headers: {'Content-Type': undefined }, transformRequest: angular.identity, method: 'POST', }).then( function(response){ if(response.data.status){ // initiate updated variables var isUpdated = false; // loop through results angular.forEach(response.data.data, function(dataRow){ //insert or update if(dataRow.id){ searchRow = $filter('filter')($scope.myTable.data.rows, {'id': dataRow.id}); //update if(searchRow[0]){ searchRowIndex = $scope.myTable.data.rows.indexOf(searchRow[0]); $scope.myTable.data.rows[searchRowIndex] = dataRow; }else{ //insert $scope.myTable.data.rows.push(dataRow); } isUpdated = true; } }); // initiate table if any row is updated if (isUpdated) { $scope.initiate(); } $scope.showModalMessage('CSV processed'); }else{ if(response.data.message){ $scope.showModalMessage(response.data.message, 0); }else{ $scope.showModalMessage('CSV Not OK', 0); } } }, function(response){ $scope.showModalMessage('Error in fetching', 0); } ); }else{ $scope.showModalMessage('No CSV selected', 0); } break; default: //other actions //send to server if(row.id){ //delete or update if(btn.action == 'update'){ //update $scope.showModalMessage('Sending update data', 0); postId = copyRow.id; delete copyRow.id; $http.post($scope.baseURL + $scope.myTable.controller + '/update/' + postId, copyRow, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).then( function(response){ if(response.data.status){ $scope.showModalMessage('Update OK'); //callback to parent if($scope.$parent['afterChange'] !== undefined){ $scope.$parent['afterChange']($scope.myTable.name, response.data.data, 'UPDATE'); } // update link table if needed isLinkUpdate = $scope.updateLinkTable(row); searchRow = $filter('filter')($scope.myTable.data.rows, {'id': row.id}); if(searchRow[0]){ searchRowIndex = $scope.myTable.data.rows.indexOf(searchRow[0]); } $scope.myTable.data.rows[searchRowIndex] = response.data.data; if (!isLinkUpdate) { $scope.processSubFields(response.data.data.id); } }else{ if(response.data.message){ $scope.showModalMessage(response.data.message, 0); }else{ $scope.showModalMessage('Update Not OK', 0); } } }, function(response){ $scope.showModalMessage('Error in fetching', 0); } ); } else if(btn.action == 'delete'){ //delete $scope.showModalMessage('Sending delete data', 0); postId = copyRow.id; delete copyRow.id; $http.get($scope.baseURL + $scope.myTable.controller + '/delete/' + postId).then( function(response){ if(response.data.status){ searchRow = $filter('filter')($scope.myTable.data.rows, {'id': postId}); if(searchRow[0]){ // update link table if needed copyRow.id = postId; angular.forEach($scope.myTable.fieldDetails, function(details, field) { if (details.link !== undefined) { copyRow[field] = []; } }); //callback to parent if($scope.$parent['afterChange'] !== undefined){ $scope.$parent['afterChange']($scope.myTable.name, searchRow[0], 'DELETE'); } $scope.updateLinkTable(copyRow); // delete row from rows searchRowIndex = $scope.myTable.data.rows.indexOf(searchRow[0]); $scope.myTable.data.rows.splice(searchRowIndex, 1); $scope.showModalMessage('Delete OK'); }else{ $scope.showModalMessage('Delete Not OK', 0); } }else{ if(response.data.message){ $scope.showModalMessage(response.data.message, 0); }else{ $scope.showModalMessage('Delete Not OK', 0); } } }, function(response){ $scope.showModalMessage('Error in fetching', 0); } ); } }else{ //add $scope.showModalMessage('Sending insert data', 0); postId = copyRow.id; delete copyRow.id; $http.post($scope.baseURL + $scope.myTable.controller + '/insert', copyRow, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).then( function(response){ if(response.data.status){ $scope.showModalMessage('Insert OK'); $scope.myTable.data.rows.push(response.data.data); //callback to parent if($scope.$parent['afterChange'] !== undefined){ $scope.$parent['afterChange']($scope.myTable.name, response.data.data, 'CREATE'); } // update link table if needed copyRow.id = response.data.data.id; isLinkUpdate = $scope.updateLinkTable(copyRow, 'C'); if (!isLinkUpdate) { $scope.processSubFields(response.data.data.id); } }else{ if(response.data.message){ $scope.showModalMessage(response.data.message, 0); }else{ $scope.showModalMessage('Update Not OK', 0); } } }, function(response){ $scope.showModalMessage('Error in fetching', 0); } ); } break; } } } $scope.convertDateObjToJS = function(objDate, reverse, type, debug){ if(debug){ console.log('------- function Convert Date --------'); console.log(objDate); console.log(type); console.log(reverse); } if(!reverse){ tempTime = objDate.split(/[- :]/); switch(type){ case 'date': tempNewTime = new Date(tempTime[0], tempTime[1]-1, tempTime[2], 0, 0, 0); break; case 'time': if(!tempTime[2]){ tempTime[2] = 0; } tempNewTime = new Date(0 ,0, 0, tempTime[0], tempTime[1], tempTime[2]); break; case 'datetime': tempNewTime = new Date(tempTime[0], tempTime[1]-1, tempTime[2], tempTime[3], tempTime[4], tempTime[5]); break; } return tempNewTime; }else{ switch(type){ case 'date': if(typeof objDate.getFullYear !== 'function'){ return null; } return ([objDate.getFullYear(), objDate.getMonth()+1, objDate.getDate()].join('-')); break; case 'time': if(typeof objDate.getHours !== 'function'){ return null; } return ([objDate.getHours(), objDate.getMinutes(), objDate.getSeconds()].join(':')); break; case 'datetime': if(typeof objDate.getFullYear !== 'function'){ return null; } return ([objDate.getFullYear(), objDate.getMonth()+1, objDate.getDate()].join('-')+' '+[objDate.getHours(), objDate.getMinutes(), objDate.getSeconds()].join(':')); break; default: return objDate; break; } } } // updates link table for row and returns true if no link table is found $scope.updateLinkTable = function(row, type) { if (type === undefined || !type) { type = 'U'; } copyRow = angular.copy(row); postId = copyRow.id; delete copyRow.id; updateCount = 0; // update link table if ($scope.myTable && $scope.myTable.fieldDetails) { angular.forEach($scope.myTable.fieldDetails, function(details, field) { if (details.link !== undefined && copyRow[field] !== undefined) { subController = details.link; linkData = copyRow[field]; delete copyRow[field]; if ($scope.myTable.subQueries[subController] === undefined || $scope.myTable.subQueries[$scope.myTable.fieldDetailsController[field]] === undefined) { return; } linkQuery = $scope.myTable.subQueries[subController]; subQuery = $scope.myTable.subQueries[$scope.myTable.fieldDetailsController[field]]; originalRow = $scope.myTable.data.rows.filter(function(dataRow) { return dataRow.id == postId; }); if ((originalRow && originalRow.length == 1 && originalRow[0]['original_' + field]) || type == 'C') { // get old values and new values oldValues = (type == 'C' ? [] : originalRow[0]['original_' + field]); newValues = linkData; // determine which need to be deleted and which need to be inserted insertValues = arrDifference(newValues, oldValues); deleteValues = arrDifference(oldValues, newValues); // get the deletion rows by the original data deleteRows = $scope.myTable.data[subController].filter(function(dataRow) { return deleteValues.indexOf(dataRow[subQuery.ffield]) !== -1 && dataRow[linkQuery.ffield] == row[linkQuery.lfield]; }); // make the rows that needs to be inserted insertRows = []; angular.forEach(insertValues, function(value, key) { insertRow = {}; insertRow[subQuery.ffield] = value; insertRow[linkQuery.ffield] = row[linkQuery.lfield]; insertRows.push(insertRow); }); // add to update count for clean update if (deleteRows && deleteRows.length) { updateCount += deleteRows.length; } // add to update count for clean update if (insertRows && insertRows.length) { updateCount += insertRows.length; } // check if the rows exists in the original data if (deleteRows && deleteRows.length) { // delete the rows by id from the link table angular.forEach(deleteRows, function(deleteRow, key, array) { if (deleteRow.id) { $http.get('/' + subController + '/delete/' + deleteRow.id).then(function(response) { if (response.data.status) { index = $scope.myTable.data[subController].indexOf(deleteRow); if (index !== -1) { $scope.myTable.data[subController].splice(index, 1); } } updateCount--; if (updateCount == 0) { $scope.processSubFields(postId); } }); } }); } // check if the rows are succesfully made if (insertRows && insertRows.length) { // insert the rows in the link table angular.forEach(insertRows, function(insertRow, key, array) { $http.post('/' + subController + '/insert', insertRow, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}}).then(function(response) { if (response.data.status) { $scope.myTable.data[subController].push(response.data.data); } updateCount--; if (updateCount == 0) { $scope.processSubFields(postId); } }); }); } } } }); } return updateCount !== 0; } $scope.restoreOriginals = function(row){ strOriginal = 'original_'; angular.forEach(row, function(fieldValue, fieldName){ if(fieldName &&(strPos = fieldName.indexOf(strOriginal)) !== -1){ subField = fieldName.substr(strPos + strOriginal.length); row[subField] = fieldValue; delete row[fieldName]; } }); return row; } $scope.showEditField = function(fieldName){ if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[fieldName] && $scope.myTable.fieldDetails[fieldName].hideEdit){ return false; }else{ return true; } } $scope.getAllOptions = function() { if (!$scope.arrReturnOptions) { $scope.arrReturnOptions = {}; if ($scope.myTable.fieldDetails) { subFieldDetailKeys = Object.keys($scope.myTable.fieldDetails); if (subFieldDetailKeys) { angular.forEach(subFieldDetailKeys, function(field) { if ($scope.myTable.fieldDetails[field] && $scope.myTable.fieldDetails[field].changeTo && $scope.myTable.fieldDetailsController) { if ((subController = $scope.myTable.fieldDetailsController[field]) && (subControllerData = $scope.myTable.data[subController])) { $scope.arrReturnOptions[field] = []; //set default undefined option objOption = {}; objOption.id = 0; objOption.label = angular.copy($scope.myTable.labels.selectLabel); $scope.arrReturnOptions[field][0] = objOption; //----continue ffield = 'id'; if ($scope.myTable.fieldDetails[field].changeToFfield !== undefined) { ffield = $scope.myTable.fieldDetails[field].changeToFfield; } else if ($scope.myTable.fieldDetails[field].link !== undefined && $scope.myTable.subQueries[subController]['lfield'] !== undefined) { ffield = $scope.myTable.subQueries[subController]['lfield']; } else if ($scope.myTable.subQueries[subController] && $scope.myTable.subQueries[subController]['ffield'] !== undefined) { ffield = $scope.myTable.subQueries[subController]['ffield']; } angular.forEach(subControllerData, function(row){ objOption = {}; objOption.id = row[ffield]; objOption.label = ''; angular.forEach($scope.myTable.fieldDetails[field].changeTo, function(rplField){ if((strPos = rplField.indexOf('.')) !== -1){ subField = rplField.substr(strPos + 1); if(row[subField] !== undefined){ objOption.label = objOption.label + row[subField]; }else{ objOption.label = objOption.label + rplField; } }else{ // no conversion possible objOption.label = objOption.label + rplField; } }); if(objOption.label == ''){ objOption.label = '(empty)'; } //write back to options //$scope.arrReturnOptions[field][objOption.id] = objOption; $scope.arrReturnOptions[field].push(objOption); }); } } }); } } } return $scope.arrReturnOptions; } /*-------------[sort rows]---------------*/ $scope.showSort = function(fieldName){ return ($scope.sortRows[fieldName] !== undefined); } $scope.showSortReverse = function(fieldName){ if($scope.sortRows[fieldName] && !$scope.sortRows[fieldName].asc){ return true; }else{ return false; } } $scope.setSortRows = function(fieldName, desc){ if($scope.sortRows[fieldName] === undefined){ sortObj = { 'name': fieldName, 'asc': !desc, }; $scope.sortRows[fieldName] = sortObj; }else if(desc !== undefined){ $scope.sortRows[fieldName].asc = !desc; }else if($scope.sortRows[fieldName].asc){ $scope.sortRows[fieldName].asc = false; }else{ delete $scope.sortRows[fieldName]; } $scope.doSortRows(); } $scope.doSortRows = function(){ sortRowKeys = Object.keys($scope.sortRows); if(sortRowKeys.length){ sortRowKeys.reverse(); tmpSortedRows = $scope.myTable.data.rows; angular.forEach(sortRowKeys, function(key){ orderRow = $scope.sortRows[key]; tmpSortedRows = $filter('orderBy')(tmpSortedRows, orderRow.name, !orderRow.asc); }); $scope.myTable.data.rows = tmpSortedRows; } }; /*-------------[pagination]--------------*/ $scope.setPage = function(key){ $scope.page = key; } $scope.getPages = function() { if($scope.myTable.data !== undefined && $scope.myTable.data.rows !== undefined){ pageLimit = 1; if($scope.myTable.pageLimit){ pageLimit = $scope.myTable.pageLimit; } //calculate filtered items by getFilter and global search cntRows = $scope.myTable.data.rows.length; arrGetFilter = $scope.myTable.data.rows.filter(function(row){return $scope.getFilter(row)}); //$scope.cntFilteredItems = cntRows - arrGetFilter.filter(function(row){return $scope.getGlobalSearchFilter(row)}).length $scope.cntFilteredItems = cntRows - $filter('filter')(arrGetFilter, $scope.myTable.globalSearch).length; cntResult = (cntRows - $scope.cntFilteredItems); if($scope.myTable.limit && $scope.myTable.limit < cntResult){ cntResult = $scope.myTable.limit; } num = Math.ceil(cntResult / pageLimit); if(num <= $scope.page){ $scope.page = 0; } return new Array(num); } } $scope.getTotalRows = function(){ if($scope.myTable.data === undefined || $scope.myTable.data.rows === undefined){ return ; } if($scope.cntFilteredItems){ result = ($scope.myTable.data.rows.length - $scope.cntFilteredItems) + ' (' + $scope.myTable.data.rows.length + ')'; }else{ result = ($scope.myTable.data.rows.length - $scope.cntFilteredItems); } //total limit if($scope.myTable.limit && $scope.myTable.limit < result){ result = $scope.myTable.limit; } return result; } /*----------[field filter]------*/ $scope.toLabel = function(fieldName){ if($scope.myTable.fieldDetails !== undefined && $scope.myTable.fieldDetails[fieldName] !== undefined && $scope.myTable.fieldDetails[fieldName].label !== undefined){ return $scope.myTable.fieldDetails[fieldName].label; }else{ return fieldName.split("_").join(" "); } } $scope.getFieldType = function(fieldName){ if($scope.myTable.fieldDetails !== undefined && $scope.myTable.fieldDetails[fieldName] !== undefined && $scope.myTable.fieldDetails[fieldName].type !== undefined){ return $scope.myTable.fieldDetails[fieldName].type; }else{ return 'text'; } } $scope.getFieldOption = function(fieldName, option){ if($scope.myTable.fieldDetails !== undefined && $scope.myTable.fieldDetails[fieldName] !== undefined && $scope.myTable.fieldDetails[fieldName][option] !== undefined){ return $scope.myTable.fieldDetails[fieldName][option]; }else{ return false; } } $scope.sortFields = function(field){ if($scope.myTable.fields !== undefined){ fieldName = field.name.toLowerCase(); if ($scope.myTable.fields.indexOf(fieldName) !== -1){ return $scope.myTable.fields.indexOf(fieldName); } } } $scope.showFields = function(fieldName){ if($scope.myTable.fields !== undefined){ if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[fieldName] && $scope.myTable.fieldDetails[fieldName].hideList){ return false; } //field maybe to lowercase fieldNameLowerCase = fieldName.toLowerCase(); return ($scope.myTable.fields.indexOf(fieldName) !== -1 || $scope.myTable.fields.indexOf(fieldNameLowerCase) !== -1); }else{ return false; } } $scope.getFieldData = function(row, fieldName){ //normal if (row[fieldName] !== undefined){ strReturn = row[fieldName]; if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[fieldName] && $scope.myTable.fieldDetails[fieldName].type){ //types switch($scope.myTable.fieldDetails[fieldName].type){ case 'datetime': strReturn = $filter('date')(row[fieldName], 'yyyy-MM-dd HH:mm:ss'); if ($scope.myTable['fieldDetails'][fieldName]['format'] !== undefined && $scope.myTable['fieldDetails'][fieldName]['format']) { strReturn = $filter('date')(row[fieldName], this.myTable['fieldDetails'][fieldName]['format']); } break; case 'date': strReturn = $filter('date')(row[fieldName], 'yyyy-MM-dd'); if ($scope.myTable['fieldDetails'][fieldName]['format'] !== undefined && $scope.myTable['fieldDetails'][fieldName]['format']) { strReturn = $filter('date')(row[fieldName], this.myTable['fieldDetails'][fieldName]['format']); } break; case 'time': strReturn = $filter('date')(row[fieldName], 'HH:mm'); if ($scope.myTable['fieldDetails'][fieldName]['format'] !== undefined && $scope.myTable['fieldDetails'][fieldName]['format']) { strReturn = $filter('date')(row[fieldName], this.myTable['fieldDetails'][fieldName]['format']); } break; case 'boolean': if (row[fieldName] == $scope.myTable.fieldDetails[fieldName].booleanOn) { strReturn = '✔'; } else if (row[fieldName] == $scope.myTable.fieldDetails[fieldName].booleanOff) { strReturn = '✖'; } break; case 'number': strReturn = parseFloat(row[fieldName]); if (isNaN(strReturn)) { strReturn = ''; } else { currAmount = parseFloat(row[fieldName]); if($scope.myTable.fieldDetails[fieldName].currency){ currAmount = $filter('currency')(currAmount, $scope.myTable.fieldDetails[fieldName].currency); } strReturn = currAmount; } break; case 'enum': strReturn = $filter('filter')($scope.myTable.fieldDetails[fieldName].options, {'id': row[fieldName]}); if (Array.isArray(strReturn) && strReturn.length == 1) { if (strReturn[0]) { strReturn = strReturn[0].name; } } else if (typeof strReturn == 'string') { strReturn = row[fieldName]; } else { strReturn = ''; } break; } } return strReturn; } } $scope.getFilteredSubRow = function(subRow, ffield, ffieldData) { if (angular.isArray(ffieldData)) { return subRow[ffield] !== undefined && ffieldData.indexOf(subRow[ffield]) !== -1; } if(subRow[ffield] !== undefined && subRow[ffield] == ffieldData){ return true; }else{ return false; } } /*---------------[message]-----------------------*/ $scope.showMessage = function(message, timeout){ if(message){ $scope.message = message; if(timeout === undefined){ timeout = 1000; } if(timeout > 0){ $timeout(function(){ $scope.message = ""; }, timeout); } } } $scope.showModalMessage = function(message, timeout, error){ if(message){ $scope.modalMessage = message; if(timeout === undefined){ timeout = 1000; $scope.modalMessageSuccess = true; }else{ $scope.modalMessageSuccess = false; } if(error){ $scope.modalMessageSuccess = !error; } if (timeout > 0) { $timeout(function(){ $scope.modalMessage = ''; if($scope.myTable.showModal){ $scope.closeModal(); } }, timeout); } else if (timeout == 0) { let modalMsgTimout = 3000; if ($scope.myTable.modalMessageTimeout !== undefined && Number.isInteger($scope.myTable.modalMessageTimeout)) { modalMsgTimout = $scope.myTable.modalMessageTimeout; } $timeout(function() { $scope.modalMessage = ''; }, modalMsgTimout); } //Give sign to parent if($scope.$parent['modalUpdate']){ $scope.$parent['modalUpdate']($scope.myTable.name); } } } /*----------------[Select Rows]------------------*/ $scope.myTable.selectRows = function(filteredRows){ switch($scope.myTable.toSelectRows){ case '1': //deselect filtered rows angular.forEach(filteredRows, function(row){ row.sba_selected = false; }); break; case '2': //select filtered rows angular.forEach(filteredRows, function(row){ row.sba_selected = true; }); break; case '3': //de-select all rows //select filtered rows angular.forEach($scope.myTable.data.rows, function(row){ row.sba_selected = false; }); break; case '4': //select all rows angular.forEach($scope.myTable.data.rows, function(row){ row.sba_selected = true; }); break; } $scope.myTable.toSelectRows = 0; } /*----------------[Filter]-----------------------*/ if($scope.rowFilter === undefined){ $scope.rowFilter = {}; } if($scope.rowFilterMin === undefined){ $scope.rowFilterMin = {}; } if($scope.rowFilterMax === undefined){ $scope.rowFilterMax = {}; } $scope.statistics = {}; $scope.getFilter = function(row) { var returnValue = true; angular.forEach(row, function(value, key) { if ($scope.rowFilter[key] !== undefined && $scope.rowFilter[key] && $scope.rowFilter[key] != '!' && $scope.rowFilter[key] != '!!' && value) { matchValue = angular.copy(value) if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[key] && $scope.myTable.fieldDetails[key].type){ if($scope.myTable.fieldDetails[key].type == 'boolean' && $scope.myTable.fieldDetails[key].booleanOn !== undefined && $scope.myTable.fieldDetails[key].booleanOff !== undefined){ if(matchValue == $scope.myTable.fieldDetails[key].booleanOn){ matchValue = 'true'; }else{ matchValue = 'false'; } } if($scope.myTable.fieldDetails[key].type == 'datetime' || $scope.myTable.fieldDetails[key].type == 'date' || $scope.myTable.fieldDetails[key].type == 'time'){ //types switch($scope.myTable.fieldDetails[key].type){ case 'datetime': matchValue = $filter('date')(matchValue, 'yyyy-MM-dd HH:mm:ss'); break; case 'date': matchValue = $filter('date')(matchValue, 'yyyy-MM-dd'); break; case 'time': matchValue = $filter('date')(matchValue, 'HH:mm'); break; } } } matchValue = matchValue.toString().toLowerCase(); matchFilter = angular.copy($scope.rowFilter[key]).toString().toLowerCase(); returnValue = matchValue.match(matchFilter) && returnValue; } else if ($scope.rowFilter[key] !== undefined && $scope.rowFilter[key] == '!!' && !value) { returnValue = returnValue && true; } else if ($scope.rowFilter[key] !== undefined && $scope.rowFilter[key] == '!!' && value) { returnValue = returnValue && false; } else if ($scope.rowFilter[key] !== undefined && $scope.rowFilter[key] == '!' && value) { returnValue = returnValue && true; } else if ($scope.rowFilter[key] !== undefined && $scope.rowFilter[key] && !value){ returnValue = false; } else { returnValue = returnValue && true; } //min if ($scope.rowFilterMin[key] !== undefined && $scope.rowFilterMin[key] && value) { if(angular.isDate(value)){ var date = value.getFullYear() + "-" + appendLeadingZeroes(value.getMonth() + 1) + "-" + appendLeadingZeroes(value.getDate()); returnValue = returnValue && $scope.rowFilterMin[key].toString().replace('/-/g', '') <= date.toString().replace('/-/g', ''); }else{ returnValue = returnValue && $scope.rowFilterMin[key] <= value; } } //max if ($scope.rowFilterMax[key] !== undefined && $scope.rowFilterMax[key] && value) { if(angular.isDate(value)){ var date = value.getFullYear() + "-" + appendLeadingZeroes(value.getMonth() + 1) + "-" + appendLeadingZeroes(value.getDate()); returnValue = returnValue && $scope.rowFilterMax[key].toString().replace('/-/g', '') >= date.toString().replace('/-/g', ''); }else{ returnValue = returnValue && $scope.rowFilterMax[key] >= value; } } }); //rowFilter if(row['sba_selected'] === undefined && $scope.rowFilter['sba_selected'] == "true"){ returnValue = returnValue && false; } else if ((row['sba_selected'] == "false" || row['sba_selected'] === undefined) && $scope.rowFilter['sba_selected'] === false){ returnValue = returnValue && true; } return returnValue; } function appendLeadingZeroes(n){ if(n <= 9){ return "0" + n; } return n } function isNumeric(val) { //return !isNaN(parseFloat(val)) && isFinite(val); return Number(parseFloat(val))==val; } $scope.getPageIndex = function(){ if($scope.myTable.pageLimit && $scope.page){ return $scope.myTable.pageLimit * $scope.page; }else{ return 0; } } $scope.getStatistics = function(name, filteredItems) { //get field Type if($scope.myTable && $scope.myTable.fieldDetails && $scope.myTable.fieldDetails[name] && $scope.myTable.fieldDetails[name].type && $scope.myTable.fieldDetails[name].type != 'boolean' && $scope.myTable.fieldDetails[name].type != 'float' && $scope.myTable.fieldDetails[name].type != 'number'){ switch($scope.myTable.fieldDetails[name].type) { case 'time': i = 0; minutes = 0; for (rowKey in filteredItems) { row = filteredItems[rowKey]; angular.forEach(row, function(value, key) { if(key === name && value){ minutes += value.getHours() * 60 + value.getMinutes(); } }); }; hours = Math.floor(minutes / 60); minutes = minutes - hours * 60; if(String(minutes).length == 1){ minutes = '0' + minutes; } if(String(hours).length == 1){ hours = '0' + hours; } varResult = hours + ':' + minutes; break; default: varResult = ''; } }else{ sum = 0.0; for (rowKey in filteredItems) { row = filteredItems[rowKey]; angular.forEach(row, function(value, key) { if(key === name && value){ sum = sum + parseFloat(value); } }); }; sum = (isNaN(sum) ? '' : sum); varResult = sum == 0.0 ? '' : sum; } if ($scope.myTable.fieldDetails[name].currency) { varResult = $filter('currency')(varResult, $scope.myTable.fieldDetails[name].currency); } $scope.myTable.statistics[name] = varResult; return varResult; } /*-------------------[JSON CALL]-----------------*/ $scope.processSubFields = function(row_id){ //update? if(row_id !== undefined){ $scope.myTable.loadData = $scope.myTable.data; } //loop all rows for replace rowsToKeep = []; arrFields = $scope.myTable.loadData.fields; //set field Controller, in case no rows if(!$scope.myTable.loadData.rows.length){ if($scope.myTable.fieldDetails){ angular.forEach($scope.myTable.fieldDetails, function(objField, field){ if(objField.changeTo){ //convert changeTo to array if not if(!angular.isArray(objField.changeTo)){ tmpChangeTo = objField.changeTo; objField.changeTo = []; objField.changeTo.push(tmpChangeTo); } //process changeTo with current Controller rplFieldValue = ''; angular.forEach(objField.changeTo, function(rplField){ if((strPos = rplField.indexOf('.')) !== -1){ subController = rplField.substr(0,strPos); //write controller back to fieldDetails if(!$scope.myTable.fieldDetailsController){ $scope.myTable.fieldDetailsController = []; } if(!$scope.myTable.fieldDetailsController[field]){ $scope.myTable.fieldDetailsController[field] = subController; } } }); } }); } } angular.forEach($scope.myTable.loadData.rows, function(row, index){ if(row_id != null && row_id != row.id){ return; } angular.forEach(arrFields, function(objField){ field = objField.name; if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field] && $scope.myTable.fieldDetails[field].changeTo){ //convert changeTo to array if not if(!angular.isArray($scope.myTable.fieldDetails[field].changeTo)){ tmpChangeTo = $scope.myTable.fieldDetails[field].changeTo; $scope.myTable.fieldDetails[field].changeTo = []; $scope.myTable.fieldDetails[field].changeTo.push(tmpChangeTo); } //process changeTo with current Controller rplFieldValue = ''; linkFieldData = false; angular.forEach($scope.myTable.fieldDetails[field].changeTo, function(rplField) { if ((strPos = rplField.indexOf('.')) !== -1) { subController = rplField.substr(0, strPos); if ($scope.myTable.fieldDetails[field].link) { subController = $scope.myTable.fieldDetails[field].link; } if ($scope.myTable.subQueries && $scope.myTable.subQueries[subController]) { //write controller back to fieldDetails if(!$scope.myTable.fieldDetailsController){ $scope.myTable.fieldDetailsController = []; } if(!$scope.myTable.fieldDetailsController[field]){ $scope.myTable.fieldDetailsController[field] = rplField.substr(0, strPos); } subField = rplField.substr(strPos + 1); lfield = field; //local lookup field // link local field if ($scope.myTable.fieldDetails[field].link && $scope.myTable.subQueries[subController].lfield) { lfield = $scope.myTable.subQueries[subController].lfield; } ffield = 'id'; if($scope.myTable.fieldDetails[field].changeToFfield !== undefined){ ffield = $scope.myTable.fieldDetails[field].changeToFfield; }else if($scope.myTable.subQueries[subController]['ffield'] !== undefined){ ffield = $scope.myTable.subQueries[subController]['ffield']; } ffieldData = row[lfield]; // check if subcontroller exists in loaded data if ($scope.myTable.loadData[subController]) { // get subitems from the subcontroller subItems = $scope.myTable.loadData[subController].filter(function(subRow){return $scope.getFilteredSubRow(subRow, ffield, ffieldData)}); // if link subitems, get the linked items if (subItems && $scope.myTable.fieldDetails[field].link) { subController = rplField.substr(0, strPos); // check if other subcontroller exists if ($scope.myTable.subQueries[subController]) { rplFieldPlaceholder = ''; if (!angular.isObject(rplFieldValue)) { rplFieldPlaceholder = rplFieldValue; rplFieldValue = {}; } // get field data from linked table arrlfielddata = subItems.map(function(a) { return a[$scope.myTable.subQueries[subController]['ffield']]; }); subItems = $scope.myTable.loadData[subController].filter(function(subRow){return $scope.getFilteredSubRow(subRow, $scope.myTable.subQueries[subController]['lfield'], arrlfielddata)}); // loop through subitems to created the desired list items if (subItems) { linkFieldData = subItems.map(function(a) { return a[$scope.myTable.subQueries[subController]['lfield']]; }) angular.forEach(subItems.map(function(a) { return a[subField]; }), function(item, key) { if (rplFieldValue[key] === undefined) { rplFieldValue[key] = rplFieldPlaceholder; } rplFieldValue[key] = rplFieldValue[key] + item; }); } } else { // no conversion possible angular.isObject(rplFieldValue) ? angular.forEach(rplFieldValue, function(item, key) { rplFieldValue[key] = rplFieldValue[key] + rplField; }) : rplFieldValue = rplFieldValue + rplField; } // if no link, add to field value } else { if(subItems[0] !== undefined && subItems[0][subField] !== undefined){ rplFieldValue = rplFieldValue + subItems[0][subField]; } } } else { // no conversion possible angular.isObject(rplFieldValue) ? angular.forEach(rplFieldValue, function(item, key) { rplFieldValue[key] = rplFieldValue[key] + rplField; }) : rplFieldValue = rplFieldValue + rplField; } } else { // no conversion possible angular.isObject(rplFieldValue) ? angular.forEach(rplFieldValue, function(item, key) { rplFieldValue[key] = rplFieldValue[key] + rplField; }) : rplFieldValue = rplFieldValue + rplField; } } else { // no conversion possible angular.isObject(rplFieldValue) ? angular.forEach(rplFieldValue, function(item, key) { rplFieldValue[key] = rplFieldValue[key] + rplField; }) : rplFieldValue = rplFieldValue + rplField; } }); //write back to row row['original_' + field] = linkFieldData ? linkFieldData : row[field]; row[field] = angular.isObject(rplFieldValue) ? Object.values(rplFieldValue).join(', ') : rplFieldValue; }else if(!row[field]){ //set anyway for filter row[field] = ''; //no changeTo and not set in row? if((strPos = field.indexOf('.')) !== -1 && $scope.myTable.subQueries){ subController = field.substr(0,strPos); subField = field.substr(strPos + 1); //subQueryProcessing if($scope.myTable.loadData[subController] && (lfield = $scope.myTable.subQueries[subController]['lfield']) && row[lfield]){ ffield = 'id'; if($scope.myTable.subQueries[subController]['ffield'] !== undefined){ ffield = $scope.myTable.subQueries[subController]['ffield']; } //if original field is replaced if(row['original_' + lfield]){ ffieldData = row['original_' + lfield] }else{ ffieldData = row[lfield]; } subItems = $scope.myTable.loadData[subController].filter(function(subRow){ return $scope.getFilteredSubRow(subRow, ffield, ffieldData) }); if(subItems[0] !== undefined && subItems[0][subField] !== undefined){ row[field] = subItems[0][subField]; } } } } //----------------------------[Convert Fields Types]------------------------------------------- if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field] && $scope.myTable.fieldDetails[field].type){ //datetime switch($scope.myTable.fieldDetails[field].type){ case 'datetime': if(row[field]){ row[field] = $scope.convertDateObjToJS(row[field], false, 'datetime'); } break; case 'date': if(row[field]){ row[field] = $scope.convertDateObjToJS(row[field], false, 'date'); } break; case 'time': if(row[field]){ row[field] = $scope.convertDateObjToJS(row[field], false, 'time'); } break; case 'file': if(row[field] && ($scope.myTable.fieldDetails[field].multiple == undefined || $scope.myTable.fieldDetails[field].multiple == 1)){ try { row[field] = JSON.parse(row[field]); } catch(e) { row[field] = []; } } break; } } //----------------------------[Where Fields]------------------------------------------- if($scope.myTable.fieldDetails && $scope.myTable.fieldDetails[field]){ //sort if($scope.myTable.fieldDetails[field].sortAsc !== undefined){ desc = !$scope.myTable.fieldDetails[field].sortAsc; if($scope.myTable.fieldDetails[field].sortOriginal){ $scope.setSortRows('original_' + field, desc); }else{ $scope.setSortRows(field, desc); } } //where if($scope.myTable.fieldDetails[field].where){ tmpWhere = $scope.myTable.fieldDetails[field].where; //array of 2 parts if(angular.isObject(tmpWhere)){ angular.forEach(tmpWhere, function(right, compare){ if(!$scope.myTable.fieldDetails[field].whereOnChangeTo && row['original_' + field]){ left = row['original_' + field]; }else{ left = row[field]; } if(!doCompare(left,compare,right)){ rowsToKeep.push(row.id); } }); } } } }); }); //inverse items to be deleted $scope.myTable.loadData.rows = $filter('filter')($scope.myTable.loadData.rows, function(row){ return rowsToKeep.indexOf(row.id) === -1}); //copy loadData to data $scope.myTable.data = angular.copy($scope.myTable.loadData); $scope.myTable.loadData = {}; //predefined filters? if($scope.myTable.predefinedFilters){ $scope.rowFilter = $scope.myTable.predefinedFilters; } //done? $scope.doSortRows(); $scope.showMessage($scope.myTable.labels.ready); if($scope.$parent['tableReady']){ $scope.$parent['tableReady']($scope.myTable.name); } //set readOnly to cache $scope.myTable.readOnly = $scope.cacheReadOnly; $scope.loading = false; $scope.currentTime = Date.now(); } //update predefined filters $scope.myTable.updatePredefinedFilters = function(fieldName, filter){ if($scope.rowFilter === undefined){ $scope.rowFilter = {}; } $scope.rowFilter[fieldName] = filter; } function doCompare(left, compare, right){ switch(compare) { case '<>': return (left != right); break; case '!=': return (left != right); break; case '==': return (left == right); break; case '>=': return (left >= right); break; case '<=': return (left <= right); break; case '>': return (left > right); break; case '<': return (left < right); break; default: return false; } } function getCompare(left, compareright){ if(compareright.substring(0,1) == '>' || compareright.substring(0,1) == '<'){ return doCompare(left, compareright.substring(0,1), compareright.substring(1)); }else{ return doCompare(left, compareright.substring(0,2), compareright.substring(2)); } } //--------------[trLayout]----------------------- $scope.trLayout = function(row){ strReturn = ''; if($scope.myTable.style && $scope.myTable.style.row){ angular.forEach($scope.myTable.style.row, function(checkFields, strClass){ angular.forEach(checkFields, function(fieldCompare, checkField){ if(row[checkField] !== undefined){ if(getCompare(row[checkField], fieldCompare)){ strReturn = strClass; } } }); }); } //return class return strReturn; } //--------------[tdLayout]----------------------- $scope.tdLayout = function(fieldName, fieldValue){ strReturn = ''; if($scope.myTable.style && $scope.myTable.style.cell){ angular.forEach($scope.myTable.style.cell, function(checkFields, strClass){ angular.forEach(checkFields, function(fieldCompare, checkField){ if(fieldName == checkField || checkField.substring(0, 7) == '_global'){ if(getCompare(fieldValue, fieldCompare)){ strReturn = strClass; } } }); }); } //return class return strReturn; } //--------------[subData]----------------------- $scope.getSubData = function(){ if (!$scope.myTable.subQueries || ($scope.myTable.subQueries !== undefined && !Object.keys($scope.myTable.subQueries).length)) { //process subfields $scope.showMessage($scope.myTable.labels.processSubFields,0); $scope.processSubFields(); return; } else { $scope.cntSubQueriesDone = 0; angular.forEach($scope.myTable.subQueries, function(subQuery, subQueryName){ if(!subQuery.function){ subQueryFunction = 'getAll'; } else { subQueryFunction = subQuery.function; } if(!subQuery.name){ subQuery.name = subQuery.controller; } //preload name subQueryPreloadName = subQueryName + "_" + subQueryFunction; if (subQuery.controller) { if ($scope.$parent.SbaCrudTablePreload && $scope.$parent.SbaCrudTablePreload.data && $scope.$parent.SbaCrudTablePreload[subQueryPreloadName]){ $scope.myTable.loadData[subQueryName] = $scope.$parent.SbaCrudTablePreload[subQueryPreloadName]; $scope.showMessage('SubQuery ' + subQuery.controller + ' ' + $scope.myTable.labels.alreadyLoaded); $scope.cntSubQueriesDone++; } else { $scope.showMessage($scope.myTable.labels.loading + ' ' + subQueryName + '...'); $http.get('/' + subQuery.controller + '/' + subQueryFunction).then(function(response) { var data = response.data; if(data.status){ if($scope.$parent.SbaCrudTablePreload === undefined){ $scope.$parent.SbaCrudTablePreload = {}; } if($scope.$parent.SbaCrudTablePreload.data === undefined){ $scope.$parent.SbaCrudTablePreload.data = {}; } if($scope.$parent.SbaCrudTablePreload.data[subQueryPreloadName] === undefined){ $scope.$parent.SbaCrudTablePreload.data[subQueryPreloadName] = data.data; } $scope.myTable.loadData[subQueryName] = data.data; } $scope.cntSubQueriesDone++; }, function(response) { $scope.showMessage($scope.myTable.labels.errorInFetching); $scope.cntSubQueriesDone++; }); } } else { $scope.cntSubQueriesDone++; } }); } } $scope.$watch('cntSubQueriesDone', function (newValue, oldValue) { if($scope.cntSubQueriesDone > 0){ subQueriesKeys = Object.keys($scope.myTable.subQueries); if($scope.cntSubQueriesDone == subQueriesKeys.length){ //process subfields $scope.showMessage($scope.myTable.labels.processSubFields ,0); $scope.processSubFields(); } } }); /* ---- [file upload] ---- */ $scope.uploadFiles = function(file, field, model) { if (file) { var data = new FormData(); data.append("file", file); $http( { url: $scope.baseURL + field.uploadFileUrl, data: data, headers: { 'Content-Type': undefined }, transformRequest: angular.identity, method: 'POST', } ).then(function(response) { if (response.status && response.data.status) { // hide error message field.uploadFileError = ''; if (field.multiple !== undefined && (field.multiple == false || field.multiple == 0)) { //add only image $scope.myTable.modal.data[field.name] = response.data.data.relative_file; } else { // check model if (model === undefined || model === null || !Array.isArray(model)) { model = []; } // add to model model.push(response.data.data.relative_file); } } else { // show error message let errorMessage = 'Could not upload file!'; if (response.data.data[0] !== undefined && response.data.data[0]) { errorMessage = response.data.data[0]; } field.uploadFileError = errorMessage; } }, function(error) { // show error message field.uploadFileError = 'Could not upload file, please try again!'; }); } } $scope.filenameFromFilePath = function(filePath) { if (typeof filePath == 'string'){ return filePath.split("/").pop(); } } $scope.fetchFile = function(file, field) { if (field.fetchFileUrl) { window.open($scope.baseURL + field.fetchFileUrl + '/' + $scope.filenameFromFilePath(file), '_blank'); } else { window.open($scope.baseURL + file, '_blank'); } } $scope.getData = function(){ varFunction = 'getAll'; if($scope.myTable.function !== undefined){ varFunction = $scope.myTable.function; } getId = ''; if($scope.myTable.getId !== undefined && $scope.myTable.getId){ getId = '/' + $scope.myTable.getId; } if($scope.myTable.preload && $scope.myTable.preload.data && $scope.myTable.preload.data.rows){ $scope.myTable.loadData.rows = $scope.myTable.preload.data.rows; $scope.showMessage($scope.myTable.labels.alreadyLoaded); $scope.getSubData(); }else{ $scope.showMessage($scope.myTable.labels.loading + ' ' + $scope.myTable.controller); $http.get($scope.baseURL + $scope.myTable.controller + '/' + varFunction + getId).then(function(response) { var data = response.data; if(data.status){ $scope.myTable.loadData.rows = data.data; $scope.getSubData(); }else{ $scope.myTable.loadData.rows = []; $scope.getSubData(); } }, function(response) { $scope.showMessage($scope.myTable.labels.errorInFetching); $scope.loading = false; }); } } $scope.initiate = function(automatic){ if(automatic === undefined){ automatic = false; } if($scope.myTable !== undefined){ if(!$scope.myTable.initiate && $scope.myTable.initiate !== undefined && automatic){ return ; } //save readOnly cache if ($scope.myTable.readOnly !== undefined && typeof $scope.myTable.readOnly === "boolean") { $scope.cacheReadOnly = $scope.myTable.readOnly; } $scope.myTable.readOnly = true; //panel class if($scope.myTable.panelClass){ $scope.panelClass = $scope.myTable.panelClass; } //data object for table $scope.myTable.statistics = {}; $scope.myTable.data = {}; $scope.myTable.data.rows = []; $scope.myTable.data.fields = []; $scope.myTable.selectedItems = []; $scope.myTable.convertDateObjToJS = function(objDate, reverse, type, debug){ return $scope.convertDateObjToJS(objDate, reverse, type, debug); } //remove modal options if ($scope.arrReturnOptions !== undefined) { delete $scope.arrReturnOptions; } //showFilters if($scope.myTable.showFilters !== undefined){ $scope.showFilters = $scope.myTable.showFilters; } //show getCSV if($scope.myTable.getCSV){ $scope.showCSV = true; } //show putCSV if($scope.myTable.putCSV && $scope.buttons['putCSV']['header']){ $scope.buttons['putCSV']['header'] = blnSet; } //until loading is done $scope.myTable.loadData = {}; $scope.showMessage($scope.myTable.labels.loading, 0); $scope.loading = true; //buttons if(!$scope.myTable.buttonRow){ $scope.myTable.buttonRow = true; //add custom buttons if($scope.myTable.buttons){ angular.forEach($scope.myTable.buttons, function(button){ $scope.buttons[button.id.toUpperCase()] = button; }); } if($scope.myTable.allowDeleteMany){ $scope.buttons.DA.header = true; } $scope.myTable.buttons = $scope.buttons; } //get table fields from controller $http.get($scope.baseURL + $scope.myTable.controller + '/fields').then(function(response) { var data = response.data; if(data.status){ $scope.myTable.loadData.originalFields = data.data; //check if fields are already set if($scope.myTable.fields !== undefined){ $scope.myTable.loadData.fields = []; angular.forEach($scope.myTable.fields, function(value){ objTemp = { 'name': value, }; $scope.myTable.loadData.fields.push(objTemp); }); //auto list undefined fields if($scope.myTable.listUndefinedFields){ tmpFilterFields = $filter('filter')($scope.myTable.loadData.originalFields, function(item) { if(item.name != 'id'){ tmpResult = true; angular.forEach($scope.myTable.loadData.fields, function(field){ if(item.name == field.name){ tmpResult = false; } }); }else{ tmpResult = false; } return tmpResult; } ); //put them into fields angular.forEach(tmpFilterFields, function(field){ $scope.myTable.loadData.fields.push(field); //set field details tmpFieldDetail = { 'hideList': true, 'hideEdit': false, }; if($scope.myTable.fieldDetails === undefined){ $scope.myTable.fieldDetails = {}; } $scope.myTable.fieldDetails[field.name] = tmpFieldDetail; }); } }else{ $scope.myTable.loadData.fields = $scope.myTable.loadData.originalFields; //set field names $scope.myTable.fields = []; angular.forEach($scope.myTable.loadData.fields, function(field){ $scope.myTable.fields.push(field.name); }); } angular.forEach($scope.myTable.loadData.originalFields, function(field){ //fieldDetails if($scope.myTable.fieldDetails === undefined){ $scope.myTable.fieldDetails = {}; } if($scope.myTable.fieldDetails[field.name] === undefined){ $scope.myTable.fieldDetails[field.name] = {}; } //tmpUpdateField tmpUpdateField =$filter('filter')($scope.myTable.fields, {'$': field.name}); if($scope.myTable.listUndefinedFields || (tmpUpdateField && tmpUpdateField[0])){ //------type------ if($scope.myTable.fieldDetails[field.name] && !$scope.myTable.fieldDetails[field.name].type){ //auto set field type blnOn = false; blnOff = false; switch(field.type){ case 'text': strType = 'textarea'; break; case 'time': strType = 'time'; break; case 'datetime': strType = 'datetime'; break; case 'date': strType = 'date'; break; case 'float': strType = 'number'; break; case 'int': strType = 'number'; if(field.max_length == 1){ strType = 'boolean'; blnOn = 1; blnOff = 0; } break; default: strType = 'text'; break; } //set type tmpFieldName = field.name; //no for _id if(tmpFieldName.indexOf('_id') === -1){ $scope.myTable.fieldDetails[field.name].type = strType; } if(blnOn !== false && blnOff !== false){ $scope.myTable.fieldDetails[field.name].booleanOn = blnOn; $scope.myTable.fieldDetails[field.name].booleanOff = blnOff; } } } //------max length------ if(field.max_length){ $scope.myTable.fieldDetails[field.name].max_length = field.max_length; } //------autoChangeTo---- if($scope.myTable.autoChangeTo && $scope.myTable.autoChangeTo.indexOf(field.name) !== -1){ //auto changeTo tmpFieldName = field.name; tmpController = tmpFieldName.substr(0, tmpFieldName.lastIndexOf('_id')); tmpChangeTo = tmpController + '.name'; tmpChangeToId = tmpController + '.id'; if($scope.myTable.fieldDetails[field.name].changeTo === undefined){ $scope.myTable.fieldDetails[tmpFieldName].changeTo = [tmpChangeToId, ' - ', tmpChangeTo]; } arrSubQueries = { 'lfield': tmpController + '_id', 'ffield': 'id', 'controller': tmpController, }; if($scope.myTable.subQueries === undefined){ $scope.myTable.subQueries = {}; } if($scope.myTable.subQueries[tmpController] === undefined){ $scope.myTable.subQueries[tmpController] = arrSubQueries; } } }); $scope.getData(); } }, function(response) { $scope.showMessage($scope.myTable.labels.errorInFetching); $scope.loading = false; }); } } $scope.myTable.call = function(strFunction){ $scope[strFunction](); } $scope.myTable.initiate = function(automatic){ $scope.initiate(automatic); } function arrDifference(A, B) { C = []; if (!angular.isArray(A) || !angular.isArray(B)) { return C; } A.forEach(function(key) { if (B.indexOf(key) === -1) { C.push(key); } }); return C; } //initial $scope.initiate(true); //image upload $scope.imageUpload = function(files) { let data = new FormData(); data.append('image', files[0]); $http.post($scope.baseURL + $scope.myTable.controller + '/uploadImage', data, {headers: {"Content-Type": undefined}}).then( function(response){ if (response.data.status) { $('.summernote').summernote('editor.insertImage', $scope.baseURL + (response.data.data.relative_file).substring(1)); } } ); } } }; });