app/javascript/controllers/photo_wizard_controller.js
import { Controller } from 'stimulus'
export default class extends Controller {
connect() {
this.addStepNumbers()
window.scrollTo(0, 0)
$('button.btn-prev').on('click', (e) => {
this.prev(e.target)
})
$('button.btn-next').on('click', (e) => {
this.next(e.target)
})
$('#photograph_file').on('change', function () {
if (this.files.length) {
const reader = new FileReader()
reader.onload = function (e) {
const file = e.target.result
$('#selected-file, .thumb').html('<img class="img img-thumbnail" alt="" />')
$('#selected-file img, .thumb img').attr('src', file)
$('.step-1-next-button').removeAttr('disabled')
}
reader.readAsDataURL(this.files[0])
}
})
this.initBuildings()
this.initPeople()
this.initDates()
this.initMap()
}
initDates() {
$('#dates-question button').on('click', (e) => {
const type = e.target.dataset.dateType
$('#dates-question button.btn-primary').removeClass('btn-primary').addClass('btn-light')
$(e.target).addClass('btn-primary').removeClass('btn-light')
$('#photograph_date_type').val(type)
document.getElementById('photograph-date-type').className = type
$('select:visible').chosen({
disable_search_threshold: 15
})
})
}
initPeople() {
$('#person-question .btn-primary').on('click', function () {
$('#person-question').fadeOut()
$('#person-fields').fadeIn()
})
$('#person-autocomplete').on('keyup', (e) => {
if (e.keyCode === 13) {
e.stopPropagation()
}
const input = e.target
const value = input.value
if (value.length > 1) {
$.getJSON('/people/autocomplete', { term: value }, (json) => {
const people = []
json.forEach((person) => {
people.push(`<div class="list-group-item list-group-item-action" data-person=${person.id}>${person.name}</div>`)
})
$('#person-results').html(people).show()
$('#person-results .list-group-item').on('click', (e) => {
const id = e.target.dataset.person
const name = e.target.innerHTML
this.addPerson(id, name)
input.value = null
$('#person-results').html('')
})
})
}
})
}
initBuildings() {
$('#building-question .btn-primary').on('click', function () {
$('#building-question').fadeOut()
$('#building-fields').fadeIn()
})
$('#building-autocomplete').on('keyup', (e) => {
if (e.keyCode === 13) {
e.stopPropagation()
}
const input = e.target
const value = input.value
if (value.length > 1) {
$.getJSON('/buildings/autocomplete', { term: value }, (json) => {
const buildings = []
json.forEach((building) => {
buildings.push(`<div class="list-group-item list-group-item-action" data-building=${building.id} data-lat="${building.lat}" data-lon="${building.lon}">${building.address}</div>`)
})
$('#building-results').html(buildings).show()
$('#building-results .list-group-item').on('click', (e) => {
const id = e.target.dataset.building
const lat = e.target.dataset.lat
const lon = e.target.dataset.lon
const address = e.target.innerHTML
this.addBuilding(id, address, lat, lon)
input.value = null
$('#building-results').html('')
})
})
}
})
}
addBuilding(id, address, lat, lon) {
const formId = `photograph_building_ids_${id}`
$(`#${formId}`).closest('.form-check').remove()
const html = `<div class="form-check"><input type="checkbox" class="form-check-input" name="photograph[building_ids][]" id="${formId}" value="${id}" checked /><label class="form-check-label" for="${formId}">${address}</label></div>`
$('.photograph_building_ids').append(html)
if ($('.photograph_building_ids input:checked').length === 1) {
$('#photograph_latitude').val(lat)
$('#photograph_longitude').val(lon).trigger('change')
}
}
addPerson(id, name) {
const formId = `photograph_person_ids_${id}`
$(`#${formId}`).closest('.form-check').remove()
const html = `<div class="form-check"><input type="checkbox" class="form-check-input" name="photograph[person_ids][]" id="${formId}" value="${id}" checked /><label class="form-check-label" for="${formId}">${name}</label></div>`
$('.photograph_person_ids').append(html)
}
addStepNumbers() {
const steps = $('#photo-wizard .card')
const numSteps = steps.length
let i = 0
steps.each(function () {
$(this).find('.card-body').prepend(`<h3 class="card-title">Step ${++i} of ${numSteps}</h3>`)
})
}
initCard(card) {
window.scrollTo(0, 0)
if (card.find('#map').length && !this.mapInitialized) {
this.initMap()
}
card.find('select:visible').chosen({
disable_search_threshold: 15
})
}
prev(el) {
this.initCard($(el).closest('.card').deactivateCard().prev().activateCard())
}
next(el) {
this.initCard($(el).closest('.card').deactivateCard().next().activateCard())
}
initMap() {
if (typeof google === 'undefined') {
setTimeout(
() => this.initMap(),
1000
)
return
}
this.mapInitialized = true
const startLat = document.getElementById('photograph_latitude').value
const startLon = document.getElementById('photograph_longitude').value
const loc = (startLat && startLon) ? [parseFloat(startLat), parseFloat(startLon)] : JSON.parse(document.getElementById('photograph-map').dataset.center)
const map = new google.maps.Map(document.getElementById('photograph-map'), {
center: { lat: loc[0], lng: loc[1] },
zoom: 13
})
const marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29),
draggable: true
})
marker.setPosition(map.getCenter())
marker.setVisible(true)
const input = document.getElementById('pac-input')
const autocomplete = new google.maps.places.Autocomplete(input)
autocomplete.bindTo('bounds', map)
autocomplete.setFields(['address_components', 'geometry', 'icon', 'name'])
autocomplete.addListener('place_changed', () => {
this.handlePlaceAutocompletion(marker, autocomplete, map)
})
marker.addListener('dragend', function () {
const position = marker.getPosition()
document.getElementById('photograph_latitude').value = position.lat()
document.getElementById('photograph_longitude').value = position.lng()
})
$('#photograph_longitude').on('change', function() {
const lat = document.getElementById('photograph_latitude').value
const lon = document.getElementById('photograph_longitude').value
const loc = new google.maps.LatLng(parseFloat(lat), parseFloat(lon))
marker.setPosition(loc)
map.setCenter(loc)
})
}
handlePlaceAutocompletion(marker, autocomplete, map) {
marker.setVisible(false)
const place = autocomplete.getPlace()
if (!place.geometry) {
window.alert("No details available for input: '" + place.name + "'")
return
}
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport)
} else {
map.setCenter(place.geometry.location)
map.setZoom(17)
}
marker.setPosition(place.geometry.location)
document.getElementById('photograph_latitude').value = place.geometry.location.lat()
document.getElementById('photograph_longitude').value = place.geometry.location.lng()
}
}
$.fn.activateCard = function () {
return this.each(function () {
$(this).addClass('active')
return this
})
}
$.fn.deactivateCard = function () {
return this.each(function () {
$(this).removeClass('active')
return this
})
}