Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/laciasmara.com/public_html/shop/application/views/development/ |
Upload File : |
<html> <head> <title>Place Autocomplete map</title> <style> .address-management { max-width: 800px; margin: 0 auto; } .saved-addresses { margin-bottom: 20px; } .address-item { margin-bottom: 15px; } .address-card { border: 1px solid #ddd; border-radius: 8px; padding: 15px; background: #f9f9f9; } .address-card.default { border-color: #007bff; background: #e7f3ff; } .address-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; } .default-badge { background: #007bff; color: white; padding: 2px 8px; border-radius: 4px; font-size: 12px; } .address-actions { margin-top: 10px; } .address-actions button { margin-right: 10px; padding: 5px 10px; border: none; border-radius: 4px; cursor: pointer; } .modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); z-index: 1000; } .modal-content { background: white; margin: 2% auto; padding: 20px; border-radius: 8px; max-width: 90%; max-height: 90%; overflow-y: auto; } .modal-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; border-bottom: 1px solid #ddd; padding-bottom: 10px; } .close { font-size: 24px; cursor: pointer; color: #666; } .form-group { margin-bottom: 15px; } .form-group label { display: block; margin-bottom: 5px; font-weight: bold; } .form-group input, .form-group textarea { width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; box-sizing: border-box; } .row { display: flex; gap: 15px; } .col-md-6 { flex: 1; } .form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; } .form-actions button { padding: 10px 20px; border: none; border-radius: 4px; cursor: pointer; } .form-actions button[type="submit"] { background: #007bff; color: white; } #map { border: 1px solid #ddd; border-radius: 4px; } /* Responsive */ @media (max-width: 768px) { .row { flex-direction: column; } .modal-content { margin: 5% auto; padding: 15px; } } </style> </head> <body> <div class="address-management"> <!-- Existing Addresses --> <div class="saved-addresses"> <h4>Alamat Tersimpan</h4> <div id="address-list"> <!-- Akan diisi dengan JavaScript --> </div> <button type="button" class="btn btn-primary" onclick="showAddressForm()"> + Tambah Alamat Baru </button> </div> <!-- Add New Address Modal --> <div id="address-modal" class="modal" style="display: none;"> <div class="modal-content"> <div class="modal-header"> <h3>Tambah Alamat Baru</h3> <span class="close" onclick="hideAddressForm()">×</span> </div> <div class="modal-body"> <form id="address-form"> <div class="form-group"> <label>Label Alamat</label> <input type="text" id="address-label" name="label" placeholder="Rumah, Kantor, dll" required> </div> <div class="form-group"> <label>Nama Penerima</label> <input type="text" id="recipient-name" name="recipient_name" required> </div> <div class="form-group"> <label>Nomor Telepon</label> <input type="tel" id="recipient-phone" name="phone" required> </div> <div class="form-group"> <label>Cari Alamat</label> <input type="text" id="address-search" placeholder="Cari alamat..." class="form-control"> </div> <!-- Map Container --> <div id="map" style="height: 400px; width: 100%; margin: 10px 0;"></div> <!-- Address Details (Auto-filled) --> <div class="address-details"> <div class="form-group"> <label>Alamat Lengkap</label> <textarea id="full-address" name="address" rows="3" required></textarea> </div> <div class="row"> <div class="col-md-6"> <label>Provinsi</label> <input type="text" id="province" name="province" readonly> </div> <div class="col-md-6"> <label>Kota</label> <input type="text" id="city" name="city" readonly> </div> </div> <div class="row"> <div class="col-md-6"> <label>Kecamatan</label> <input type="text" id="district" name="district" readonly> </div> <div class="col-md-6"> <label>Kelurahan</label> <input type="text" id="subdistrict" name="subdistrict" readonly> </div> </div> <div class="row"> <div class="col-md-6"> <label>Kode Pos</label> <input type="text" id="postal-code" name="postal_code" readonly> </div> <div class="col-md-6"> <label> <input type="checkbox" id="is-default" name="is_default"> Jadikan alamat utama </label> </div> </div> </div> <!-- Hidden fields untuk coordinates --> <input type="hidden" id="latitude" name="latitude"> <input type="hidden" id="longitude" name="longitude"> <div class="form-actions"> <button type="button" onclick="hideAddressForm()">Batal</button> <button type="submit">Simpan Alamat</button> </div> </form> </div> </div> </div> </div> <script async src="https://maps.googleapis.com/maps/api/js?key=<?php echo $this->config->item('google_maps_api_key'); ?>&loading=async&libraries=places,marker&callback=initMap&language=id®ion=ID&v=beta" defer></script> <script> let map; let marker; let autocomplete; let geocoder; // Initialize Map async function initMap() { try { // Request needed libraries const { Map } = await google.maps.importLibrary("maps"); const { AdvancedMarkerElement } = await google.maps.importLibrary("marker"); // Default location (Jakarta) const defaultLocation = { lat: -6.2088, lng: 106.8456 }; // Create map map = new Map(document.getElementById('map'), { center: defaultLocation, zoom: 13, mapId: '1873c42fd77c25f9fad736e6', mapTypeControl: false, streetViewControl: false, fullscreenControl: false }); // Create marker marker = new AdvancedMarkerElement({ map: map, position: defaultLocation, gmpDraggable: true, title: 'Drag untuk memilih lokasi' }); // Initialize geocoder geocoder = new google.maps.Geocoder(); // Setup autocomplete - Wait for DOM to be ready setupAutocomplete(); // Setup event listeners setupEventListeners(); // Try to get user's current location getCurrentLocation(); } catch (error) { console.error('Error initializing map:', error); // Fallback to old API if new one fails initMapFallback(); } } // Fallback to old API function initMapFallback() { console.log('Using fallback map initialization'); // Default location (Jakarta) const defaultLocation = { lat: -6.2088, lng: 106.8456 }; // Create map with old API map = new google.maps.Map(document.getElementById('map'), { center: defaultLocation, zoom: 13, mapTypeControl: false, streetViewControl: false, fullscreenControl: false }); // Create marker with old API marker = new google.maps.Marker({ position: defaultLocation, map: map, draggable: true, title: 'Drag untuk memilih lokasi' }); // Initialize geocoder geocoder = new google.maps.Geocoder(); // Setup autocomplete setupAutocomplete(); // Setup event listeners setupEventListeners(); // Try to get user's current location getCurrentLocation(); } // Setup Autocomplete - Use regular input with traditional Autocomplete as fallback function setupAutocomplete() { // Try to use the new PlaceAutocompleteElement first const autocompleteElement = document.getElementById('address-search'); if (!autocompleteElement) { console.error('Autocomplete element not found'); return; } // setupNewAutocomplete(autocompleteElement); setupTraditionalAutocomplete(autocompleteElement); } function setupNewAutocomplete(autocompleteElement) { try { // Create PlaceAutocompleteElement const placeAutocomplete = new google.maps.places.PlaceAutocompleteElement({ includedRegionCodes: ['ID'] }); // Replace the input element with PlaceAutocompleteElement autocompleteElement.parentNode.replaceChild(placeAutocomplete, autocompleteElement); // Set the same ID and classes for styling placeAutocomplete.id = 'address-search'; placeAutocomplete.className = 'form-control'; placeAutocomplete.placeholder = 'Cari alamat...'; // Use addEventListener instead of addListener for web components placeAutocomplete.addEventListener('place_changed', function() { const place = placeAutocomplete.getPlace(); console.log('Selected place:', place); if (!place.geometry) { alert('Alamat tidak ditemukan'); return; } // Update map and marker map.setCenter(place.geometry.location); map.setZoom(17); // Set marker position based on marker type if (marker.position !== undefined) { // AdvancedMarkerElement marker.position = place.geometry.location; } else { // Traditional Marker marker.setPosition(place.geometry.location); } // Fill address details fillAddressDetails(place); }); // Store reference for later use autocomplete = placeAutocomplete; } catch (error) { console.error('Error setting up new autocomplete:', error); setupTraditionalAutocomplete(autocompleteElement); } } function setupTraditionalAutocomplete(searchInput) { // Auto complete diisi dengan google.maps.places.Autocomplete autocomplete = new google.maps.places.Autocomplete(searchInput, { componentRestrictions: { country: 'ID' }, fields: ['formatted_address', 'geometry', 'address_components', 'name'], }); autocomplete.addListener('place_changed', function() { const place = autocomplete.getPlace(); console.log('Selected place:', place); if (!place.geometry) { alert('Alamat tidak ditemukan'); return; } // Update map and marker map.setCenter(place.geometry.location); map.setZoom(17); // Set marker position based on marker type if (marker.position !== undefined) { // AdvancedMarkerElement marker.position = place.geometry.location; } else { // Traditional Marker marker.setPosition(place.geometry.location); } // Fill address details fillAddressDetails(place); }); } // Setup Event Listeners function setupEventListeners() { // Marker drag event marker.addListener('dragend', function() { let position; if (marker.position && marker.position.lat) { // AdvancedMarkerElement position = marker.position; } else { // Traditional Marker position = marker.getPosition(); } reverseGeocode(position); }); // Map click event map.addListener('click', function(event) { if (marker.position !== undefined) { // AdvancedMarkerElement marker.position = event.latLng; } else { // Traditional Marker marker.setPosition(event.latLng); } reverseGeocode(event.latLng); }); // Form submit event if (document.getElementById('address-form')) { document.getElementById('address-form').addEventListener('submit', function(e) { e.preventDefault(); saveAddress(); }); } } // Get Current Location function getCurrentLocation() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( function(position) { const userLocation = { lat: position.coords.latitude, lng: position.coords.longitude }; map.setCenter(userLocation); if (marker.position !== undefined) { // AdvancedMarkerElement marker.position = userLocation; } else { // Traditional Marker marker.setPosition(userLocation); } reverseGeocode(userLocation); }, function(error) { console.log('Error getting location:', error); } ); } } // Reverse Geocoding function reverseGeocode(location) { geocoder.geocode({ location: location }, function(results, status) { if (status === 'OK') { if (results[0]) { fillAddressFromGeocoding(results[0]); } } else { console.log('Geocoder failed:', status); } }); } // Fill Address Details from Places API function fillAddressDetails(place) { if (document.getElementById('full-address')) { document.getElementById('full-address').value = place.formatted_address; } if (document.getElementById('latitude')) { document.getElementById('latitude').value = place.geometry.location.lat(); } if (document.getElementById('longitude')) { document.getElementById('longitude').value = place.geometry.location.lng(); } // Parse address components const components = place.address_components; let addressData = { province: '', city: '', district: '', subdistrict: '', postal_code: '' }; if (components) { components.forEach(function(component) { const types = component.types; if (types.includes('administrative_area_level_1')) { addressData.province = component.long_name; } else if (types.includes('administrative_area_level_2')) { addressData.city = component.long_name; } else if (types.includes('administrative_area_level_3')) { addressData.district = component.long_name; } else if (types.includes('administrative_area_level_4')) { addressData.subdistrict = component.long_name; } else if (types.includes('postal_code')) { addressData.postal_code = component.long_name; } }); } // Fill form fields if (document.getElementById('province')) { document.getElementById('province').value = addressData.province; } if (document.getElementById('city')) { document.getElementById('city').value = addressData.city; } if (document.getElementById('district')) { document.getElementById('district').value = addressData.district; } if (document.getElementById('subdistrict')) { document.getElementById('subdistrict').value = addressData.subdistrict; } if (document.getElementById('postal-code')) { document.getElementById('postal-code').value = addressData.postal_code; } } // Fill Address from Geocoding (when marker is dragged) function fillAddressFromGeocoding(result) { if (document.getElementById('full-address')) { document.getElementById('full-address').value = result.formatted_address; } if (document.getElementById('latitude')) { document.getElementById('latitude').value = result.geometry.location.lat(); } if (document.getElementById('longitude')) { document.getElementById('longitude').value = result.geometry.location.lng(); } // Parse similar to fillAddressDetails const components = result.address_components; let addressData = { province: '', city: '', district: '', subdistrict: '', postal_code: '' }; components.forEach(function(component) { const types = component.types; if (types.includes('administrative_area_level_1')) { addressData.province = component.long_name; } else if (types.includes('administrative_area_level_2')) { addressData.city = component.long_name; } else if (types.includes('administrative_area_level_3')) { addressData.district = component.long_name; } else if (types.includes('administrative_area_level_4')) { addressData.subdistrict = component.long_name; } else if (types.includes('postal_code')) { addressData.postal_code = component.long_name; } }); if (document.getElementById('province')) { document.getElementById('province').value = addressData.province; } if (document.getElementById('city')) { document.getElementById('city').value = addressData.city; } if (document.getElementById('district')) { document.getElementById('district').value = addressData.district; } if (document.getElementById('subdistrict')) { document.getElementById('subdistrict').value = addressData.subdistrict; } if (document.getElementById('postal-code')) { document.getElementById('postal-code').value = addressData.postal_code; } } // Save Address function saveAddress() { const formData = new FormData(document.getElementById('address-form')); fetch('<?php echo base_url('development/save_address'); ?>', { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { if (data.success) { alert('Alamat berhasil disimpan!'); hideAddressForm(); loadSavedAddresses(); document.getElementById('address-form').reset(); } else { alert('Gagal menyimpan alamat. Silakan coba lagi.'); } }) .catch(error => { console.error('Error:', error); alert('Terjadi kesalahan. Silakan coba lagi.'); }); } // Show/Hide Address Form function showAddressForm() { if (document.getElementById('address-modal')) { document.getElementById('address-modal').style.display = 'block'; // Resize map when modal is shown setTimeout(() => { google.maps.event.trigger(map, 'resize'); }, 100); } } function hideAddressForm() { if (document.getElementById('address-modal')) { document.getElementById('address-modal').style.display = 'none'; } } // Load Saved Addresses function loadSavedAddresses() { fetch('<?php echo base_url('development/get_addresses'); ?>') .then(response => response.json()) .then(data => { const addressList = document.getElementById('address-list'); if (addressList) { addressList.innerHTML = ''; data.addresses.forEach(address => { const addressItem = createAddressItem(address); addressList.appendChild(addressItem); }); } }) .catch(error => { console.error('Error loading addresses:', error); }); } // Create Address Item HTML function createAddressItem(address) { const div = document.createElement('div'); div.className = 'address-item'; div.innerHTML = ` <div class="address-card ${address.is_default ? 'default' : ''}"> <div class="address-header"> <strong>${address.label}</strong> ${address.is_default ? '<span class="default-badge">Utama</span>' : ''} </div> <div class="address-details"> <p><strong>${address.recipient_name}</strong> | ${address.phone}</p> <p>${address.address}</p> <p>${address.district}, ${address.city}, ${address.province} ${address.postal_code}</p> </div> <div class="address-actions"> <button onclick="selectAddress(${address.id})">Pilih</button> <button onclick="editAddress(${address.id})">Edit</button> <button onclick="deleteAddress(${address.id})">Hapus</button> </div> </div> `; return div; } // Select Address for Shipping function selectAddress(addressId) { // Implementation depends on your checkout flow console.log('Selected address:', addressId); // You might want to store this in a hidden field or session } // Load addresses when page loads document.addEventListener('DOMContentLoaded', function() { if (typeof loadSavedAddresses === 'function') { loadSavedAddresses(); } }); </script> </body> </html>