function selectAttachment() { var elementToChooseFile = document.getElementById('AttachFile'); elementToChooseFile.click(); var progressBarContainer = document.createElement('div'); progressBarContainer.className = 'progress-container'; var progressBar = document.createElement('div'); progressBar.className = 'progress-bar'; progressBar.style.width = '0'; progressBarContainer.appendChild(progressBar); var containerForFile = document.querySelector('.ContainerForFile'); containerForFile.appendChild(progressBarContainer); var uploadButton = document.getElementById('UploadButton'); uploadButton.blur(); } var guidArray = []; var selectedFilesCount = 0; var additionalFileCount = 0; var uploadedChunksCountsforAzure = {}; // Object to store the number of uploaded chunks for each file for azure storage var uploadedChunksCountsforNotes = {}; // Object to store the number of uploaded chunks for each file for notes storage var totalExpectedChunks = 0; var filesToWaitForSubmitEnable = 0; var deletedAnnotations = []; var completeUploadedAnnotations = []; function chooseAttachment() { var elementToChooseFile = document.getElementById('AttachFile'); var newdivforfile = document.getElementById('newdivforfileinfo'); var additionalFileDiv = document.querySelector('.additional-files'); // Create a parent container div for additional files after reflow var parentContainerDiv = document.createElement('div'); parentContainerDiv.className = 'additional-files-container'; var allFiles = elementToChooseFile.files; var elementForZeroFile = document.createElement("input"); elementForZeroFile.setAttribute("type", "file"); elementToChooseFile.files = elementForZeroFile.files; var location = document.getElementById("AttachFile_HiddenField_Location"); var formId = document.getElementById("AttachFile_HiddenField_FormID"); var formInstanceId = document.getElementById("AttachFile_HiddenField_InstanceId"); var regardingId = document.getElementById("AttachFile_HiddenField_RegardingId"); var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; allFiles = validateFiles(allFiles); if (allFiles == null) { return; } for (var i = 0; i < allFiles.length; i++) { var file = allFiles[i]; var fileName = file.name; var fileSize = file.size; var fileExtension = getFileExtension(fileName); if (selectedFilesCount < maxFileLimit) { selectedFilesCount++; } else { //Show maxLimitError if max file limit is reached var content = document.querySelector('.file-limit'); content.textContent = window.ResourceManager['Upload_a_maximum_of_validation'] + maxFileLimit + window.ResourceManager['files']; $('#ModalToShowErrorForFileLimit').modal('show'); $('#ModalToShowErrorForFileLimit').attr('tabindex', '0'); return; } if (selectedFilesCount >= maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = true; } // Calculate file size in KB, MB, or GB var fileSizeDisplay; if (fileSize >= 1024 * 1024 * 1024) { fileSizeDisplay = (fileSize / (1024 * 1024 * 1024)).toFixed(1) + ' GB'; } else if (fileSize >= 1024 * 1024) { fileSizeDisplay = (fileSize / (1024 * 1024)).toFixed(1) + ' MB'; } else if (fileSize >= 1024) { fileSizeDisplay = (fileSize / 1024).toFixed(1) + ' KB'; } else { fileSizeDisplay = fileSize + ' bytes'; } if (!navigator.onLine) { selectedFilesCount--; var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Retry_Span_Error_Message']; return; } // clientside file extension validation if (!checkFileExtension(file.type, fileName)) { continue; } // Clientside FileSize validation if (!checkFileSize(fileSize, fileName)) { continue; } // Logic for overflow Div var linesOccupiedByFiles = getNumberOfRowsOccupied(newdivforfile); if (linesOccupiedByFiles) { newdivforfile.appendChild(parentContainerDiv); overflowdivlogic(file, parentContainerDiv, additionalFileDiv, fileName, fileExtension, formId, formInstanceId, "", "", regardingId, selectedFilesCount, fileSizeDisplay); if (additionalFileDiv) { parentContainerDiv.appendChild(additionalFileDiv); newdivforfile.appendChild(parentContainerDiv); additionalFileDiv.style.display = 'none'; // Hide initially } } // Logic for each file getting uploaded in new div for files else { // Create a new button for each file var fileButton = document.createElement('div'); fileButton.type = 'button'; fileButton.className = 'custom-button'; var fileNameAndSizeSpan = document.createElement('div'); fileNameAndSizeSpan.className = 'fileNameAndSizeSpan '; fileNameAndSizeSpan.style.display = 'flex'; fileNameAndSizeSpan.style.margin = 'auto'; var fileIcondiv = document.createElement('div'); fileIcondiv.style.display = 'block'; var fileIcon = getFileIconByExtension(fileName); fileIcon.className = 'fileicon'; fileIcondiv.appendChild(fileIcon); fileNameAndSizeSpan.appendChild(fileIcondiv); var imageerrordiv = document.createElement('div'); imageerrordiv.className = 'erroricondiv'; imageerrordiv.style.display = 'none'; var errorIcon = customRenderImageTag("/xrm-adx/icons/error.png", "errorcircle"); errorIcon.className = 'erroricon'; imageerrordiv.appendChild(errorIcon); fileNameAndSizeSpan.appendChild(imageerrordiv); var fileNameSpan = document.createElement('div'); fileNameSpan.className = "filename"; fileNameSpan.ariaLabel = fileName + ' (' + fileSizeDisplay + ')'; fileNameSpan.title = fileName + ' (' + fileSizeDisplay + ')'; fileNameSpan.textContent = truncateFileName(fileName, 22, ' (' + fileSizeDisplay + ')'); fileNameAndSizeSpan.appendChild(fileNameSpan); fileNameSpan.tabIndex = 0; // Add a progress bar var progressBarContainer = document.createElement('div'); progressBarContainer.className = 'progress-container'; progressBarContainer.tabIndex = '0'; progressBarContainer.style.display = 'inline-flex'; progressBarContainer.style.width = '25%'; progressBarContainer.style.height = '5px'; progressBarContainer.style.backgroundColor = '#e1dfdd'; // Grey background progressBarContainer.style.margin = 'auto'; progressBarContainer.style.marginLeft = '20px' progressBarContainer.style.marginRight = '2px'; var progressBar = document.createElement('div'); progressBar.className = 'progress-bar'; progressBar.ariaLabel = '0% of the file is uploaded'; progressBar.style.width = '0'; progressBar.style.height = '100%'; progressBar.style.backgroundColor = '#018a39'; // Green color progressBar.style.transition = 'width 1s'; // Animation for width changes progressBarContainer.appendChild(progressBar); var reloadIcondiv = document.createElement('div'); reloadIcondiv.className = 'reloadicondiv'; reloadIcondiv.style.display = 'none'; var reloadIcon = customRenderImageTag("/xrm-adx/icons/retry.png", "delete"); reloadIcon.className = 'reloadicon'; reloadIcondiv.appendChild(reloadIcon); fileNameAndSizeSpan.appendChild(reloadIcondiv); var retrySpan = document.createElement('button'); retrySpan.className = 'retrySpan'; retrySpan.textContent = 'Retry'; fileNameAndSizeSpan.appendChild(retrySpan); var canceldiv = document.createElement('button'); canceldiv.style.background = 'none'; canceldiv.style.border = 'none'; canceldiv.style.display = 'flex'; canceldiv.style.margin = 'auto'; canceldiv.className = 'cancelIconDiv' var cancelIcon = customRenderImageTag("/xrm-adx/icons/Cancel.svg", "cancel"); cancelIcon.className = 'cancelicon'; canceldiv.setAttribute('aria-label', 'Cancelicon'); canceldiv.appendChild(cancelIcon); canceldiv.onclick = function (e) { e.preventDefault(); deleteFileFromUI(fileButton); }; canceldiv.tabIndex = 0; var imagediv = document.createElement('button'); imagediv.className = 'deleteicondiv'; imagediv.style.display = 'none'; imagediv.style.margin = 'auto'; var deleteIcon = customRenderImageTag("/xrm-adx/icons/Delete.svg", "delete"); deleteIcon.className = 'deleteicon'; imagediv.setAttribute('aria-label', 'deleteicon'); imagediv.onclick = function (e) { e.preventDefault(); deleteFileFromUI(fileButton); }; imagediv.appendChild(deleteIcon); var loaderdiv = document.createElement('button'); loaderdiv.className = 'loadericondiv'; loaderdiv.style.margin = 'auto'; loaderdiv.style.display = 'none'; var loadericon = customRenderImageTag("/xrm-adx/icons/SpinnerBase.svg", "loaderfordelete"); loaderdiv.appendChild(loadericon); fileNameSpan.focus(); fileButton.appendChild(fileNameAndSizeSpan); fileButton.appendChild(progressBarContainer); fileButton.appendChild(canceldiv); fileButton.appendChild(imagediv); fileButton.appendChild(loaderdiv); if (location.value == "AzureBlobStorage") { uploadedChunksCountsforAzure[fileName] = 0; // Initialize uploadedChunksCounts for each file totalExpectedChunks += calculateTotalChunks(file.size); // Calculate total expected chunks uploadAzureFile(file, fileExtension, fileSizeDisplay, formId.value, formInstanceId.value, progressBar, fileButton, regardingId.value, fileName); } else if (location.value == "CrmDocument") { uploadedChunksCountsforNotes[fileName] = 0; // Initialize uploadedChunksCounts for each file totalExpectedChunks += calculateTotalChunks(file.size); // Calculate total expected chunks uploadNotesFile(file, fileExtension, fileSizeDisplay, formId.value, formInstanceId.value, progressBar, fileButton, regardingId.value, fileName); } var newdivforfile = document.getElementById('newdivforfileinfo'); var additionalFilesContainer = document.querySelector(".additional-files-container"); if (additionalFilesContainer) { newdivforfile.insertBefore(fileButton, additionalFilesContainer); } else { newdivforfile.appendChild(fileButton); } } } } var unsupportedFileNamesNullAlert = ""; function validateFilesForNullError(file, fileButton) { var genericErrorStatus = false; var filesValidatedArray = []; if (genericErrorStatus) { filesValidatedArray.push(file); } else { if (genericErrorStatus == false) { if (unsupportedFileNamesNullAlert == "") { unsupportedFileNamesNullAlert += file.name; } else { unsupportedFileNamesNullAlert += " , " + file.name; } } } if (unsupportedFileNamesNullAlert != "") { var errordivforgenericfail = document.querySelector('.errordiv.generic.alert-danger'); errordivforgenericfail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanforgeneric'); retrySpanfordelete.textContent = unsupportedFileNamesNullAlert + window.ResourceManager['Attachments_NullSize']; } var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.removeChild(fileButton); return filesValidatedArray; } var unsupportedFileNamesAlert = ""; function validateFilesForGenericError(file, response, fileButton) { var genericErrorStatus = true; if (response.ErrorCode != "AU00029" || response.ErrorCode != "AU00039" || response.ErrorCode != "AU00038" || response.ErrorCode != "AU00040" || response.ErrorCode != "AU00041") { genericErrorStatus = false; } var filesValidatedArray = []; if (genericErrorStatus) { filesValidatedArray.push(file); } else { if (genericErrorStatus == false) { if (unsupportedFileNamesAlert == "") { unsupportedFileNamesAlert += file.name; } else { unsupportedFileNamesAlert += " , " + file.name; } } } if (unsupportedFileNamesAlert != "") { var errordivforgenericfail = document.querySelector('.errordiv.generic.alert-danger'); errordivforgenericfail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanforgeneric'); retrySpanfordelete.textContent = unsupportedFileNamesAlert + window.ResourceManager['Generic_Fail']; } var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.removeChild(fileButton); return filesValidatedArray; } function validateFiles(allFiles) { var fileExtensionStatus = Array(allFiles.length).fill(true); var fileSizeStatus = Array(allFiles.length).fill(true); var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; var unsupportedFileNames = ""; if (maxFileLimit > 15) { maxFileLimit = 15; } if ((allFiles.length + selectedFilesCount) > maxFileLimit) { //Show maxLimitError if max file limit is reached var content = document.querySelector('.file-limit'); content.textContent = window.ResourceManager['Upload_a_maximum_of_validation'] + maxFileLimit + window.ResourceManager['files']; $('#ModalToShowErrorForFileLimit').modal('show'); $('#ModalToShowErrorForFileLimit').attr('tabindex', '0'); return null; } for (var i = 0; i < allFiles.length; i++) { var file = allFiles[i]; // clientside file extension validation if (!checkFileExtension(file.type, file.name, false)) { fileExtensionStatus[i] = false; } // Clientside FileSize validation if (!checkFileSize(file.size, file.name, false)) { fileSizeStatus[i] = false; } } for (var i = 0; i < allFiles.length; i++) { if (fileExtensionStatus[i] == false) { if (unsupportedFileNames == "") { unsupportedFileNames += allFiles[i].name; } else { unsupportedFileNames += " , " + allFiles[i].name; } } } if (unsupportedFileNames != "") { var content = document.querySelector('.file-type'); var supportedTypes = getSupportedTypes(); content.textContent = unsupportedFileNames + window.ResourceManager['Not_supported_file_extensions'] + " " + supportedTypes + " " + window.ResourceManager['files']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileTypeError = elementToChooseFile.attributes["data-file-type-error-message"]; if (configuredFileTypeError) { var configuredFileTypeErrorMessage = configuredFileTypeError.value; if (configuredFileTypeErrorMessage) { content.textContent = configuredFileTypeErrorMessage; } } $('#ModalToShowErrorForFileType').modal('show'); $('#ModalToShowErrorForFileType').attr('tabindex', '0'); } unsupportedFileNames = ""; for (var i = 0; i < allFiles.length; i++) { if (fileSizeStatus[i] == false) { if (unsupportedFileNames == "") { unsupportedFileNames += allFiles[i].name; } else { unsupportedFileNames += " , " + allFiles[i].name; } } } if (unsupportedFileNames != "") { var maxFileSize = document.getElementById("AttachFile_HiddenField_MaxFileSizeInKB").value; var fileSizeDisplay; if (maxFileSize >= 1024 * 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024 * 1024)).toFixed(1) + ' GB '; } else if (maxFileSize >= 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024)).toFixed(1) + ' MB '; } else if (maxFileSize >= 1024) { fileSizeDisplay = (maxFileSize / 1024).toFixed(1) + ' KB '; } else { fileSizeDisplay = maxFileSize + ' bytes '; } var content = document.querySelector('.file-size'); content.textContent = unsupportedFileNames + window.ResourceManager['MaxFileSize_Error_Message'] + fileSizeDisplay + window.ResourceManager['Try_again']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileSizeError = elementToChooseFile.attributes["data-file-size-error-message"]; if (configuredFileSizeError) { var configuredFileSizeErrorMessage = configuredFileSizeError.value; if (configuredFileSizeErrorMessage) { content.textContent = configuredFileSizeErrorMessage; } } $('#ModalToShowErrorForFileSize').modal('show'); $('#ModalToShowErrorForFileSize').attr('tabindex', '0'); } var filesValidatedArray = []; for (var i = 0; i < allFiles.length; i++) { if (fileSizeStatus[i] && fileExtensionStatus[i]) { filesValidatedArray.push(allFiles[i]); } } return filesValidatedArray; } function overflowdivlogic(file, parentContainerDiv, additionalFileDiv, fileName, fileExtension, formId, formInstanceId, progressBar, fileButton, regardingId, selectedFilesCount, fileSizeDisplay) { // Check if an overflow button is already present var overflowButton = document.querySelector('.overflow-button'); var additionalFileDiv = document.querySelector('.additional-files'); var showOverflowButton = false; var location = document.getElementById("AttachFile_HiddenField_Location"); var newdivforfile = document.getElementById('newdivforfileinfo'); if (overflowButton) { overflowButton.innerHTML = additionalFileCount + 1 + " more "; } showOverflowButton = true; // check if overflow button is already present else add it if (showOverflowButton && !overflowButton) { var overflowButton = document.createElement('button'); overflowButton.type = 'button'; overflowButton.className = 'overflow-button'; overflowButton.innerHTML = "1 more "; overflowButton.onclick = function () { additionalFileDiv.style.display = (additionalFileDiv.style.display === 'none' || additionalFileDiv.style.display === '') ? 'block' : 'none'; }; parentContainerDiv.appendChild(overflowButton); } // check if additional files div is already present and keep appending the uploaded files if (!additionalFileDiv) { var additionalFileDiv = document.createElement('div'); additionalFileDiv.className = 'additional-files'; additionalFileDiv.style.display = 'none'; parentContainerDiv.appendChild(additionalFileDiv); newdivforfile.appendChild(parentContainerDiv); } // create new div for reflow files var fileDiv = document.createElement('div'); fileDiv.style.padding = '5px 5px 5px 5px'; fileDiv.style.display = 'flex'; var fileIcon = getFileIconByExtension(fileName); fileIcon.className = 'fileicon'; fileDiv.appendChild(fileIcon); var fileNameElement = document.createElement('span'); fileNameElement.className = "filename"; fileNameElement.tabIndex = '0'; fileNameElement.textContent = truncateFileName(fileName, 22, ''); fileNameElement.ariaLabel = fileName; fileNameElement.title = fileName; fileDiv.appendChild(fileNameElement); var deleteButton = document.createElement('button'); deleteButton.className = 'deleteicondiv'; deleteButton.style.display = 'flex'; deleteButton.style.margin = 'auto'; deleteButton.style.background = 'none'; deleteButton.style.border = 'none'; var deleteIcon = customRenderImageTag("/xrm-adx/icons/Delete.svg", "delete"); deleteIcon.className = 'deleteicon'; deleteButton.setAttribute('aria-label', 'deleteicon'); deleteButton.appendChild(deleteIcon); deleteButton.tabIndex = '0'; deleteButton.disabled = true; fileDiv.appendChild(deleteButton); additionalFileCount++; additionalFileDiv.appendChild(fileDiv); if (location.value == "AzureBlobStorage") { uploadedChunksCountsforAzure[fileName] = 0; // Initialize uploadedChunksCounts for each file totalExpectedChunks += calculateTotalChunks(file.size); // Calculate total expected chunks uploadAzureFile(file, fileExtension, fileSizeDisplay, formId.value, formInstanceId.value, progressBar, fileButton, regardingId.value, fileName, fileDiv); } else if (location.value == "CrmDocument") { uploadedChunksCountsforNotes[fileName] = 0; // Initialize uploadedChunksCounts for each file totalExpectedChunks += calculateTotalChunks(file.size); // Calculate total expected chunks uploadNotesFile(file, fileExtension, fileSizeDisplay, formId.value, formInstanceId.value, progressBar, fileButton, regardingId.value, fileName, fileDiv); } } // Calculating chunks for each file uplaoded function calculateTotalChunks(fileSize) { let chunkSize = 50 * 1024 * 1024; //50mb if (fileSize <= 10 * 1024 * 1024) //10mb { chunkSize = 4 * 1024 * 1024; //4mb } else if (fileSize <= 100 * 1024 * 1024) //100mb { chunkSize = 10 * 1024 * 1024; //10mb } let numberOfBlocks; if (fileSize % chunkSize == 0) { numberOfBlocks = fileSize / chunkSize; } else { numberOfBlocks = parseInt(fileSize / chunkSize, 10) + 1; } return numberOfBlocks; } (function (webapi, $) { function safeAjax(ajaxOptions) { var deferredAjax = $.Deferred(); shell.getTokenDeferred().done(function (token) { // add headers for AJAX if (!ajaxOptions.headers) { $.extend(ajaxOptions, { headers: { "__RequestVerificationToken": token } }); } else { ajaxOptions.headers["__RequestVerificationToken"] = token; } $.ajax(ajaxOptions) .done(function (data, textStatus, jqXHR) { validateLoginSession(data, textStatus, jqXHR, deferredAjax.resolve); }).fail(deferredAjax.reject); //AJAX }).fail(function () { deferredAjax.rejectWith(this, arguments); // on token failure pass the token AJAX and args }); return deferredAjax.promise(); } webapi.safeAjax = safeAjax; })(window.webapi = window.webapi || {}, jQuery) var uploadedChunksfornotes = 0; function showRefreshWarning() { var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Attachments_RefreshPage']; } function showDialogForMaxLimit(fileButton) { var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; //Show maxLimitError if max file limit is reached var content = document.querySelector('.file-limit'); content.textContent = window.ResourceManager['Upload_a_maximum_of_validation'] + maxFileLimit; $('#ModalToShowErrorForFileLimit').modal('show'); $('#ModalToShowErrorForFileLimit').attr('tabindex', '0'); var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.removeChild(fileButton); return null; } function showDialogForSizeLimit(fileName,fileButton) { var maxFileSize = document.getElementById("AttachFile_HiddenField_MaxFileSizeInKB").value; var fileSizeDisplay; if (maxFileSize >= 1024 * 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024 * 1024)).toFixed(1) + ' GB '; } else if (maxFileSize >= 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024)).toFixed(1) + ' MB '; } else if (maxFileSize >= 1024) { fileSizeDisplay = (maxFileSize / 1024).toFixed(1) + ' KB '; } else { fileSizeDisplay = maxFileSize + ' bytes '; } var content = document.querySelector('.file-size'); content.textContent = fileName + window.ResourceManager['MaxFileSize_Error_Message'] + fileSizeDisplay + window.ResourceManager['Try_again']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileSizeError = elementToChooseFile.attributes["data-file-size-error-message"]; if (configuredFileSizeError) { var configuredFileSizeErrorMessage = configuredFileSizeError.value; if (configuredFileSizeErrorMessage) { content.textContent = configuredFileSizeErrorMessage; } } $('#ModalToShowErrorForFileSize').modal('show'); $('#ModalToShowErrorForFileSize').attr('tabindex', '0'); var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.removeChild(fileButton); return null; } function showDialogForType(fileName, fileButton) { var supportedTypes = getSupportedTypes(); var content = document.querySelector('.file-type'); content.textContent = fileName + window.ResourceManager['Not_supported_file_extensions'] + " " + supportedTypes + " " + window.ResourceManager['files']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileTypeError = elementToChooseFile.attributes["data-file-type-error-message"]; if (configuredFileTypeError) { var configuredFileTypeErrorMessage = configuredFileTypeError.value; if (configuredFileTypeErrorMessage) { content.textContent = configuredFileTypeErrorMessage; } } $('#ModalToShowErrorForFileType').modal('show'); $('#ModalToShowErrorForFileType').attr('tabindex', '0'); var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.removeChild(fileButton); return null; } function uploadNotesFile(file, fileExtension, fileSizeDisplay, formId, formInstanceId, progressBar, fileButton, regardingId, fileName, fileDiv = undefined) { var formType = document.getElementById("AttachFile_HiddenField_FormType").value; var url = "/_api/file/InitializeFileUpload/note?" + "formType=" + formType + "&" + "formId=" + formId + "®ardingId=" + regardingId; var fileName = file.name; var filetype = file.type; var fileSize = file.size; var fileExtension = getFileExtension(fileName); const encodedFileName = encodeURIComponent(fileName); var filename = encodedFileName; let chunkSize = 50 * 1024 * 1024; //50mb if (file.size <= 10 * 1024 * 1024) //10mb { chunkSize = 4 * 1024 * 1024; //4mb } else if (file.size <= 100 * 1024 * 1024) //100mb { chunkSize = 10 * 1024 * 1024; //10mb } let numberOfBlocks; let token; let fileContinuationToken; let cancelUpload = false; // Flag to track cancellation if (file.size % chunkSize == 0) { numberOfBlocks = file.size / chunkSize; } else { numberOfBlocks = Math.ceil(file.size / chunkSize); } let initializationSuccess = false; // Flag to track initialization success webapi.safeAjax({ type: "POST", url: url,//replace this with url headers: { "x-ms-file-name": filename, "x-ms-file-size": file.size, "x-ms-form-session-id": formInstanceId, "x-ms-file-type": filetype || "application/octet-stream" }, contentType: (filetype === "application/json" || filetype === "text/json") ? "application/octet-stream" : filetype, processData: false, data: null, success: function (response, status, xhr) { // Set the submit button disabled once upload starts var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = true; filesToWaitForSubmitEnable++; token = response.AnnotationId; initializationSuccess = true; if (fileButton) { // Append each new button to the div fileButton.querySelector(".cancelIconDiv").onclick = function (e) { e.preventDefault(); // Cancel upload logic cancelUpload = true; deleteNotesFile(fileName, fileButton, token, formInstanceId); }; } var encodedToken = encodeURIComponent(response.FileContinuationToken); fileContinuationToken = encodedToken; uploadNoteChunk(0); }, error: function (XMLHttpRequest, textStatus, errorThrown) { selectedFilesCount--; var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } var response = JSON.parse(XMLHttpRequest.responseText); if (response && response.ErrorCode === "AU00040") { handleRetryLogic(blockno); } if (response.ErrorCode === "AU00039") { var button = document.getElementById("UploadButton"); button.disabled = true; showDialogForMaxLimit(fileButton); } else if (response.ErrorCode === "AU00038") { showDialogForSizeLimit(fileName, fileButton); } else if (response.ErrorCode === "AU00029") { showDialogForType(fileName, fileButton); } else if (response && response.ErrorCode === "AU00041") { showRefreshWarning(); } else if (response && (response.ErrorCode === "AU0009" || response.ErrorCode === "AU00010" || response.ErrorCode === "AU00033")) { validateFilesForNullError(file, fileButton); } else { validateFilesForGenericError(file, response, fileButton); } } }); function uploadNoteChunk(blockno) { if (!initializationSuccess || cancelUpload) return; var fileReader = new FileReader(); if (blockno < numberOfBlocks) { var end = (blockno * chunkSize + chunkSize) > file.size ? blockno * chunkSize + file.size % chunkSize : blockno * chunkSize + chunkSize; var content = file.slice(blockno * chunkSize, end); fileReader.readAsArrayBuffer(content); } fileReader.onload = function () { webapi.safeAjax({ type: "PUT", url: "/_api/file/UploadFileBlock/note?offset=" + (blockno * chunkSize) + "&fileSize=" + file.size + "&chunkSize=" + chunkSize + "¬eId=" + token + "&formType=" + formType + "&formId=" + formId, headers: { "x-ms-file-name": filename, "x-ms-form-session-id": formInstanceId, "x-ms-file-continuation-token": fileContinuationToken, "x-ms-file-type" : filetype || "application/octet-stream" }, contentType: (filetype === "application/json" || filetype === "text/json") ? "application/octet-stream" : filetype, processData: false, data: content, success: function (res, status, xhr) { var percentComplete = ((parseFloat(end) / parseFloat(file.size)) * 100).toFixed(2); uploadedChunksCountsforNotes[fileName]++; // Increment the uploaded chunks count for this file totalExpectedChunks--; // Decrement total expected chunks animateProgressBarForNoteFile(fileName, fileExtension, fileButton, fileSizeDisplay, progressBar, percentComplete, token, formInstanceId, fileDiv); uploadNoteChunk(blockno + 1); }, error: function (XMLHttpRequest, textStatus, errorThrown) { selectedFilesCount--; var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } var response = JSON.parse(XMLHttpRequest.responseText); if (cancelUpload && response.ErrorCode === "AU0003") { // cancel is done and call already started would give 404 return; } if (response && response.ErrorCode === "AU00040") { handleRetryLogic(blockno); } if (response.ErrorCode === "AU00039") { var button = document.getElementById("UploadButton"); button.disabled = true; showDialogForMaxLimit(fileButton); } else if (response.ErrorCode === "AU00038") { showDialogForSizeLimit(fileName, fileButton); } else if (response.ErrorCode === "AU00029") { showDialogForType(fileName, fileButton); } else if (response && response.ErrorCode === "AU00041") { showRefreshWarning(); } else if (response && (response.ErrorCode === "AU0009" || response.ErrorCode === "AU00010" || response.ErrorCode === "AU00033")) { validateFilesForNullError(file, fileButton); } else { validateFilesForGenericError(file, response, fileButton); } } }); } } } var uploadedChunksforazure = 0; function uploadAzureFile(file, fileExtension, fileSizeDisplay, formId, formInstanceId, progressBar, fileButton, regardingId, fileName, fileDiv = undefined) { var formType = document.getElementById("AttachFile_HiddenField_FormType").value; var url = "/_api/file/InitializeFileUpload/blob?" + "formType=" + formType + "&" + "formId=" + formId + "®ardingId=" + regardingId; var fileName = file.name; var filetype = file.type; var fileSize = file.size; var fileExtension = getFileExtension(fileName); const encodedFileName = encodeURIComponent(fileName); var filename = encodedFileName; let chunkSize = 50 * 1024 * 1024; //50mb if (file.size <= 10 * 1024 * 1024) //10mb { chunkSize = 4 * 1024 * 1024; //4mb } else if (file.size <= 100 * 1024 * 1024) //100mb { chunkSize = 10 * 1024 * 1024; //10mb } let numberOfBlocks; let token; let fileContinuationToken; let cancelUpload = false; // Flag to track cancellation if (file.size % chunkSize == 0) { numberOfBlocks = file.size / chunkSize; } else { numberOfBlocks = Math.ceil(file.size / chunkSize); } let initializationSuccess = false; // Flag to track initialization success webapi.safeAjax({ type: "POST", url: url,//replace this with url headers: { "x-ms-file-name": filename, "x-ms-file-size": file.size, "x-ms-form-session-id": formInstanceId, "x-ms-file-type": filetype || "application/octet-stream" }, contentType: (filetype === "application/json" || filetype === "text/json") ? "application/octet-stream" : filetype, processData: false, data: null, success: function (response, status, xhr) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = true; filesToWaitForSubmitEnable++; token = response.AnnotationId; initializationSuccess = true; if (fileButton) { fileButton.querySelector(".cancelIconDiv").onclick = function (e) { e.preventDefault(); // Cancel upload logic cancelUpload = true; deleteAzureFile(fileName, fileButton, token, formInstanceId); }; } var encodedToken = encodeURIComponent(response.FileContinuationToken); fileContinuationToken = encodedToken; uploadFileChunk(0); }, error: function (XMLHttpRequest, textStatus, errorThrown) { selectedFilesCount--; var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } var response = JSON.parse(XMLHttpRequest.responseText); if (response && response.ErrorCode === "AU00040") { handleRetryLogic(blockno); } else if (response.ErrorCode === "AU00039") { var button = document.getElementById("UploadButton"); button.disabled = true; showDialogForMaxLimit(fileButton); } else if (response.ErrorCode === "AU00038") { showDialogForSizeLimit(fileName, fileButton); } else if (response.ErrorCode === "AU00029") { showDialogForType(fileName, fileButton); } else if (response && (response.ErrorCode === "AU0009" || response.ErrorCode === "AU00010" || response.ErrorCode === "AU00033")) { validateFilesForNullError(file, fileButton); } else if (response && response.ErrorCode === "AU00041") { showRefreshWarning(); } else { validateFilesForGenericError(file, response, fileButton); } } }); function uploadFileChunk(blockno) { if (!initializationSuccess || cancelUpload) return; var fileReader = new FileReader(); if (blockno < numberOfBlocks) { var end = (blockno * chunkSize + chunkSize) > file.size ? blockno * chunkSize + file.size % chunkSize : blockno * chunkSize + chunkSize; var content = file.slice(blockno * chunkSize, end); fileReader.readAsArrayBuffer(content); } fileReader.onload = function () { webapi.safeAjax({ type: "PUT", url: "/_api/file/UploadFileBlock/blob?offset=" + (blockno * chunkSize) + "&fileSize=" + file.size + "&chunkSize=" + chunkSize + "¬eId=" + token + "&formType=" + formType + "&" + "formId=" + formId, headers: { "x-ms-file-name": filename, "x-ms-form-session-id": formInstanceId, "x-ms-file-continuation-token": fileContinuationToken, "x-ms-file-type": filetype || "application/octet-stream" }, contentType: (filetype === "application/json" || filetype === "text/json") ? "application/octet-stream" : filetype, processData: false, data: content, success: function (res, status, xhr) { var percentComplete = ((parseFloat(end) / parseFloat(file.size)) * 100).toFixed(2); animateProgressBarForAzureFile(fileName, fileExtension, fileButton, fileSizeDisplay, progressBar, percentComplete, token, formInstanceId, fileDiv); uploadFileChunk(blockno + 1); uploadedChunksCountsforAzure[fileName]++; // Increment the uploaded chunks count for this file totalExpectedChunks--; // Decrement total expected chunks }, error: function (XMLHttpRequest, textStatus, errorThrown) { selectedFilesCount--; var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } var response = JSON.parse(XMLHttpRequest.responseText); if (cancelUpload && response.ErrorCode === "AU0003") { // cancel is done and call already started would give 404 return; } if (response && response.ErrorCode === "AU00040") { handleRetryLogic(blockno); } else if (response.ErrorCode === "AU00039") { var button = document.getElementById("UploadButton"); button.disabled = true; ; showDialogForMaxLimit(fileButton); } else if (response.ErrorCode === "AU00038") { showDialogForSizeLimit(fileName, fileButton); } else if (response.ErrorCode === "AU00029") { showDialogForType(fileName, fileButton); } else if (response && (response.ErrorCode === "AU0009" || response.ErrorCode === "AU00010" || response.ErrorCode === "AU00033")) { validateFilesForNullError(file, fileButton); } else if (response && response.ErrorCode === "AU00041") { showRefreshWarning(); } else { validateFilesForGenericError(file, response, fileButton); } } }); } } } function handleRetryLogic(blockno) { var newdivforfile = document.getElementById('newdivforfileinfo'); newdivforfile.appendChild(fileButton); var errordiv = document.querySelector('.errordiv.alert-danger'); errordiv.style.display = 'block'; var erroricon = document.querySelector('.erroricondiv'); erroricon.style.display = 'block'; var fileicon = document.querySelector('.fileicon'); fileicon.style.display = 'none'; var retryspan = document.querySelector('.retrySpan'); retryspan.style.display = 'block'; retryspan.addEventListener('click', function () { uploadFileChunk(blockno); }); var reloadicon = document.querySelector('.reloadicondiv'); reloadicon.style.display = 'block'; reloadicon.addEventListener('click', function () { uploadFileChunk(blockno); }); var filebutton = document.querySelector('.custom-button'); filebutton.classList.add('alert-danger'); } function animateProgressBarForAzureFile(fileName, fileExtension, fileButton, fileSizeDisplay, progressBar, percentComplete, annotationId, formInstanceId, fileDiv = undefined) { if (fileDiv == undefined) { progressBar.style.width = percentComplete + "%"; progressBar.ariaLabel = percentComplete + "% of the file is uploaded"; if (percentComplete == 100) { guidArray.push(annotationId); completeUploadedAnnotations.push(annotationId); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); if (!deletedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } fileButton.style.backgroundColor = "#FFFFFF"; fileButton.style.boxShadow = "0px 1px 2px 0px rgba(0,0,0,0.36)"; // filename to 15 chars var filename = fileButton.querySelector('.filename'); filename.textContent = truncateFileName(fileName, 30, ' (' + fileSizeDisplay + ')'); // cancel div tabindex -1 var canceldiv = fileButton.querySelector('.cancelIconDiv'); canceldiv.tabIndex = -1; // If progress bar reached 100%, replace cross icon with delete icon progressBar.parentElement.style.display = 'none'; var crossIcon = fileButton.querySelector('.cancelicon'); crossIcon.style.display = 'none'; // Hide cross icon ////for complete upload state var deleteIcon = fileButton.querySelector('.deleteicondiv'); deleteIcon.style.display = 'flex'; deleteIcon.style.margin = 'auto'; deleteIcon.style.background = 'none'; deleteIcon.style.border = 'none'; deleteIcon.tabIndex = 0; // Add event listener to deleteIcon deleteIcon.onclick = function (e) { e.preventDefault(); deleteAzureFile(fileName, fileButton, annotationId, formInstanceId); }; var fileNameAndSizeSpan = fileButton.querySelector('.filename'); // Add hover effect to show the file name as a link fileNameAndSizeSpan.onmouseover = function () { this.style.textDecoration = 'underline'; this.style.cursor = 'pointer'; this.style.color = '#0078D4'; fileButton.style.boxShadow = "0px 3.2px 7.2px 0px rgba(0,0,0,0.33)"; this.onclick = function () { var url = "/_api/file/download/blob?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); }; }; // Remove hover effect when not hovering fileNameAndSizeSpan.onmouseout = function () { this.style.textDecoration = 'none'; this.style.cursor = 'default'; this.style.color = 'initial'; fileButton.style.boxShadow = "0px 1px 2px 0px rgba(0,0,0,0.36)"; this.onclick = null; }; // Add keydown event listener to enable Enter keypress fileNameAndSizeSpan.addEventListener('keydown', function (event) { if (event.key === 'Enter') { var url = "/_api/file/download/blob?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); } }); } } else { if (percentComplete == 100) { guidArray.push(annotationId); completeUploadedAnnotations.push(annotationId); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); if (!deletedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } // Hide cross icon ////for complete upload state var deleteIcon = fileDiv.querySelector('.deleteicondiv'); deleteIcon.disabled = false; // Add event listener to deleteIcon deleteIcon.onclick = function (e) { e.preventDefault(); var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; // Handle delete file logic here var url = "/_api/file/delete/blob?" + "noteId=" + annotationId; webapi.safeAjax({ //$.ajax({ url: url, type: "DELETE", headers: { "x-ms-form-session-id": formInstanceId }, success: function () { // delete that element var newdiv = fileDiv.parentElement; newdiv.removeChild(fileDiv); additionalFileCount--; var overflowButton = document.querySelector('.overflow-button'); if (overflowButton) { overflowButton.innerHTML = additionalFileCount + " more "; } if (additionalFileCount <= 0) { var container = document.querySelector(".additional-files-container"); container.parentElement.removeChild(container); } if (!completeUploadedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } // delete annotation id from input hidden array var index = guidArray.indexOf(annotationId); if (index !== -1) { guidArray.splice(index, 1); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); } selectedFilesCount--; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } }, error: function (XMLHttpRequest, textStatus, errorThrown) { var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Delete_Fail_one'] + fileName + window.ResourceManager['Delete_Fail_second']; } }); }; var fileNameAndSizeSpan = fileDiv.querySelector('.filename'); // Add hover effect to show the file name as a link fileNameAndSizeSpan.onmouseover = function () { this.style.textDecoration = 'underline'; this.style.cursor = 'pointer'; this.style.color = '#0078D4'; fileButton.style.boxShadow = "0px 3.2px 7.2px 0px rgba(0,0,0,0.33)"; this.onclick = function () { var url = "/_api/file/download/blob?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); }; }; // Remove hover effect when not hovering fileNameAndSizeSpan.onmouseout = function () { this.style.textDecoration = 'none'; this.style.cursor = 'default'; this.style.color = 'initial'; fileButton.style.boxShadow = "0px 1px 2px 0px rgba(0,0,0,0.36)"; this.onclick = null; }; // Add keydown event listener to enable Enter keypress fileNameAndSizeSpan.addEventListener('keydown', function (event) { if (event.key === 'Enter') { var url = "/_api/file/download/note?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); } }); } } } function animateProgressBarForNoteFile(fileName, fileExtension, fileButton, fileSizeDisplay, progressBar, percentComplete, annotationId, formInstanceId, fileDiv = undefined) { if (fileDiv == undefined) { progressBar.style.width = percentComplete + "%"; progressBar.ariaLabel = percentComplete + "% of the file is uploaded"; if (percentComplete == 100) { guidArray.push(annotationId); completeUploadedAnnotations.push(annotationId); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); if (!deletedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } fileButton.style.backgroundColor = "#FFFFFF"; fileButton.style.boxShadow = "0px 1px 2px 0px rgba(0,0,0,0.36)"; // filename to 15 chars var filename = fileButton.querySelector('.filename'); filename.textContent = truncateFileName(fileName, 30, ' (' + fileSizeDisplay + ')'); // cancel div tabindex -1 var canceldiv = fileButton.querySelector('.cancelIconDiv'); canceldiv.tabIndex = -1; // If progress bar reached 100%, replace cross icon with delete icon progressBar.parentElement.style.display = 'none'; var crossIcon = fileButton.querySelector('.cancelicon'); crossIcon.style.display = 'none'; // Hide cross icon ////for complete upload state var deleteIcon = fileButton.querySelector('.deleteicondiv'); deleteIcon.style.display = 'flex'; deleteIcon.style.margin = 'auto'; deleteIcon.style.background = 'none'; deleteIcon.style.border = 'none'; // Add event listener to deleteIcon deleteIcon.onclick = function (e) { e.preventDefault(); deleteNotesFile(fileName, fileButton, annotationId, formInstanceId); }; var fileNameAndSizeSpan = fileButton.querySelector('.filename'); // Add hover effect to show the file name as a link fileNameAndSizeSpan.onmouseover = function () { this.style.textDecoration = 'underline'; this.style.cursor = 'pointer'; this.style.color = '#0078D4'; this.onclick = function () { var url = "/_api/file/download/note?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); }; }; // Remove hover effect when not hovering fileNameAndSizeSpan.onmouseout = function () { this.style.textDecoration = 'none'; this.style.cursor = 'default'; this.style.color = 'initial'; this.onclick = null; }; // Add keydown event listener to enable Enter keypress fileNameAndSizeSpan.addEventListener('keydown', function (event) { if (event.key === 'Enter') { var url = "/_api/file/download/note?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); } }); } } else { if (percentComplete == 100) { guidArray.push(annotationId); completeUploadedAnnotations.push(annotationId); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); // Hide cross icon ////for complete upload state var deleteIcon = fileDiv.querySelector('.deleteicondiv'); deleteIcon.disabled = false; if (!deletedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } // Add event listener to deleteIcon deleteIcon.onclick = function (e) { e.preventDefault(); var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; // Handle delete file logic here var url = "/_api/file/delete/note?" + "noteId=" + annotationId; webapi.safeAjax({ //$.ajax({ url: url, type: "DELETE", headers: { "x-ms-form-session-id": formInstanceId }, success: function () { // delete that element var newdiv = fileDiv.parentElement; newdiv.removeChild(fileDiv); additionalFileCount--; var overflowButton = document.querySelector('.overflow-button'); if (overflowButton) { overflowButton.innerHTML = additionalFileCount + " more "; } if (additionalFileCount <= 0) { var container = document.querySelector(".additional-files-container"); container.parentElement.removeChild(container); } if (!completeUploadedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } // delete annotation id from input hidden array var index = guidArray.indexOf(annotationId); if (index !== -1) { guidArray.splice(index, 1); document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); } selectedFilesCount--; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } }, error: function (XMLHttpRequest, textStatus, errorThrown) { var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Delete_Fail_one'] + fileName + window.ResourceManager['Delete_Fail_second']; } }); }; var fileNameAndSizeSpan = fileDiv.querySelector('.filename'); // Add hover effect to show the file name as a link fileNameAndSizeSpan.onmouseover = function () { this.style.textDecoration = 'underline'; this.style.cursor = 'pointer'; this.style.color = '#0078D4'; this.onclick = function () { var url = "/_api/file/download/note?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); }; }; // Remove hover effect when not hovering fileNameAndSizeSpan.onmouseout = function () { this.style.textDecoration = 'none'; this.style.cursor = 'default'; this.style.color = 'initial'; this.onclick = null; }; // Add keydown event listener to enable Enter keypress fileNameAndSizeSpan.addEventListener('keydown', function (event) { if (event.key === 'Enter') { var url = "/_api/file/download/note?noteId=" + annotationId + "&formInstanceId=" + encodeURIComponent(formInstanceId); window.open(url, "_blank"); } }); } } } function getFileExtension(fileName) { var lastDotIndex = fileName.lastIndexOf('.'); if (lastDotIndex !== -1 && lastDotIndex > 0) { var extension = fileName.substring(lastDotIndex + 1).toLowerCase(); return extension; } else { return ''; } } function getNumberOfRowsOccupied(element) { var maxHeightThreshold = 150; var rect = element.getBoundingClientRect(); var elementHeight = rect.height; if (elementHeight >= maxHeightThreshold) { return true; } else { return false; } } function truncateFileName(filename, maxLength, filesize) { const parts = filename.split('.'); const extension = parts.pop(); let fileName = parts.join('.'); // Determine the prefix and suffix lengths based on the maxLength const remainingLength = maxLength - extension.length - filesize.length - 5; if (fileName.length <= remainingLength) { return `${fileName}.${extension}${filesize}`; } const prefixLength = Math.floor(remainingLength / 2); const suffixLength = remainingLength - prefixLength; // Truncate the filename const truncated = `${fileName.substring(0, prefixLength)}...${fileName.substring(fileName.length - suffixLength)}`; return `${truncated}.${extension}${filesize}`; } function deleteAzureFile(fileName, fileButton, annotationId, formInstanceId) { var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; var deleteIcon = fileButton.querySelector('.deleteicondiv'); deleteIcon.style.display = 'none'; var cancelIcon = fileButton.querySelector('.cancelIconDiv'); cancelIcon.style.display = 'none'; var loaderdiv = fileButton.querySelector('.loadericondiv'); loaderdiv.style.display = 'flex'; loaderdiv.style.margin = 'auto'; loaderdiv.classList.add("loading"); // Add a CSS class for loading animation // Handle delete file logic here var url = "/_api/file/delete/blob?" + "noteId=" + annotationId; webapi.safeAjax({ //$.ajax({ url: url, type: "DELETE", headers: { "x-ms-form-session-id": formInstanceId}, success: function () { // delete that element deleteFileFromUI(fileButton); loaderdiv.classList.remove("loading"); // Remove loading class selectedFilesCount--; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } // delete annotation id from input hidden array var index = guidArray.indexOf(annotationId); if (index !== -1) { guidArray.splice(index, 1); if (guidArray.length == 0) { document.getElementById("AttachFile_HiddenField_AnnotationIds").value = ""; } else { document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); } } if (!completeUploadedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } deletedAnnotations.push(annotationId); // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } }, error: function (XMLHttpRequest, textStatus, errorThrown) { // Remove loader on error deleteIcon.style.display = 'block'; loaderdiv.style.display = 'none'; var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Delete_Fail_one'] + fileName + window.ResourceManager['Delete_Fail_second']; } }); } function deleteNotesFile(fileName, fileButton, annotationId, formInstanceId) { var maxFileLimit = document.getElementById("AttachFile_HiddenField_MaxFile").value; // Handle delete file logic here var url = "/_api/file/delete/note?" + "noteId=" + annotationId; var deleteIcon = fileButton.querySelector('.deleteicondiv'); deleteIcon.style.display = 'none'; var cancelIcon = fileButton.querySelector('.cancelIconDiv'); cancelIcon.style.display = 'none'; var loaderdiv = fileButton.querySelector('.loadericondiv'); loaderdiv.style.display = 'flex'; loaderdiv.style.margin = 'auto'; loaderdiv.classList.add("loading"); // Add a CSS class for loading animation webapi.safeAjax({ //$.ajax({ url: url, type: "DELETE", headers: { "x-ms-form-session-id": formInstanceId }, success: function () { // delete that element deleteFileFromUI(fileButton); loaderdiv.classList.remove("loading"); // Remove loading class selectedFilesCount--; if (selectedFilesCount < maxFileLimit) { var button = document.getElementById("UploadButton"); button.disabled = false; } // delete annotation id from input hidden array var index = guidArray.indexOf(annotationId); if (index !== -1) { guidArray.splice(index, 1); if (guidArray.length == 0) { document.getElementById("AttachFile_HiddenField_AnnotationIds").value = ""; } else { document.getElementById("AttachFile_HiddenField_AnnotationIds").value = JSON.stringify(guidArray); } } if (!completeUploadedAnnotations.includes(annotationId)) { filesToWaitForSubmitEnable--; } deletedAnnotations.push(annotationId); // Enable submit button if all chunks for all files are uploaded if (filesToWaitForSubmitEnable <= 0) { var submitButton = document.getElementById("UpdateButton") || document.getElementById("InsertButton") || document.getElementById("SubmitButton") || document.getElementById("NextButton"); submitButton.disabled = false; } }, error: function (XMLHttpRequest, textStatus, errorThrown) { // Remove loader on error deleteIcon.style.display = 'block'; loaderdiv.style.display = 'none'; var errordivfordeletefail = document.querySelector('.errordiv.deletefail.alert-danger'); errordivfordeletefail.style.display = 'flex'; var retrySpanfordelete = document.querySelector('.retrySpanfordelete'); retrySpanfordelete.textContent = window.ResourceManager['Delete_Fail_one'] + fileName + window.ResourceManager['Delete_Fail_second']; } }); } function deleteFileFromUI(fileButton) { var newdivforfile = document.getElementById('newdivforfileinfo'); // Remove the specified fileButton newdivforfile.removeChild(fileButton); } function customRenderImageTag(url, altText) { const cdnUrl = document.getElementById("CdnUrl").value; const imageUrl = "/icons/" + (url ? url.split('/').pop() : ''); const builder = document.createElement("img"); builder.setAttribute("alt", altText); if (cdnUrl) { builder.setAttribute("src", cdnUrl + imageUrl); const onErrorFallbackScript = `javascript: var target = event.target; var img = document.createElement('img'); img.src = '${url}'; img.alt = '${altText}' ; target.insertAdjacentElement('afterend',img); target.remove();`; } else { builder.setAttribute("src", url); } return builder; } function checkFileSize(fileSize, fileName, showModal = true) { var maxFileSize = document.getElementById("AttachFile_HiddenField_MaxFileSizeInKB").value; var fileSizeDisplay; if (maxFileSize >= 1024 * 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024 * 1024)).toFixed(1) + ' GB '; } else if (maxFileSize >= 1024 * 1024) { fileSizeDisplay = (maxFileSize / (1024 * 1024)).toFixed(1) + ' MB '; } else if (maxFileSize >= 1024) { fileSizeDisplay = (maxFileSize / 1024).toFixed(1) + ' KB '; } else { fileSizeDisplay = maxFileSize + ' bytes '; } if (fileSize > maxFileSize) { if (showModal) { var content = document.querySelector('.file-size'); content.textContent = fileName + window.ResourceManager['MaxFileSize_Error_Message'] + fileSizeDisplay + window.ResourceManager['Try_again']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileSizeError = elementToChooseFile.attributes["data-file-size-error-message"]; if (configuredFileSizeError) { var configuredFileSizeErrorMessage = configuredFileSizeError.value; if (configuredFileSizeErrorMessage) { content.textContent = configuredFileSizeErrorMessage; } } $('#ModalToShowErrorForFileSize').modal('show'); $('#ModalToShowErrorForFileSize').attr('tabindex', '0'); } return false; } return true; } function checkFileExtension(fileType, fileName, showModal = true) { var supportedFileTypes = document.getElementById("AttachFile_HiddenField_SupportedFileType").value; var supportedMimeTypes = document.getElementById("AttachFile_HiddenField_SupportedMimeType").value; var supportedTypes = getSupportedTypes(); const mimeTypesArray = supportedMimeTypes.split(',').map(type => type.trim()); const extensionsArray = supportedFileTypes.split(',').map(ext => ext.trim()); // Validate MIME type against allowed patterns let isValidMimeType = false; mimeTypesArray.forEach(pattern => { const regexPattern = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$', 'i'); if (regexPattern.test(fileType)) { isValidMimeType = true; } }); if (mimeTypesArray.includes("*/*")) { isValidMimeType = true; } // Validate file extension against allowed extensions var fileExtension = fileName.split('.').pop().toLowerCase(); fileExtension = "." + fileExtension; const isValidExtension = extensionsArray.includes(fileExtension); // Check if both MIME type and file extension are valid if (isValidMimeType || isValidExtension) { return true; } else { if (showModal) { var content = document.querySelector('.file-type'); content.textContent = fileName + window.ResourceManager['Not_supported_file_extensions'] + " " + supportedTypes + " " + window.ResourceManager['files']; var elementToChooseFile = document.getElementById('AttachFile'); var configuredFileTypeError = elementToChooseFile.attributes["data-file-type-error-message"]; if (configuredFileTypeError) { var configuredFileTypeErrorMessage = configuredFileTypeError.value; if (configuredFileTypeErrorMessage) { content.textContent = configuredFileTypeErrorMessage; } } $('#ModalToShowErrorForFileType').modal('show'); $('#ModalToShowErrorForFileType').attr('tabindex', '0'); } return false; } } function getSupportedTypes() { var supportedFileTypes = document.getElementById("AttachFile_HiddenField_SupportedFileType").value; var supportedMimeTypes = document.getElementById("AttachFile_HiddenField_SupportedMimeType").value; let types = supportedMimeTypes.split(',').map(type => { let trimmedType = type.trim(); let parts = trimmedType.split('/'); // Handle invalid MIME type case if (parts.length !== 2 || !parts[0].trim() || !parts[1].trim()) { return ''; } // Handle specific case where MIME type is "^$" or any other misconfigurations if (trimmedType === "^$" || (parts[0].trim() === "^" && parts[1].trim() === "$")) { return ''; } return parts[1].trim() !== '*' ? parts[1].trim() : parts[0].trim(); }).filter(type => type !== ''); // Joining processed types into a comma-separated string let supportedTypes = types.join(', '); // Checking and appending additional extensions if attachFileAcceptExtensions is not empty if (supportedFileTypes && supportedFileTypes.trim() !== '') { if (supportedTypes && supportedFileTypes.trim() !== '') { supportedTypes += ', ' + supportedFileTypes.trim(); } else { supportedTypes = supportedFileTypes.trim(); } } return supportedTypes; } function closeModalForFileLimit() { $('#ModalToShowErrorForFileLimit').modal('hide'); } function closeModalForFileSize() { $('#ModalToShowErrorForFileSize').modal('hide'); } function closeModalForFileType() { $('#ModalToShowErrorForFileType').modal('hide'); } function genericcloseAlert() { var closealert = document.querySelector('.errordiv.generic.alert-danger'); closealert.style.display = 'none'; } function deletecloseAlert() { var closealert = document.querySelector('.errordiv.deletefail.alert-danger'); closealert.style.display = 'none'; } function getFileIconByExtension(fileName) { var fileExtension = getFileExtension(fileName); switch (fileExtension) { case 'mp3': case 'wav': case 'flac': case 'aac': case 'ogg': case 'wma': return customRenderImageTag("/xrm-adx/icons/audio.svg", "audiofile"); case 'png': case 'jpeg': case 'jpg': case 'gif': case 'bmp': case 'tiff': case 'svg': return customRenderImageTag("/xrm-adx/icons/photo360.svg", "imagefile"); case 'ppt': case 'pptx': return customRenderImageTag("/xrm-adx/icons/pptx.svg", "pptfile"); case 'doc': case 'docx': return customRenderImageTag("/xrm-adx/icons/docx.svg", "wordfile"); case 'xls': case 'xlsx': return customRenderImageTag("/xrm-adx/icons/xlsx.svg", "excelfile"); case 'pdf': return customRenderImageTag("/xrm-adx/icons/pdf.svg", "pdffile"); case 'odt': case 'rtf': case 'txt': return customRenderImageTag("/xrm-adx/icons/txt.svg", "textfile"); case 'mp4': case 'avi': case 'mkv': case 'mov': case 'wmv': case 'flv': return customRenderImageTag("/xrm-adx/icons/video.svg", "videofile"); default: return customRenderImageTag("/xrm-adx/icons/default.svg", "defaultfile"); } }