Form changes Horizon - Upload Daily Field Work Photo
Specific Folder FTP Upload / ftp-deploy (push) Successful in 1m21s
Details
Specific Folder FTP Upload / ftp-deploy (push) Successful in 1m21s
Details
This commit is contained in:
parent
de0ef5dcaa
commit
07a127d003
|
|
@ -157,9 +157,9 @@
|
||||||
@break
|
@break
|
||||||
|
|
||||||
@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')
|
@if($question->code == 'upload_photo')
|
||||||
|
|
||||||
<div class="d-flex align-items-center gap-2 mb-2">
|
<div class="d-flex align-items-center gap-2 mb-2">
|
||||||
<label for="field-upload_photo" class="form-label mb-0">
|
<label for="field-upload_photo" class="form-label mb-0">
|
||||||
{{$question->question}}
|
{{$question->question}}
|
||||||
|
|
@ -167,22 +167,53 @@
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<button type="button" id="start-photo-camera"
|
<button type="button" id="start-photo-camera"
|
||||||
class="btn btn-primary btn-sm">
|
class="btn btn-primary btn-sm">
|
||||||
Open Camera
|
Open Camera
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@else
|
|
||||||
<label for="field-{{$question->code}}" class="form-label">
|
|
||||||
{{$question->question}}
|
|
||||||
{!!$question->required == 'yes' ? '<span class="text-danger">*</span>':''!!}
|
|
||||||
</label>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
|
|
||||||
@elseif(isset($question->value))
|
<div id="photo-camera-container">
|
||||||
<img src="{{$question->value}}" class="img-fluid">
|
<video id="photo-camera-preview"
|
||||||
|
autoplay 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/*"
|
||||||
|
data-required="{{$question->required == 'yes' ? '1' : '0'}}"
|
||||||
|
style="display:none;">
|
||||||
|
|
||||||
|
<div class="d-flex flex-wrap gap-2 mt-2">
|
||||||
|
<button type="button" id="capture-photo"
|
||||||
|
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
|
@endif
|
||||||
@break
|
|
||||||
|
@elseif(isset($question->value))
|
||||||
|
<img src="{{$question->value}}" class="img-fluid">
|
||||||
|
@endif
|
||||||
|
@break
|
||||||
|
|
||||||
@case('multitextbox')
|
@case('multitextbox')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
@ -366,47 +397,63 @@
|
||||||
const photoInput = document.getElementById('field-upload_photo');
|
const photoInput = document.getElementById('field-upload_photo');
|
||||||
|
|
||||||
$('#start-photo-camera').on('click', async function () {
|
$('#start-photo-camera').on('click', async function () {
|
||||||
try {
|
try {
|
||||||
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
if (!navigator.mediaDevices ||
|
||||||
throw new Error('Camera access requires HTTPS or localhost.');
|
!navigator.mediaDevices.getUserMedia) {
|
||||||
}
|
throw new Error('Camera API is unavailable. Use HTTPS or localhost.');
|
||||||
|
}
|
||||||
|
|
||||||
// This triggers the browser's native camera permission prompt
|
// Request camera permission
|
||||||
photoStream = await navigator.mediaDevices.getUserMedia({
|
photoStream = await navigator.mediaDevices.getUserMedia({
|
||||||
video: { facingMode: { ideal: 'environment' } },
|
video: {
|
||||||
audio: false
|
facingMode: { ideal: 'environment' }
|
||||||
});
|
},
|
||||||
|
audio: false
|
||||||
|
});
|
||||||
|
|
||||||
video.srcObject = photoStream;
|
// Check required elements
|
||||||
video.style.display = 'block';
|
if (!video || !preview || !photoInput) {
|
||||||
preview.style.display = 'none';
|
throw new Error('Camera elements are missing from the page.');
|
||||||
|
}
|
||||||
|
|
||||||
$('#start-photo-camera').hide();
|
video.srcObject = photoStream;
|
||||||
$('#capture-photo').show();
|
video.style.display = 'block';
|
||||||
$('#retake-photo').hide();
|
preview.style.display = 'none';
|
||||||
|
|
||||||
} catch (error) {
|
await video.play();
|
||||||
console.error('Camera error:', error);
|
|
||||||
|
|
||||||
if (error.name === 'NotAllowedError' ||
|
$('#start-photo-camera').hide();
|
||||||
error.name === 'PermissionDeniedError') {
|
$('#capture-photo').show();
|
||||||
|
$('#retake-photo').hide();
|
||||||
|
|
||||||
Swal.fire({
|
} catch (error) {
|
||||||
icon: 'warning',
|
console.error('Camera error:', error);
|
||||||
title: 'Camera Permission Required',
|
|
||||||
text: 'Please allow camera access in your browser settings and click Open Camera again.'
|
// Stop any partially opened camera stream
|
||||||
|
if (photoStream) {
|
||||||
|
photoStream.getTracks().forEach(track => track.stop());
|
||||||
|
photoStream = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error.name === 'NotAllowedError' ||
|
||||||
|
error.name === 'PermissionDeniedError') {
|
||||||
|
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'warning',
|
||||||
|
title: 'Camera Access Denied',
|
||||||
|
text: 'Please enable camera permission for this website in your browser settings, then try again.'
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
icon: 'error',
|
||||||
|
title: 'Unable to Open Camera',
|
||||||
|
text: error.message || 'Please check your camera and try again.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
|
||||||
Swal.fire({
|
|
||||||
icon: 'error',
|
|
||||||
title: 'Camera Unavailable',
|
|
||||||
text: 'Unable to access your camera. Please check your camera and try again.'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#capture-photo').on('click', function () {
|
$('#capture-photo').on('click', function () {
|
||||||
if (!photoStream || !video.videoWidth) {
|
if (!photoStream || !video.videoWidth) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue