1var maxFileSize = 10; 2var maxFileCount = 5; 3var currentFileCount = 0; 4var nextFileCount = []; 5var validImageTypes = [ 6 'image/jpeg', 7 'image/png', 8 'application/pdf', 9 'application/msword', 10 'application/vnd.ms-excel', 11 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 12 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 13 'application/octet-stream' 14]; 15 16if (window.$ == undefined) window.$ = jQuery; 17 18// Hide emergency wrapper 19if ( 20 window.location.pathname == '/practice_response/' || 21 window.location.pathname == 'practice_response/' || 22 window.location.pathname == 'practice_response' || 23 window.location.pathname == '/practice_response' 24) { 25 var emergency = document.getElementById('emergency-popup-wrapper'); 26 27 if (emergency) { 28 emergency.style.display = 'none'; 29 } 30} 31 32function patientFileChanged(element) { 33 if ($(element)[0].files.length == 1) { 34 var fileSizeExceded = false; 35 var file = $(element)[0].files[0]; 36 var fileSize = file.size / 1024 / 1024; 37 fileSize = fileSize.toFixed(2); 38 39 if (fileSize >= maxFileSize) { 40 fileSizeExceded = true; 41 } 42 43 var fileType = file.type; 44 if ($.inArray(fileType, validImageTypes) < 0) { 45 46 const formGroup = $(element).closest('.nhsuk-form-group'); 47 48 formGroup.find('#file-size-error').remove(); 49 formGroup.addClass('nhsuk-form-group--error'); 50 51 const addFileButton = formGroup.find('#add-file-button'); 52 53 addFileButton.after(` 54 <p id="file-size-error" role="alert" class="nhsuk-error-message"> 55 <span class="nhsuk-u-visually-hidden">Error:</span> 56 The selected file must be a jpg, png, doc, docx, pdf, xls or xlsx 57 </p> 58 `); 59 60 const currentDescribedBy = addFileButton.attr('aria-describedby') || ''; 61 const describedByParts = currentDescribedBy.split(' ').filter(id => id !== 'file-size-error'); 62 describedByParts.unshift('file-size-error'); 63 addFileButton.attr('aria-describedby', describedByParts.join(' ')); 64 $(element).val(''); 65 66 $(element) 67 .closest('.nhsuk-grid-column-one-third.nhsuk-card-group__item') 68 .remove(); 69 return; 70 } else { 71 const formGroup = $(element).closest('.nhsuk-form-group'); 72 73 formGroup.find('#file-size-error').remove(); 74 formGroup.removeClass('nhsuk-form-group--error'); 75 76 const addFileButton = formGroup.find('#add-file-button'); 77 const currentDescribedBy = addFileButton.attr('aria-describedby') || ''; 78 const updatedDescribedBy = currentDescribedBy 79 .split(' ') 80 .filter(id => id !== 'file-size-error') 81 .join(' '); 82 addFileButton.attr('aria-describedby', updatedDescribedBy); 83 } 84 85 var itemCount = $(element).attr('next-file'); 86 87 if (fileSizeExceded) { 88 89 const formGroup = $(element).closest('.nhsuk-form-group'); 90 91 formGroup.find('#file-size-error').remove(); 92 93 formGroup.addClass('nhsuk-form-group--error'); 94 95 const addFileButton = formGroup.find('#add-file-button'); 96 addFileButton.after(` 97 <p id="file-size-error" role="alert" class="nhsuk-error-message"> 98 <span class="nhsuk-u-visually-hidden">Error:</span> 99 The selected file must be smaller than 10MB 100 </p> 101 `); 102 103 const currentDescribedBy = addFileButton.attr('aria-describedby') || ''; 104 const describedByParts = currentDescribedBy.split(' ').filter(id => id !== 'file-size-error'); 105 describedByParts.unshift('file-size-error'); 106 addFileButton.attr('aria-describedby', describedByParts.join(' ')); 107 $(element).val(''); 108 109 $(element) 110 .closest('.nhsuk-grid-column-one-third.nhsuk-card-group__item') 111 .remove(); 112 113 return; 114 } else { 115 const formGroup = $(element).closest('.nhsuk-form-group'); 116 117 formGroup.find('#file-size-error').remove(); 118 119 formGroup.removeClass('nhsuk-form-group--error'); 120 121 const addFileButton = formGroup.find('#add-file-button'); 122 const currentDescribedBy = addFileButton.attr('aria-describedby') || ''; 123 const updatedDescribedBy = currentDescribedBy 124 .split(' ') 125 .filter(id => id !== 'file-size-error') 126 .join(' '); 127 addFileButton.attr('aria-describedby', updatedDescribedBy); 128 } 129 130 setThumbnail(element, $('#patient_file_selector_' + itemCount + ' img')); 131 132 if (currentFileCount > 0) { 133 $('#add-file-button').html('Upload another file'); 134 } 135 136 if (currentFileCount == 5) { 137 $('#add-file-button').html('Maximum file limit of 5 reached'); 138 } 139 140 $('#patient_file_selector_' + itemCount + ' .nhsuk-card__img').after( 141 "<p id='patient_file_" + itemCount + "_desc' class='nhsuk-body-s'>" + 142 "<span class='nhsuk-u-visually-hidden'>File name: </span>" + file.name + 143 "</p>" 144 ); 145 146 $('#patient_file_selector_' + itemCount + ' .nhsuk-card__content').append(
147 "<button type='button' class='nhsuk-button nhsuk-button--secondary' " + 148 "aria-describedby='patient_file_" + itemCount + "_desc' " + 149 "onclick='removeSelectedFile(" + itemCount + ")'>" + 150 "Remove" + 151 "</button>" 152 ); 153 } 154} 155 156function addPatientFile(e) { 157 e.preventDefault(); 158 159 if (currentFileCount < 5) { 160 var count = currentFileCount; 161 162 if (nextFileCount.length > 0) { 163 count = nextFileCount[Math.floor(Math.random() * nextFileCount.length)]; 164 } 165 166 if (nextFileCount.length > 0) { 167 nextFileCount.splice(nextFileCount.indexOf(count), 1); 168 } 169 170 var nextFile = getNextAvaliablefile(); 171 172 $('#patient_files').append( 173 `<div class='nhsuk-grid-column-one-third nhsuk-card-group__item' id='patient_file_selector_${nextFile}'> 174 <div class='nhsuk-card nhsuk-card--clickable'> 175 <div class='nhsuk-card__content nhsuk-u-padding-3'> 176 <input 177 style="display:none" 178 next-file='${nextFile}' 179 onchange='patientFileChanged(this)' 180 type='file' 181 accept='.png,.PNG,.jpg,.jpeg,.JPG,.JPEG,.pdf,.msword,.doc,.docx,.xl,.xlsx' 182 name='patient_file_${nextFile}' 183 id='patient_file_${nextFile}' 184 /> 185 <img src='' class='nhsuk-card__img nhsuk-u-margin-bottom-3' /> 186 </div> 187 </div> 188 </div>` 189 ); 190 191 $('#patient_file_' + nextFile).click(); 192 193 $('#patient_file_' + nextFile).on('cancel', function() { 194 $('#patient_file_selector_' + nextFile).remove(); 195 }); 196 197 if (currentFileCount == 5) { 198 $('#add-file-button').html('You have reached the maximum of five attachments'); 199 $('#add-file-button').attr('disabled', true); 200 } 201 202 if (currentFileCount > 0) { 203 $('#add-file-button').html('Upload another file'); 204 } 205 206 currentFileCount = currentFileCount + 1; 207 } 208} 209 210function removeSelectedFile(fileId) { 211 $('#patient_file_selector_' + fileId).remove(); 212 nextFileCount.push(fileId); 213 currentFileCount = currentFileCount - 1; 214 215 if (currentFileCount == 0) { 216 $('#add-file-button').html('Upload file'); 217 } 218 219 if (currentFileCount < 5 && currentFileCount > 0) { 220 $('#add-file-button').html('Upload another file'); 221 $('#add-file-button').attr('disabled', false); 222 } 223} 224 225function setThumbnail(input, location) { 226 if (input.files && input.files[0]) { 227 var reader = new FileReader(); 228 reader.onload = function(e) { 229 $(location).attr('src', e.target.result); 230 }; 231 232 if ( 233 input.files[0].type.length == 0 || 234 input.files[0].type == 'application/pdf' || 235 input.files[0].type == 'application/msword' || 236 input.files[0].type == 237 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' || 238 input.files[0].type == 239 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 240 ) { 241 $(location).attr('src', '/wp-content/plugins/spForms/images/file.png'); 242 } else { 243 reader.readAsDataURL(input.files[0]); 244 } 245 } 246} 247 248function getNextAvaliablefile() { 249 for (var i = 0; i <= 4; i++) { 250 if ($('#patient_file_selector_' + i).length == 0) { 251 return i; 252 } 253 254 if ($('#patient_file_' + i) && $('#patient_file_' + i).get(0).files.length == 0) { 255 removeSelectedFile(i); 256 return i; 257 } 258 } 259} 260 261function initFileUpload() { 262 window.fileUploadInitiated = false; 263 264 var dropzoneItemsToReplace = $('.frm_dropzone'); 265 let container = dropzoneItemsToReplace.closest('.frm_form_field'); 266 267 if (container.hasClass('h1_label_l') || container.hasClass('h1_label_xl')) { 268 $('.frm_dropzone') 269 .siblings('h1').children('.frm_primary_label') 270 .addClass('nhsuk-label') 271 .attr('for', 'add-file-button'); 272 } else { 273 $('.frm_dropzone') 274 .siblings('.frm_primary_label') 275 .addClass('nhsuk-label nhsuk-label--s') 276 .attr('for', 'add-file-button'); 277 } 278 279 $('.frm_dropzone').removeAttr('aria-describedby'); 280 281 $('.frm_dropzone').map(function(item) { 282 window.fileUploadInitiated = true; 283 284 let uploadLabelId; 285 286 if ( container.hasClass('h1_label_l') || 287 container.hasClass('h1_label_xl')) { 288 289 uploadLabelId = $('.frm_dropzone') 290 .siblings('h1') 291 .children('.frm_primary_label') 292 .attr('id'); 293 } else { 294 uploadLabelId = $('.frm_dropzone') 295 .siblings('.frm_primary_label') 296 .attr('id'); 297 } 298 299 300 let fieldKey = uploadLabelId.split('_')[1]; 301 302 let ariaLabelledby = `field_${fieldKey}_label add-file-button`; 303 304 let ariaDescribedby = 'upload-sensitive upload-file-types upload-max-size'; 305 306 if ($(`#frm_desc_field_${fieldKey}`).length) { 307 ariaDescribedby = `frm_desc_field_${fieldKey} ${ariaDescribedby}`; 308 } 309 310 $(dropzoneItemsToReplace[item]).html( 311 `<div> 312 <p id='upload-sensitive'>Do not upload sensitive photographs of penises, vaginas, bottoms (anus), breasts or minors. Your uploads may be added to your health record.</p> 313 <p id="upload-file-types">Allowed file types: jpg, png, doc, docx, pdf, xls, xlsx</p> 314 <p id="upload-max-size">You can upload up to 5 files. Maximum file size is 10MB.</p> 315 <button 316 type='button' 317 id='add-file-button'
318 class='add-file nhsuk-button nhsuk-button--secondary' 319 aria-describedby='${ariaDescribedby}' 320 aria-labelledby='${ariaLabelledby}' 321 onclick='addPatientFile(event)'> 322 Upload file 323 </button> <input onclick='this.value=null;' accept='.png,.PNG,.jpg,.jpeg,.JPG,.JPEG' next-file='0' type='file' onchange='patientFileChanged(this)' id='general-file-selector' style='display:none' /> 324 </div> 325 <div class='nhsuk-grid-row nhsuk-card-group' id='patient_files'></div>` 326 ); 327 }); 328 329 if (window.fileUploadInitiated == false) { 330 $('#inner-content').bind('DOMNodeInserted', function(e) { 331 if (window.fileUploadInitiated == false) { 332 var dropzoneItemsToReplace = $('.frm_dropzone'); 333 if (dropzoneItemsToReplace.length > 0) { 334 $('#inner-content').unbind('DOMNodeInserted'); 335 $('.frm_dropzone').map(function(item) { 336 $(dropzoneItemsToReplace[item]).html( 337 `<div> 338 <pDo not upload sensitive photographs of genitalia, bottoms (anus), breasts or minors without asking a healthcare professional first. Your uploads may be stored on your health record.</p> 339 <button type='button' id='add-file-button' class='add-file' onclick='addPatientFile(event)'>Upload file</button> 340 <input onclick='this.value=null;' accept='.png,.PNG,.jpg,.jpeg,.JPG,.JPEG' next-file='0' type='file' onchange='patientFileChanged(this)' id='general-file-selector' style='display:none' /> 341 </div> 342 <div class='nhsuk-grid-row nhsuk-card-group' id='patient_files'></div>` 343 ); 344 window.fileUploadInitiated = true; 345 }); 346 } 347 } 348 }); 349 } 350} 351 352jQuery(document).ajaxSend(function (event, xhr, settings) { 353 // Detect ONLY Formidable submissions 354 if (settings.url.includes('admin-ajax.php') && settings.data.includes('frm_entries_create')) { 355 jQuery('#file-size-error').remove(); 356 jQuery('.nhsuk-form-group--error').removeClass('nhsuk-form-group--error'); 357 358 // Fix aria-describedby ONLY for add-file-button 359 let btn = jQuery('#add-file-button'); 360 361 if (btn.length) { 362 let aria = btn.attr('aria-describedby'); 363 364 if (aria && aria.includes('file-size-error')) { 365 let cleaned = aria 366 .split(' ') 367 .filter(id => id !== 'file-size-error') 368 .join(' '); 369 370 btn.attr('aria-describedby', cleaned.trim()); 371 } 372 } 373 } 374}); 375 376$(document).ready(function() { 377 initFileUpload(); 378}); 379 380$(document).on('frmPageChanged', () => { 381 initFileUpload(); 382});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.