avo-hq / avo

Build Ruby on Rails apps 10x faster
https://avohq.io
Other
1.51k stars 239 forks source link

Mapbox address field #3233

Open adrianthedev opened 4 weeks ago

adrianthedev commented 4 weeks ago

Mapbox Field

These snippets below are what I had after a workshop I held at Visuality last year. They won't deliver the finisehd result, but it's a great starting point. This will give you a custom field that you can add to your app and will search mapbox.

Approach

The user will start to type some text in the input and when they select an option from the dropdown they will get a payload at their disposal from mapbox.

# Let's imagine that mapbox returns this payload for the query
# *I don't have the response in front of me
{
  full_address: "55 George Washington st., New York, USA",
  street_address: "55 George Washington st.",
  street_number: "55",
  city: "New York",
  state: "NY",
  country: "USA",
}

API

# when the form gets submitted it will populate the `address` column with the full address received from mapbox and all the parsed fields onto the record.

# Nothing happens when the form gets submitted
field :address, as: :mapbox_address

# All the fields from the response are passed to the record
field :address, as: :mapbox_address, map: :all

# only the fields in `map` are being passed to the record
field :address, as: :mapbox_address, map: [:full_address, :street]

# the fields from `map` are passed to the record with the key being overwritten by `custom_mapping`
field :address, as: :mapbox_address, map: [:street_address, :city, :country], custom_mapping: {street_address: :street, city: :town}

# give the user access to the `record` and `respomse` and they can choose what happens
field :address, as: :mapbox_address, populate: -> {
  # maybe we can use `update_using` instead here?
  record.street = response[:street_address]
}

If the record has an address column/property, let's display that in the UI, but let's think about a way to show the input only if the user wants it. We can talk about it.

Snippets

class DynamicAddressField < Avo::Fields::BaseField
  def initialize(name, **args, &block)
    super(name, **args, &block)
  end
end
<!-- edit component html -->
<%= field_wrapper **field_wrapper_args do %>
  <div data-controller="address">
    <%= @form.text_field @field.id,
      class: classes("w-full"),
      placeholder: @field.placeholder,
      autocomplete: "shipping address-line1",
      disabled: disabled? %>
  </div>
<% end %>
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
  static targets = ['element', "addressTextInput"]

  connect() {
    console.log('address_field_controller', this.addressTextInputTarget)
    // console.log(this.elementTarget)
    // this.initField()
  }

  onInput(e) {
    console.log("onInput", e.target.value)
  }

  initField() {
    mapboxsearch.autofill({
      accessToken: "pk.eyJ..."
    });
  }
}
github-actions[bot] commented 1 week ago

This issue has been marked as stale because there was no activity for the past 15 days.