/* * JAVASCRIPT other */ /* jshint esversion: 6 */ /* global initAjaxUploader, afusKeyInObject, afusErrorCatch, showActionIndicator, hideActionIndicator, exists, phfo, aelx, cel */ /** * clear the alert div and hide it */ function clearAlerts() { $('#alerts-div').html('').hide(); } /** * prints a single message line * @param {String} msg message text * @param {String} level level as style sheet name for highlight */ function printMsgStr(msg, level) { printMsg([{ level: level, str: msg }]); } /** * prints master error message in case of master error * @param {Object} msg messages as hash object */ function printMsg(msg) { var content = []; for (const t of msg) { // console.log('v: %s, t: %o', v, t); if (afusKeyInObject('code', t) && t.code != null && t.code.length > 0) { t.str = '[' + t.code + '] ' + t.str; } content.push(phfo(cel('div', '', t.str, ['error-' + t.level]))); } $('#alerts-div') .html(content.join('')) .show(); // calcHeightTopHeader(); } /** * wrapper for ajax calls * This will do a beforeSend call * Success generall call (before .done) * error call for general error catch (can be outside extended with .fail) * complete call to hide the action indicator * note: if pre-function is small we might want to put indicator call in this function * @param {String} call_id Caller id for debug and action indicator debug * @param {Object} queryString Query string to pass on, default empty * @param {Object} control Control for action indicator and others * no_action_indicator: true/false/empty, if true do not use action indicator * @param {String} url Target url, defaults to generalBackend.php * @return {jqXHR} JQuery XJR Object for .done, .fail, etc connection calls */ function ajaxWrapper(call_id, queryString = {}, control = {}, url = 'backend.php') { var no_action_indicator = false; if (afusKeyInObject('no_action_indicator', control)) { no_action_indicator = control.no_action_indicator ? true : false; } // if inidicator not visible, show before if (!no_action_indicator) { showActionIndicator(call_id); } // general ajax wrapper // AJAX call return $.ajax({ url: url, type: 'POST', data: queryString, // genera; before Sending beforeSend: function () { console.log('MAIN RUN: ' + call_id); }, success: function (data, status, xhr) { // additional success call console.log('[' + call_id + '] Return with [%s] as status: %s, xhr: %s, action: %s', status, data.status, xhr.status, data.action); }, // general error error: function (xhr) { console.log('[' + call_id + '] An error occured: %s %s', xhr.status, xhr.statusText); // critical error printMsgStr(call_id + ' Error', 'crash'); }, complete: function () { console.log('[' + call_id + '] Complete'); if (!no_action_indicator) { hideActionIndicator(call_id); } } }); } /** * uuid4 creator * @returns {String} uuid4 */ function uuidv4() { return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, c => (+c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> +c / 4).toString(16) ); } /** * FILE CHANGE: * helper call for ajax file upload on file selected * @param {String} target_file The file upload target prefix id * @param {Number} file_pos Position in upload queue * @param {String} target_router [description] * @param {Object} options additional functions options */ function fileChangeFunction(target_file, file_pos, target_router, options={}) { console.log('{FILE} CHANGE [%s/%s] FUNCTION CALL [%s]: [%o]', target_file, file_pos, target_router, options); clearAlerts(); // console.log('Upload Status: %s', $('#' + target_file + '-upload-status').outerHeight()); } /** * [fileChangeFunctionAll description] * @param {String} target_file [description] * @param {String} target_router [description] */ function fileChangeFunctionAll(target_file, target_router) { console.log('{FILE} CHANGE ALL [%s] FUNCTION CALL [%s]', target_file, target_router); clearAlerts(); // console.log('Upload Status: %s', $('#' + target_file + '-upload-status').outerHeight()); } /** * [fileRemoveFunction description] * @param {string} target_file [description] * @param {Number} file_pos [description] * @param {String} target_router [description] *c */ function fileRemoveFunction(target_file, file_pos, target_router) { console.log('{FILE} REMOVE [%s/%s] FUNCTION CALL [%s]', target_file, file_pos, target_router); // console.log('Upload Status: %s', $('#' + target_file + '-upload-status').outerHeight()); // clearAlerts(); } /** * [fileClearFunction description] * @param {String} target_file [description] * @param {String} target_router [description] */ function fileClearFunction(target_file, target_router) { console.log('{FILE} CLEAR [%s] FUNCTION CALL [%s]', target_file, target_router); // console.log('Upload Status: %s', $('#' + target_file + '-upload-status').outerHeight()); // clearAlerts(); } /** * [fileAppendBeforeUploadFunctionAllFunction description] * @param {String} target_file [description] * @param {String} target_router [description] * @return {Object} [description] */ function fileAppendBeforeUploadFunctionAllFunction(target_file, target_router) { console.log('{FILE} BEFORE UPLOAD ALL [%s] FUNCTION CALL [%s]', target_file, target_router); return { 'primary_key': $('#reference-id').val(), 'same-entry': 'A', 'target-files': target_file, 'target-router': target_router }; } /** * FILE BEFORE UPLOAD: * attach additional data to be sent to the server * This is called before the data is submitted to the server * @param {String} target_file The file upload target prefix id * @param {Number} file_pos Position in upload queue * @param {String} target_router * @return {Object} key -> value object to be attached to the form */ function fileAppendBeforeUploadFunction(target_file, file_pos, target_router) { console.log('{FILE} BEFORE UPLOAD [%s/%s] FUNCTION CALL [%s]', target_file, file_pos, target_router); return { 'file_data_count': $('#file-list').children().length, 'same-entry': 'B', 'target-files': target_file, 'file-pos': file_pos, 'target-router': target_router }; } /** * FILE ULOAD FINISHED: * helper call for ajax file upload on upload completed * set the uploaded file list (hidden & visible), shows import button, * adjusts hight of action box * @param {String} target_file The file upload target prefix id * @param {Object} control_data The data returned from the ajax call after upload */ function fileUploadedFunction(target_file, file_pos, target_router, control_data) { console.log('{FILE} UPLAODED [%s/%s] FUNCTION CALL [%s]: %o', target_file, file_pos, target_router, control_data); var file_id = target_file; var file_entry_exists = false; // add new uploaded file entry to the push list // first find if there is an entry for this file yet (-file-name) try { console.log('Uploaded file UID: %s', $('#' + file_id + '-uid-' + file_pos).val()); if (exists(file_id + '-uid-' + file_pos) && $('#' + file_id + '-uid-' + file_pos).val()) { // hide file info first $('#file-info').html('').hide(); // add new uplaoded files $('#file-list').append(phfo( aelx(cel('div', '', '', ['flx-ss']), cel('div', '', control_data.file_name, ['mg-5']), cel('div', '', '(NOW)', ['mg-5']), cel('div', '', control_data.file_size, ['mg-5']), cel('input', file_id + '-uploaded-' + file_pos, '', [], {type: 'hidden', value: control_data.file_uid}) ) )); // DOUBLE entry checker used in FormControl control file upload // console.log('MAP: %o', $('#file-list :input')); file_entry_exists = Object.values($('#file-list :input').map(function() { // console.log('Matching: %s - %s', control_data.file_uid, $(this).val()); return control_data.file_uid == $(this).val() ? true : false; })).find(value => value === true); console.log('Matched: %s', file_entry_exists); if (!file_entry_exists) { // add hidden and visible elment // addControlFileElement(file_id, $('#' + file_id + '-file_name').val(), control_data.other_data.status_text); } } } catch(err) { afusErrorCatch(err); } // chain action test var call_id = 'chainAction'; var queryString = { action: call_id, chain: control_data.file_uid }; ajaxWrapper(call_id, queryString).done(function (data) { console.log('Data: %o', data); try { if (data.status == 'error') { // } else { // list files if (data.status == 'warn') { // } else { // } } // top message printMsg(data.msg); } catch (err) { afusErrorCatch(err); } }); } /** * [fileUploadedAllFunction description] * @param {String} target_file [description] * @param {Number} target_router [description] * @param {Boolean} all_success If true all files where accepted by the servers */ function fileUploadedAllFunction(target_file, target_router, all_success) { console.log('{FILE} UPLAODED ALL [%s] FUNCTION CALL [%s]: %o', target_file, target_router, all_success); } /** * [fileUploadErrorFunction description] * @param {String} target_file [description] * @param {Number} file_pos [description] * @param {String} target_router [description] * @param {Object} control_data [description] */ function fileUploadErrorFunction(target_file, file_pos, target_router, control_data) { console.log('{FILE} UPLOAD ERROR [%s/%s] FUNCTION CALL [%s]: %o', target_file, file_pos, target_router, control_data); // eg print special error data from control } // ** init here **/file-list $(document).ready(function () { // run and fill uploaded var call_id = 'fileList'; var queryString = { action: call_id }; ajaxWrapper(call_id, queryString).done(function (data) { console.log('Data: %o', data); try { if (data.status == 'error') { // } else { $('#reference-id').val(data.content.reference_id); // list files if (data.status == 'warn') { $('#file-info') .addClass('error-warn') .html(data.content.info); } else { $('#file-info').html(''); for (const files of data.content.file_list) { // console.log('F: %o', files); $('#file-list').append(phfo( aelx(cel('div', '', '', ['flx-ss']), cel('div', '', files.name, ['mg-5']), cel('div', '', files.create_date, ['mg-5']), cel('div', '', files.size, ['mg-5']), cel('input', 'uploaded-' + files.name, '', [], {type: 'hidden', value: files.name}) ) )); } } } // top message printMsg(data.msg); } catch (err) { afusErrorCatch(err); } }); // check that html elements needed are there // fill the file upload part initAjaxUploader({ target_file: 'first_upload', target_form: 'formdata', max_files: 5, target_router: 'fileUpload', target_action: '', form_parameters: {'parameter_a': 'Value 123'}, auto_submit: false, function_options: {action_box_id: 'actionBox-alt', 'other': 'free'}, translation: { remove: "REMOVE" }, fileChange: fileChangeFunction, fileChangeAll: fileChangeFunctionAll, fileRemove: fileRemoveFunction, fileClear: fileClearFunction, fileBeforeUploadAll: fileAppendBeforeUploadFunctionAllFunction, fileBeforeUpload: fileAppendBeforeUploadFunction, fileUploaded: fileUploadedFunction, fileUploadedAll: fileUploadedAllFunction, fileUploadError: fileUploadErrorFunction }); // for second test initAjaxUploader({ target_file: 'second_upload', target_form: 'formdata', max_files: 1, max_file_size: 500000, // ~500KB // allowed_extensions: ['txt', 'csv'], allowed_file_types: ['text/plain', 'text/csv'], target_router: 'fileUpload', target_action: '', form_parameters: {'parameter_b': 'Value 456'}, auto_submit: false, fileChange: fileChangeFunction, fileChangeAll: fileChangeFunctionAll, fileRemove: fileRemoveFunction, fileClear: fileClearFunction, fileBeforeUploadAll: fileAppendBeforeUploadFunctionAllFunction, fileBeforeUpload: fileAppendBeforeUploadFunction, fileUploaded: fileUploadedFunction, fileUploadedAll: fileUploadedAllFunction, fileUploadError: fileUploadErrorFunction }); // for third test initAjaxUploader({ target_file: 'third_upload', target_form: 'formdata', max_files: 0, target_router: 'fileUpload', target_action: '', form_parameters: {'parameter_c': 'Value 789'}, auto_submit: false, fileChange: fileChangeFunction, fileChangeAll: fileChangeFunctionAll, fileRemove: fileRemoveFunction, fileClear: fileClearFunction, fileBeforeUploadAll: fileAppendBeforeUploadFunctionAllFunction, fileBeforeUpload: fileAppendBeforeUploadFunction, fileUploaded: fileUploadedFunction, fileUploadedAll: fileUploadedAllFunction, fileUploadError: fileUploadErrorFunction }); });