Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

phayes0289's avatar

Using A Blade Component for both creating and editing

I have a custom Blade geocoding component for a create form. It gets used on various models. Is there a way I can use it for the "edit form also? I would need to somehow pass the query values into the component. The name of the query would be dependent on where it is being used.

<div class="panel-container show">
                            <div class="panel-content">
                                <x-geocoder />
                            </div>
                        </div>

This is my geocoder.blade.php component:

                          {{-- Begin FireOps Geocoder --}}
                          <div id="geocoder" name="geocoder">
                              {{-- Begin Geo-Codeing Address Box --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-12">
                                          <div class="mb-2 p-2" style="background:#e7eff7">
                                              <label class="form-label mt-2" for="location">Search For Address
                                                  Info</label>
                                              <input type="text" id="location" name="location" class="form-control"
                                                  value="{{ old('location') }}">
                                              <small class="fs-10px text-gray-500-darker">Enter an address to search
                                                  Googles
                                                  database, then select the correct address to populate all the adress
                                                  fields
                                                  below.</small>
                                          </div>
                                      </div>
                                  </div>
                              </div>
                              {{-- End Geo-Codeing Address Box --}}
                              {{-- Begin Street Number, Street and Unit Number --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-2">
                                          <label class="form-label" for="streetnumber">Number</label>
                                          <input type="text" id="streetnumber" name="streetnumber"
                                              class="form-control @error('streetnumber') is-invalid @enderror"
                                              value="{{ old('streetnumber') }}">
                                          @error('streetnumber')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                      <div class="col-8">
                                          <label class="form-label" for="street">Street</label>
                                          <input type="text" id="street" name="street"
                                              class="form-control @error('street') is-invalid @enderror"
                                              value="{{ old('street') }}">
                                          @error('street')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                      <div class="col-2">
                                          <label class="form-label" for="unit">Unit</label>
                                          <input type="text" id="unit" name="unit"
                                              class="form-control @error('unit') is-invalid @enderror"
                                              value="{{ old('unit') }}">
                                          @error('unit')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                  </div>
                              </div>
                              {{-- End Street Number, Street and Unit Number --}}
                              {{-- Begin Address 2 (Non-geocode field) --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-12">
                                          <label class="form-label" for="street_alt">Street Address 2</label>
                                          <input type="text" id="street_alt" name="street_alt"
                                              class="form-control @error('street_alt') is-invalid @enderror"
                                              value="{{ old('street_alt') }}">
                                          @error('street_alt')
                                              <span class="invalid-feedback" role="alert">
                                                  <strong>{{ $message }}</strong>
                                              </span>
                                          @enderror
                                      </div>
                                  </div>
                              </div>
                              {{-- End Address 2 (Non-geocode field) --}}
                              {{-- Begin City, State and Postalcode --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-6">
                                          <label class="form-label" for="city">City</label>
                                          <input type="text" id="city" name="city"
                                              class="form-control
                                              @error('city') is-invalid @enderror"
                                              value="{{ old('city') }}">
                                          @error('city')
                                              <span class="invalid-feedback" role="alert">
                                                  <strong>{{ $message }}</strong>
                                              </span>
                                          @enderror
                                      </div>
                                      <div class="col-3">
                                          <label class="form-label" for="state">State</label>
                                          <input type="text" id="state" name="state"
                                              class="form-control @error('state') is-invalid @enderror"
                                              value="{{ old('state') }}">
                                          @error('state')
                                              <p class="invalid-feedback">
                                                  {{ $message }}
                                              </p>
                                          @enderror
                                      </div>
                                      <div class="col-3">
                                          <label class="form-label" for="postalcode">Postal Code</label>
                                          <input type="text" id="postalcode" name="postalcode"
                                              class="form-control
                                              @error('prefix') is-invalid @enderror"
                                              value="{{ old('postalcode') }}">
                                          @error('postalcode')
                                              <span class="invalid-feedback" role="alert">
                                                  <strong>{{ $message }}</strong>
                                              </span>
                                          @enderror
                                      </div>
                                  </div>
                              </div>

                              {{-- End City, State and Postalcode --}}
                              {{-- Begin Neighborhood --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-12">
                                          <label class="form-label" for="neighborhood">Neighborhood</label>
                                          <input type="text" id="neighborhood" name="neighborhood"
                                              class="form-control
                                   @error('neighborhood') is-invalid @enderror"
                                              value="{{ old('neighborhood') }}">
                                          @error('neighborhood')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                  </div>
                              </div>
                              {{-- End Neighborhood --}}
                              {{-- Begin County & Country --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-6">
                                          <label class="form-label" for="county">County</label>
                                          <input type="text" id="county" name="county"
                                              class="form-control
                                   @error('county') is-invalid @enderror"
                                              value="{{ old('county') }}">
                                          @error('county')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                      <div class="col-6">
                                          <label class="form-label" for="lat">Country</label>
                                          <input type="text" id="country" name="country"
                                              class="form-control
                                   @error('country') is-invalid @enderror"
                                              value="{{ old('country') }}">
                                          @error('country')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>

                                  </div>
                              </div>
                              {{-- End County & Country --}}
                              {{-- Begin Lat & Lng for Addresss --}}
                              <div class="form-group mb-0">
                                  <div class="row">
                                      <div class="col-6">
                                          <label class="form-label" for="lng">Longitude</label>
                                          <input type="text" id="lng" name="lng"
                                              class="form-control
                                   @error('lng') is-invalid @enderror"
                                              value="{{ old('lng') }}">
                                          @error('lng')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>
                                      <div class="col-6">
                                          <label class="form-label" for="lat">Latitude</label>
                                          <input type="text" id="lat" name="lat"
                                              class="form-control
                                   @error('lat') is-invalid @enderror"
                                              value="{{ old('lat') }}">
                                          @error('lat')
                                              <span class="invalid-feedback">
                                                  {{ $message }}
                                              </span>
                                          @enderror
                                      </div>

                                  </div>
                              </div>
                              {{-- End Lat & Lng for Addresss --}}
                          </div>
                          {{-- End FireOps Geocoder --}}
                          <script>
                              let autocomplete;
                              let addressField = document.getElementById('location');

                              function initAutocomplete() {
                                  autocomplete = new google.maps.places.Autocomplete(
                                      addressField, {
                                          types: ['address'],
                                          componentRestrictions: {
                                              country: ["US"]
                                          },
                                          componentRestrictions: {
                                              state: ["CT"]
                                          },
                                          fields: ['name', 'address_components', 'geometry'],
                                      }
                                  );

                                  autocomplete.addListener('place_changed', onPlaceChanged)

                                  google.maps.event.addDomListener(addressField, 'keydown', event => {
                                      if (event.key === 'Enter') {
                                          event.preventDefault();
                                          document.getElementById('city').focus();
                                      }
                                  })
                              }

                              function onPlaceChanged() {
                                  const place = autocomplete.getPlace()
                                  console.log(place)

                                  place.address_components.forEach(component => {
                                      if (component.types.includes('street_number')) {
                                          document.getElementById('streetnumber').value = component.long_name
                                      }

                                      if (component.types.includes('route')) {
                                          document.getElementById('street').value = component.long_name
                                      }

                                      if (component.types.includes('locality')) {
                                          document.getElementById('city').value = component.long_name
                                      }

                                      if (component.types.includes('administrative_area_level_1')) {
                                          document.getElementById('state').value = component.long_name
                                      }

                                      if (component.types.includes('postal_code')) {
                                          document.getElementById('postalcode').value = component.long_name
                                      }
                                      if (component.types.includes('administrative_area_level_2')) {
                                          document.getElementById('county').value = component.long_name
                                      }
                                      if (component.types.includes('country')) {
                                          document.getElementById('country').value = component.long_name
                                      }


                                  })

                                  document.getElementById('lat').value = place.geometry.location.lat();
                                  document.getElementById('lng').value = place.geometry.location.lng()

                              }
                          </script>
                          <script
                              src="https://maps.googleapis.com/maps/api/js?key={{ ENV('GOOGLE_MAP_KEY') }}&libraries=places&callback=initAutocomplete">
                          </script>

Is there a way to make the script appear at the bottom with the rest of the scripts?

0 likes
2 replies
LaryAI's avatar
Level 58

To use the Blade component for both creating and editing forms, you can pass in the existing model data as a prop to the component. You can then use this data to set the default values for your form fields. Additionally, to ensure that the script appears at the bottom with the rest of the scripts, you can use Blade's stack directive.

Here's how you can modify your Blade component to accept a model prop and use it to set default values:

{{-- Begin FireOps Geocoder --}}
<div id="geocoder" name="geocoder">
    {{-- ... other fields ... --}}

    {{-- Example for the street field --}}
    <input type="text" id="street" name="street"
        class="form-control @error('street') is-invalid @enderror"
        value="{{ old('street', $model->street ?? '') }}">
    @error('street')
        <span class="invalid-feedback">
            {{ $message }}
        </span>
    @enderror

    {{-- ... other fields ... --}}
</div>
{{-- End FireOps Geocoder --}}

In the above example, old('street', $model->street ?? '') will first check for an old input value (which is useful when validation fails and the page is reloaded). If there's no old input, it will use the street attribute from the passed model. If model is not set (like in a create form), it will default to an empty string.

To use this component in a create or edit form, you can do the following:

{{-- Create form --}}
<x-geocoder />

{{-- Edit form --}}
<x-geocoder :model="$existingModelInstance" />

For the script, you can push it to a stack that is yielded at the bottom of your layout file. Here's how you can do that:

In your component (geocoder.blade.php), replace the script tags with the following:

@push('scripts')
    <script>
        // Your JavaScript code here
    </script>
    <script src="https://maps.googleapis.com/maps/api/js?key={{ env('GOOGLE_MAPS_API_KEY') }}&libraries=places&callback=initAutocomplete"></script>
@endpush

Then, in your main layout file (e.g., layouts/app.blade.php), you should have something like this at the bottom, before the closing </body> tag:

{{-- Other scripts --}}
@stack('scripts')
</body>

This will ensure that the scripts from your component are included at the bottom of the page, along with any other scripts you might have. Remember to replace GOOGLE_MAPS_API_KEY with the actual environment variable that holds your Google Maps API key.

Snapey's avatar

a few pointers

  • use the second parameter of the old() function to provide a default value (usually from and existing model)
  • in the case of a new form, pass a new (empty) model into the component
  • never use env() helper in your code. When the config is cached, the env file is not even read. Instead create a config item that loads from env and then use the config helper in your code
  • incase you use your component more than once in a page, push the google script using the @push() directive

Please or to participate in this conversation.