1

I have the following code that uses the StandaloneSearchBox component from react-google-maps. The search works fine, but what I would like to be able to do is to turn around and populate multiple input fields with the retrieved data from StandaloneSearchBox to allow the user to review/edit any inconsistencies prior to adding the information to a database. The various things I have tried so far without success are commented out.

/* global google */

import React, { Component } from "react";
import {
  compose,
  withProps,
  lifecycle
} from "recompose";
import {
  withScriptjs
} from "react-google-maps";
import { StandaloneSearchBox } from "react-google-maps/lib/components/places/StandaloneSearchBox";
import "./Form.css";

const MyMapComponent = compose(

  withProps({
    googleMapURL: "https://maps.googleapis.com/maps/api/js?key=....&v=3.exp&libraries=geometry,drawing,places",
    loadingElement: <div style={{ height: `100%` }} />,
    containerElement: <div style={{ height: `600px` }} />,
    mapElement: <div style={{ height: `75vh`, width: '50vw' }} />,
  }),
  lifecycle({
    componentWillMount() {
      const refs = {}

      this.setState({
        places: [],

        onSearchBoxMounted: ref => {
          refs.searchBox = ref;
        },
        onPlacesChanged: () => {
          const places = refs.searchBox.getPlaces();

          this.setState({
            places,
            // location_name: this.places.name,
            // location_name: props.places.name
            location_name: places.name
          });
        },
      })
    },
  }),
  withScriptjs
)(props =>
  <div data-standalone-searchbox="">
    <StandaloneSearchBox
      ref={props.onSearchBoxMounted}
      bounds={props.bounds}
      onPlacesChanged={props.onPlacesChanged}
    >
      <input
        type="text"
        placeholder="Enter establishment name:"
        style={{
          boxSizing: `border-box`,
          border: `1px solid transparent`,
          width: `500px`,
          height: `45px`,
          padding: `0 12px`,
          borderRadius: `3px`,
          boxShadow: `0 2px 6px rgba(0, 0, 0, 0.3)`,
          fontSize: `25px`,
          outline: `none`,
          textOverflow: `ellipses`,
        }}
      />
    </StandaloneSearchBox>
    <form className="form">
      <input
        value={this.location_name}
        name="location_name"
        onChange={this.handleInputChange}
        type="text"
        placeholder="Establishment"
      />
      <button onClick={this.handleFormSubmit}>Submit</button>
    </form>
    < ol>
      {
        props.places.map(({ place_id,
          name,
          formatted_address,
          formatted_phone_number,
          geometry: { location }
        }) =>
          <div>
            <div>
              <p>
                {name}
                {/* {this.location_name = name} */}
              </p>
              {formatted_address.split(',').map((address, i) =>
                <p>
                  {address}
                </p>
              )}
              <p>
                {formatted_phone_number}
              </p>
            </div>
          </div>
        )
      }
    </ol >
  </div >
);

class MyFancyComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      location_name: ""
    }
  }

  render() {
    return (
      <MyMapComponent
      />
    )
  }
};


export default MyFancyComponent;

Any assistance, or hints, would be appreciated.

1 Answer 1

1

The following example demonstrates how places result (name property) could be handled:

<form onSubmit={this.saveAddress}>
      <div>
        {this.state.places.map(({ place_id, name, formatted_address, geometry: { location } }) =>
          <div key={place_id}>
            <input type="text" defaultValue={name} onChange={(e) => this.handleChange(place_id, e)} />
          </div>
        )}
      </div>
      <button>Save</button>
      <div><pre>{JSON.stringify(this.state.places.map( p=> p.name), null, 2) }</pre></div>
    </form>




handleChange = (placeId, e) => {
    let newName = e.target.value;
    this.setState(prevState => {
      const places = [...prevState.places];
      let idx = places.findIndex(p => { return p.place_id == placeId });
      places[idx].name = newName;
      return { places: places };
    });
  };

Now the updated/reviewed places result could be saved once the user submits the form:

saveAddress = (e) => {
   //console.log(this.state.places);
   e.preventDefault();
};

Here is a demo for your reference

Sign up to request clarification or add additional context in comments.

1 Comment

That worked great. My only issue is that if deleting more then one character you have to hi-lite the characters or click in the input field. Once again, thank you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.