574 lines
25 KiB
PHP
574 lines
25 KiB
PHP
@extends('layouts.admin.app')
|
|
|
|
@section('title', 'Tambah Cafe')
|
|
|
|
@section('styles')
|
|
@parent
|
|
<link href="https://cdn.jsdelivr.net/npm/cropperjs@1.5.13/dist/cropper.min.css" rel="stylesheet">
|
|
<style>
|
|
#map {
|
|
height: 400px !important;
|
|
width: 100% !important;
|
|
margin-bottom: 15px;
|
|
border-radius: 8px;
|
|
background-color: #f0f0f0;
|
|
border: 1px solid #ccc;
|
|
position: relative !important;
|
|
z-index: 1 !important;
|
|
}
|
|
.field-spacer {
|
|
margin-bottom: 20px;
|
|
}
|
|
select {
|
|
padding-top: 12px;
|
|
padding-bottom: 12px;
|
|
padding-left: 6px;
|
|
padding-right: 6px;
|
|
}
|
|
.leaflet-container {
|
|
z-index: 1 !important;
|
|
}
|
|
.leaflet-control-container {
|
|
z-index: 1000 !important;
|
|
}
|
|
/* Crop Modal Styles */
|
|
.crop-modal {
|
|
display: none;
|
|
position: fixed;
|
|
z-index: 9999;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
background-color: rgba(0, 0, 0, 0.7);
|
|
overflow: auto;
|
|
}
|
|
|
|
.crop-modal-content {
|
|
background-color: #fefefe;
|
|
margin: 5% auto;
|
|
padding: 20px;
|
|
border-radius: 8px;
|
|
width: 80%;
|
|
max-width: 800px;
|
|
}
|
|
|
|
.crop-img-container {
|
|
max-height: 60vh;
|
|
overflow: hidden;
|
|
margin-bottom: 15px;
|
|
}
|
|
|
|
.crop-controls {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
justify-content: flex-end;
|
|
}
|
|
|
|
.crop-controls button {
|
|
margin-left: 10px;
|
|
}
|
|
|
|
.preview-container {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 10px;
|
|
margin-top: 15px;
|
|
max-width: 340px;
|
|
}
|
|
|
|
.preview-image {
|
|
width: 100px;
|
|
height: 100px;
|
|
object-fit: cover;
|
|
border-radius: 4px;
|
|
border: 2px solid #ddd;
|
|
}
|
|
|
|
.sortable-indicator {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
background-color: rgba(0,0,0,0.5);
|
|
color: white;
|
|
z-index: 5;
|
|
opacity: 0;
|
|
transition: opacity 0.3s ease;
|
|
pointer-events: none;
|
|
}
|
|
|
|
.sortable-item:hover .sortable-indicator {
|
|
opacity: 1;
|
|
}
|
|
|
|
.delete-btn {
|
|
position: absolute;
|
|
top: 0;
|
|
right: 0;
|
|
background-color: #ef4444;
|
|
color: white;
|
|
width: 24px;
|
|
height: 24px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-size: 14px;
|
|
z-index: 20;
|
|
opacity: 0;
|
|
transition: all 0.3s;
|
|
cursor: pointer;
|
|
transform: translate(50%, -50%) scale(0.5);
|
|
box-shadow: 0 2px 5px rgba(0,0,0,0.3);
|
|
}
|
|
|
|
.sortable-item:hover .delete-btn {
|
|
opacity: 1;
|
|
transform: translate(0, 0) scale(1);
|
|
}
|
|
|
|
.delete-btn:hover {
|
|
background-color: #dc2626;
|
|
transform: scale(1.1);
|
|
}
|
|
</style>
|
|
@endsection
|
|
|
|
@section('content')
|
|
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 mb-8 border border-gray-100 dark:border-gray-700">
|
|
<div class="flex justify-between items-center mb-6">
|
|
<h1 class="text-2xl font-bold text-gray-800 dark:text-white">Tambah Cafe Baru</h1>
|
|
<a href="{{ route('admin.cafes.index') }}" class="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700 cursor-pointer">
|
|
Kembali
|
|
</a>
|
|
</div>
|
|
|
|
@if ($errors->any())
|
|
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-6 rounded" role="alert">
|
|
<p class="font-bold">Ada kesalahan dalam pengisian form:</p>
|
|
<ul>
|
|
@foreach ($errors->all() as $error)
|
|
<li>{{ $error }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
|
|
<form action="{{ route('admin.cafes.store') }}" method="POST" enctype="multipart/form-data" class="space-y-6">
|
|
@csrf
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
<!-- Kolom Kiri: Nama Cafe dan Peta -->
|
|
<div class="space-y-6">
|
|
<div class="field-spacer">
|
|
<label for="nama" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">NAMA CAFE</label>
|
|
<input type="text" name="nama" id="nama" value="{{ old('nama') }}" style="min-height: 48px; padding-top: 12px; padding-bottom: 12px; padding-left: 8px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50" required>
|
|
</div>
|
|
|
|
<div class="field-spacer">
|
|
<label for="area" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">AREA</label>
|
|
<div class="flex flex-wrap gap-4">
|
|
<div class="flex items-center">
|
|
<input type="checkbox" name="area[]" id="area_indoor" value="Indoor" {{ is_array(old('area')) && in_array('Indoor', old('area')) ? 'checked' : '' }} class="w-5 h-5 text-blue-600 dark:text-blue-500 rounded border-gray-300 focus:ring-blue-500">
|
|
<label for="area_indoor" class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">Indoor</label>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<input type="checkbox" name="area[]" id="area_semi_outdoor" value="Semi Outdoor" {{ is_array(old('area')) && in_array('Semi Outdoor', old('area')) ? 'checked' : '' }} class="w-5 h-5 text-blue-600 dark:text-blue-500 rounded border-gray-300 focus:ring-blue-500">
|
|
<label for="area_semi_outdoor" class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">Semi Outdoor</label>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<input type="checkbox" name="area[]" id="area_outdoor" value="Outdoor" {{ is_array(old('area')) && in_array('Outdoor', old('area')) ? 'checked' : '' }} class="w-5 h-5 text-blue-600 dark:text-blue-500 rounded border-gray-300 focus:ring-blue-500">
|
|
<label for="area_outdoor" class="ml-2 text-sm font-medium text-gray-700 dark:text-gray-300">Outdoor</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="field-spacer">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">PILIH LOKASI DI PETA</label>
|
|
<div id="map"></div>
|
|
<p class="text-sm text-gray-500 mt-1">Klik pada peta untuk memilih lokasi cafe. Marker akan muncul dan koordinat akan diisi otomatis.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Kolom Kanan: Semua field lainnya -->
|
|
<div class="space-y-6">
|
|
<div class="field-spacer">
|
|
<label for="koordinat" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">KOORDINAT (LATITUDE, LONGITUDE)</label>
|
|
<input type="text" name="koordinat" id="koordinat" value="{{ old('koordinat') }}" placeholder="Contoh: -8.160591, 113.721279" style="min-height: 48px; padding-top: 12px; padding-bottom: 12px; padding-left: 8px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50">
|
|
|
|
<!-- Hidden fields for latitude and longitude -->
|
|
<input type="hidden" name="latitude" id="latitude" value="{{ old('latitude') }}">
|
|
<input type="hidden" name="longitude" id="longitude" value="{{ old('longitude') }}">
|
|
</div>
|
|
|
|
<div class="field-spacer">
|
|
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">RENTANG HARGA</label>
|
|
<div class="grid grid-cols-2 gap-4">
|
|
<div>
|
|
<label for="harga_termurah" class="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">Harga Termurah (Rp)</label>
|
|
<input type="text" name="harga_termurah_display" id="harga_termurah_display" value="{{ old('harga_termurah') ? number_format(old('harga_termurah'), 0, ',', '.') : '' }}" placeholder="0" style="min-height: 48px; padding-top: 12px; padding-bottom: 12px; padding-left: 8px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50">
|
|
<input type="hidden" name="harga_termurah" id="harga_termurah" value="{{ old('harga_termurah') }}">
|
|
</div>
|
|
<div>
|
|
<label for="harga_termahal" class="block text-xs font-medium text-gray-600 dark:text-gray-400 mb-1">Harga Termahal (Rp)</label>
|
|
<input type="text" name="harga_termahal_display" id="harga_termahal_display" value="{{ old('harga_termahal') ? number_format(old('harga_termahal'), 0, ',', '.') : '' }}" placeholder="0" style="min-height: 48px; padding-top: 12px; padding-bottom: 12px; padding-left: 8px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50">
|
|
<input type="hidden" name="harga_termahal" id="harga_termahal" value="{{ old('harga_termahal') }}">
|
|
</div>
|
|
</div>
|
|
<div id="harga-error" class="text-red-500 text-sm mt-1" style="display: none;"></div>
|
|
<p class="text-sm text-gray-500 mt-1">Masukkan rentang harga menu di cafe ini (opsional)</p>
|
|
</div>
|
|
|
|
@foreach($categories as $category)
|
|
<div class="field-spacer">
|
|
<label for="category_{{ $category->id }}" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">{{ strtoupper($category->name) }}</label>
|
|
<select name="category_ratings[{{ $category->id }}]" id="category_{{ $category->id }}" style="min-height: 48px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50 subcategory-select" data-category-id="{{ $category->id }}" required>
|
|
<option value="">Pilih {{ $category->name }}</option>
|
|
@foreach($category->subcategories as $subcategory)
|
|
<option value="{{ $subcategory->id }}" {{ old('category_ratings.'.$category->id) == $subcategory->id ? 'selected' : '' }}>{{ $subcategory->name }}</option>
|
|
@endforeach
|
|
</select>
|
|
</div>
|
|
@endforeach
|
|
|
|
<div class="field-spacer">
|
|
<label for="gambar" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">GAMBAR CAFE (OPSIONAL)</label>
|
|
<input type="file" name="gambar[]" id="gambar" multiple style="min-height: 48px; padding-top: 12px; padding-bottom: 12px; padding-left: 8px;" class="w-full py-3 pl-4 rounded-md border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-500 focus:ring-opacity-50">
|
|
<p class="text-sm text-gray-500 mt-1">Anda dapat memilih lebih dari satu gambar. Format yang didukung: JPG, JPEG, PNG. Maksimal ukuran per file: 2MB</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="flex justify-end">
|
|
<button type="submit" class="px-6 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 cursor-pointer">
|
|
Simpan
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Crop Modal -->
|
|
<div id="cropModal" class="crop-modal">
|
|
<div class="crop-modal-content">
|
|
<div class="crop-img-container">
|
|
<img id="cropImage" src="" alt="Crop Image">
|
|
</div>
|
|
<div class="crop-controls">
|
|
<button id="cropCancel" class="px-4 py-2 bg-gray-400 text-white rounded">Batal</button>
|
|
<button id="cropConfirm" class="px-4 py-2 bg-blue-600 text-white rounded">Crop & Simpan</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@endsection
|
|
|
|
@push('scripts')
|
|
<!-- Map scripts -->
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Tunggu sebentar untuk memastikan semua elemen sudah dimuat
|
|
setTimeout(function() {
|
|
const mapContainer = document.getElementById('map');
|
|
if (!mapContainer) {
|
|
console.error('Map container not found');
|
|
return;
|
|
}
|
|
|
|
try {
|
|
// Pastikan Leaflet sudah dimuat
|
|
if (typeof L === 'undefined') {
|
|
console.error('Leaflet library not loaded');
|
|
return;
|
|
}
|
|
|
|
console.log('Creating map instance...');
|
|
const map = L.map('map', {
|
|
center: [-8.159765315131203, 113.72309609838182], // Pusat di Jember sebagai default
|
|
zoom: 13,
|
|
zoomControl: true,
|
|
attributionControl: true,
|
|
preferCanvas: true
|
|
});
|
|
|
|
console.log('Adding tile layer...');
|
|
const tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 18,
|
|
minZoom: 10.5,
|
|
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
|
|
});
|
|
|
|
tileLayer.addTo(map);
|
|
|
|
let marker;
|
|
|
|
// Event untuk menambahkan marker saat peta diklik
|
|
map.on('click', function(e) {
|
|
if (marker) {
|
|
map.removeLayer(marker);
|
|
}
|
|
marker = L.marker(e.latlng).addTo(map);
|
|
document.getElementById('latitude').value = e.latlng.lat;
|
|
document.getElementById('longitude').value = e.latlng.lng;
|
|
document.getElementById('koordinat').value = `${e.latlng.lat}, ${e.latlng.lng}`;
|
|
});
|
|
|
|
// Trigger resize untuk memastikan peta ditampilkan dengan benar
|
|
setTimeout(function() {
|
|
map.invalidateSize();
|
|
console.log('Map size invalidated');
|
|
}, 100);
|
|
|
|
console.log('Map initialized successfully');
|
|
} catch (error) {
|
|
console.error('Error initializing map:', error);
|
|
}
|
|
}, 1000);
|
|
});
|
|
</script>
|
|
|
|
<!-- Cropper Interactive -->
|
|
<script src="https://cdn.jsdelivr.net/npm/cropperjs@1.5.13/dist/cropper.min.js"></script>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Variables
|
|
var input = document.getElementById('gambar');
|
|
var cropModal = document.getElementById('cropModal');
|
|
var cropImage = document.getElementById('cropImage');
|
|
var cropCancel = document.getElementById('cropCancel');
|
|
var cropConfirm = document.getElementById('cropConfirm');
|
|
var previewContainer = document.createElement('div');
|
|
previewContainer.className = 'preview-container';
|
|
input.parentNode.appendChild(previewContainer);
|
|
|
|
var files = []; // Store files here
|
|
var currentIndex = 0;
|
|
var cropper = null;
|
|
|
|
// Create an empty Data Transfer object for storing cropped files
|
|
var dt = new DataTransfer();
|
|
|
|
// Show crop modal for current file
|
|
function showCropModal(file) {
|
|
var reader = new FileReader();
|
|
reader.onload = function(e) {
|
|
// Display image in modal
|
|
cropImage.src = e.target.result;
|
|
cropModal.style.display = 'block';
|
|
|
|
// Initialize cropper after image is loaded
|
|
cropImage.onload = function() {
|
|
if (cropper) {
|
|
cropper.destroy();
|
|
}
|
|
|
|
// Create new cropper instance with interactive controls
|
|
cropper = new Cropper(cropImage, {
|
|
aspectRatio: 1, // 1:1 square crop
|
|
viewMode: 1, // restrict crop box to not exceed the size of the canvas
|
|
dragMode: 'move', // Allow moving the image
|
|
guides: true, // Show grid lines
|
|
center: true, // Show center indicator
|
|
background: false, // Don't show grey background
|
|
autoCropArea: 0.8, // Define default crop area size (80% of the image)
|
|
cropBoxMovable: true,
|
|
cropBoxResizable: true,
|
|
toggleDragModeOnDblclick: true
|
|
});
|
|
};
|
|
};
|
|
reader.readAsDataURL(file);
|
|
}
|
|
|
|
// Process the current file
|
|
function processCurrentFile() {
|
|
if (currentIndex < files.length) {
|
|
showCropModal(files[currentIndex]);
|
|
} else {
|
|
// All files processed, update the input
|
|
input.files = dt.files;
|
|
}
|
|
}
|
|
|
|
// File selection handler
|
|
input.addEventListener('change', function(e) {
|
|
// Clear previous state
|
|
while(previewContainer.firstChild) {
|
|
previewContainer.removeChild(previewContainer.firstChild);
|
|
}
|
|
|
|
if (this.files.length === 0) return;
|
|
|
|
// Reset variables
|
|
files = Array.from(this.files);
|
|
currentIndex = 0;
|
|
dt = new DataTransfer();
|
|
|
|
// Start processing the first file
|
|
processCurrentFile();
|
|
});
|
|
|
|
// Cancel button handler
|
|
cropCancel.addEventListener('click', function() {
|
|
cropModal.style.display = 'none';
|
|
if (cropper) {
|
|
cropper.destroy();
|
|
cropper = null;
|
|
}
|
|
input.value = '';
|
|
files = [];
|
|
currentIndex = 0;
|
|
dt = new DataTransfer();
|
|
while(previewContainer.firstChild) {
|
|
previewContainer.removeChild(previewContainer.firstChild);
|
|
}
|
|
});
|
|
|
|
// Confirm button handler
|
|
cropConfirm.addEventListener('click', function() {
|
|
if (!cropper) return;
|
|
|
|
// Get cropped canvas
|
|
cropper.getCroppedCanvas({
|
|
width: 600, // output size
|
|
height: 600,
|
|
imageSmoothingEnabled: true,
|
|
imageSmoothingQuality: 'high'
|
|
}).toBlob(function(blob) {
|
|
// Create a new file from the blob
|
|
var croppedFile = new File([blob], files[currentIndex].name, {
|
|
type: 'image/jpeg',
|
|
lastModified: new Date().getTime()
|
|
});
|
|
|
|
// Add to data transfer object
|
|
dt.items.add(croppedFile);
|
|
|
|
// Create preview container with delete button
|
|
var previewItem = document.createElement('div');
|
|
previewItem.className = 'relative group sortable-item';
|
|
previewItem.style.display = 'inline-block';
|
|
|
|
// Create preview image
|
|
var preview = document.createElement('img');
|
|
preview.src = URL.createObjectURL(blob);
|
|
preview.className = 'preview-image';
|
|
|
|
// Create delete button
|
|
var deleteBtn = document.createElement('button');
|
|
deleteBtn.className = 'delete-btn';
|
|
deleteBtn.title = 'Hapus gambar';
|
|
deleteBtn.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 16 16"><path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5zm3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0V6z"/><path fill-rule="evenodd" d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1v1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4H4.118zM2.5 3V2h11v1h-11z"/></svg>';
|
|
|
|
// Add click event to delete button
|
|
deleteBtn.addEventListener('click', function() {
|
|
const index = Array.from(previewContainer.children).indexOf(previewItem);
|
|
if (index !== -1) {
|
|
// Create new DataTransfer to rebuild file list without this item
|
|
const newDt = new DataTransfer();
|
|
for (let i = 0; i < dt.files.length; i++) {
|
|
if (i !== index) {
|
|
newDt.items.add(dt.files[i]);
|
|
}
|
|
}
|
|
dt = newDt;
|
|
input.files = dt.files;
|
|
|
|
// Remove visual preview
|
|
previewItem.remove();
|
|
}
|
|
});
|
|
|
|
// Append elements to preview item
|
|
previewItem.appendChild(preview);
|
|
previewItem.appendChild(deleteBtn);
|
|
|
|
// Add to preview container
|
|
previewContainer.appendChild(previewItem);
|
|
|
|
// Hide modal and cleanup
|
|
cropModal.style.display = 'none';
|
|
if (cropper) {
|
|
cropper.destroy();
|
|
cropper = null;
|
|
}
|
|
|
|
// Move to next file
|
|
currentIndex++;
|
|
processCurrentFile();
|
|
}, 'image/jpeg', 0.95);
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<!-- Price formatting and validation script -->
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const hargaTermurahDisplay = document.getElementById('harga_termurah_display');
|
|
const hargaTermahalDisplay = document.getElementById('harga_termahal_display');
|
|
const hargaTermurah = document.getElementById('harga_termurah');
|
|
const hargaTermahal = document.getElementById('harga_termahal');
|
|
const hargaError = document.getElementById('harga-error');
|
|
const form = document.querySelector('form');
|
|
|
|
// Format number with thousands separator
|
|
function formatNumber(num) {
|
|
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".");
|
|
}
|
|
|
|
// Remove thousands separator and get numeric value
|
|
function unformatNumber(str) {
|
|
return parseInt(str.replace(/\./g, '')) || 0;
|
|
}
|
|
|
|
// Format input on keyup
|
|
function handleNumberInput(displayInput, hiddenInput) {
|
|
displayInput.addEventListener('input', function() {
|
|
let value = this.value.replace(/[^\d]/g, ''); // Only allow digits
|
|
if (value) {
|
|
this.value = formatNumber(value);
|
|
hiddenInput.value = value;
|
|
} else {
|
|
this.value = '';
|
|
hiddenInput.value = '';
|
|
}
|
|
validatePrices();
|
|
});
|
|
}
|
|
|
|
// Validate that harga_termahal >= harga_termurah
|
|
function validatePrices() {
|
|
const termurah = unformatNumber(hargaTermurahDisplay.value);
|
|
const termahal = unformatNumber(hargaTermahalDisplay.value);
|
|
|
|
if (termurah > 0 && termahal > 0 && termahal < termurah) {
|
|
hargaError.textContent = 'Harga termahal harus lebih besar atau sama dengan harga termurah';
|
|
hargaError.style.display = 'block';
|
|
hargaTermahalDisplay.classList.add('border-red-500');
|
|
hargaTermurahDisplay.classList.add('border-red-500');
|
|
return false;
|
|
} else {
|
|
hargaError.style.display = 'none';
|
|
hargaTermahalDisplay.classList.remove('border-red-500');
|
|
hargaTermurahDisplay.classList.remove('border-red-500');
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Initialize formatting
|
|
handleNumberInput(hargaTermurahDisplay, hargaTermurah);
|
|
handleNumberInput(hargaTermahalDisplay, hargaTermahal);
|
|
|
|
// Prevent form submission if validation fails
|
|
form.addEventListener('submit', function(e) {
|
|
if (!validatePrices()) {
|
|
e.preventDefault();
|
|
hargaError.scrollIntoView({ behavior: 'smooth' });
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
@endpush |