Form changes Horizon - Upload Daily Field Work Photo
Specific Folder FTP Upload / ftp-deploy (push) Has been cancelled
Details
Specific Folder FTP Upload / ftp-deploy (push) Has been cancelled
Details
This commit is contained in:
parent
bd0629710e
commit
23885a6f3b
|
|
@ -148,24 +148,51 @@
|
||||||
|
|
||||||
@case('file')
|
@case('file')
|
||||||
@if(!isset($form->is_approval) || $form->is_approval != 'yes')
|
@if(!isset($form->is_approval) || $form->is_approval != 'yes')
|
||||||
@if($question->code == 'upload_photo')
|
|
||||||
<input
|
@if($question->code == 'upload_photo')
|
||||||
type="file"
|
<div id="photo-camera-container">
|
||||||
id="field-{{$question->code}}"
|
<video id="photo-camera-preview"
|
||||||
name="{{$question->code}}"
|
autoplay
|
||||||
class="form-control"
|
playsinline
|
||||||
|
style="display:none; width:100%; max-height:350px; border-radius:8px;">
|
||||||
|
</video>
|
||||||
|
|
||||||
|
<img id="photo-captured-preview"
|
||||||
|
alt="Captured photo"
|
||||||
|
style="display:none; width:100%; max-height:350px; object-fit:contain;">
|
||||||
|
|
||||||
|
<input type="file"
|
||||||
|
id="field-upload_photo"
|
||||||
|
name="upload_photo"
|
||||||
accept="image/*"
|
accept="image/*"
|
||||||
capture="environment"
|
data-required="{{$question->required == 'yes' ? '1' : '0'}}"
|
||||||
{{$question->required == 'yes' ? 'required' : ''}}>
|
style="display:none;">
|
||||||
@else
|
|
||||||
<input
|
<div class="d-flex flex-wrap gap-2 mt-2">
|
||||||
type="file"
|
<button type="button" id="start-photo-camera"
|
||||||
id="field-{{$question->code}}"
|
class="btn btn-primary">
|
||||||
name="{{$question->code}}"
|
Open Camera
|
||||||
class="form-control"
|
</button>
|
||||||
value=""
|
|
||||||
{{$question->required == 'yes' ? 'required' : ''}}>
|
<button type="button" id="capture-photo"
|
||||||
@endif
|
class="btn btn-success" style="display:none;">
|
||||||
|
Capture Photo
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button type="button" id="retake-photo"
|
||||||
|
class="btn btn-secondary" style="display:none;">
|
||||||
|
Retake Photo
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<input type="file"
|
||||||
|
id="field-{{$question->code}}"
|
||||||
|
name="{{$question->code}}"
|
||||||
|
class="form-control"
|
||||||
|
{{$question->required == 'yes' ? 'required' : ''}}>
|
||||||
|
@endif
|
||||||
|
|
||||||
@elseif(isset($question->value))
|
@elseif(isset($question->value))
|
||||||
<img src="{{$question->value}}" class="img-fluid">
|
<img src="{{$question->value}}" class="img-fluid">
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -254,6 +281,22 @@
|
||||||
|
|
||||||
$('#report-form').on('submit', function(event){
|
$('#report-form').on('submit', function(event){
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
const photoField = document.getElementById('field-upload_photo');
|
||||||
|
|
||||||
|
if (
|
||||||
|
photoField &&
|
||||||
|
photoField.dataset.required === '1' &&
|
||||||
|
photoField.files.length === 0
|
||||||
|
) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'warning',
|
||||||
|
title: 'Photo Required',
|
||||||
|
text: 'Please open the camera and capture a photo before submitting.'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$("#pageloader").fadeIn();
|
$("#pageloader").fadeIn();
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
|
|
@ -297,6 +340,102 @@
|
||||||
dateField.setAttribute('max', currentDate);
|
dateField.setAttribute('max', currentDate);
|
||||||
dateField.style.pointerEvents = 'none';
|
dateField.style.pointerEvents = 'none';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let photoStream = null;
|
||||||
|
|
||||||
|
const video = document.getElementById('photo-camera-preview');
|
||||||
|
const preview = document.getElementById('photo-captured-preview');
|
||||||
|
const photoInput = document.getElementById('field-upload_photo');
|
||||||
|
|
||||||
|
$('#start-photo-camera').on('click', async function () {
|
||||||
|
try {
|
||||||
|
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
||||||
|
throw new Error('Camera access is not supported by this browser.');
|
||||||
|
}
|
||||||
|
|
||||||
|
photoStream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
video: { facingMode: { ideal: 'environment' } },
|
||||||
|
audio: false
|
||||||
|
});
|
||||||
|
|
||||||
|
video.srcObject = photoStream;
|
||||||
|
video.style.display = 'block';
|
||||||
|
preview.style.display = 'none';
|
||||||
|
|
||||||
|
$('#start-photo-camera').hide();
|
||||||
|
$('#capture-photo').show();
|
||||||
|
$('#retake-photo').hide();
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Camera Unavailable',
|
||||||
|
text: 'Please allow camera access and try again.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#capture-photo').on('click', function () {
|
||||||
|
if (!photoStream || !video.videoWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = video.videoWidth;
|
||||||
|
canvas.height = video.videoHeight;
|
||||||
|
|
||||||
|
canvas.getContext('2d').drawImage(
|
||||||
|
video, 0, 0, canvas.width, canvas.height
|
||||||
|
);
|
||||||
|
|
||||||
|
canvas.toBlob(function (blob) {
|
||||||
|
if (!blob) {
|
||||||
|
Swal.fire('Error', 'Could not capture the photo.', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = new File(
|
||||||
|
[blob],
|
||||||
|
'captured-photo.jpg',
|
||||||
|
{ type: 'image/jpeg' }
|
||||||
|
);
|
||||||
|
|
||||||
|
const transfer = new DataTransfer();
|
||||||
|
transfer.items.add(file);
|
||||||
|
photoInput.files = transfer.files;
|
||||||
|
|
||||||
|
preview.src = URL.createObjectURL(blob);
|
||||||
|
preview.style.display = 'block';
|
||||||
|
video.style.display = 'none';
|
||||||
|
|
||||||
|
stopPhotoCamera();
|
||||||
|
|
||||||
|
$('#capture-photo').hide();
|
||||||
|
$('#start-photo-camera').hide();
|
||||||
|
$('#retake-photo').show();
|
||||||
|
}, 'image/jpeg', 0.9);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#retake-photo').on('click', function () {
|
||||||
|
photoInput.value = '';
|
||||||
|
preview.src = '';
|
||||||
|
preview.style.display = 'none';
|
||||||
|
$('#retake-photo').hide();
|
||||||
|
$('#start-photo-camera').trigger('click');
|
||||||
|
});
|
||||||
|
|
||||||
|
function stopPhotoCamera() {
|
||||||
|
if (photoStream) {
|
||||||
|
photoStream.getTracks().forEach(track => track.stop());
|
||||||
|
photoStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
video.srcObject = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('beforeunload', stopPhotoCamera);
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue