├── .gitignore
├── README.md
├── acf-Autocomplete.php
├── assets
└── js
│ └── input.js
├── fields
└── class-LQ-acf-field-Autocomplete.php
└── images
├── field-in-use.png
└── repeater-field.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled source #
2 | ###################
3 | *.com
4 | *.class
5 | *.dll
6 | *.so
7 | *.swp
8 | *.swo
9 | **/*.sw[abcdefghijklmnop]
10 | .sass-cache
11 |
12 | # Packages #
13 | ############
14 | fuel/app/logs/*/*/*
15 | fuel/app/cache/*/*
16 | *.7z
17 | *.dmg
18 | *.iso
19 | *.rar
20 | *.zip
21 | *.psd
22 | .idea
23 | .idea/tasks.xml
24 | node_modules
25 | bower_components
26 |
27 | # Logs and databases #
28 | ######################
29 | *.log
30 |
31 | # OS generated files #
32 | ######################
33 | .DS_Store
34 | .DS_Store?
35 | ._*
36 | .Spotlight-V100
37 | .Trashes
38 | ehthumbs.db
39 | Thumbs.db
40 |
41 | # Wordpress Specific Ignores
42 |
43 | vendor
44 | sql
45 |
46 | # Theme Ignores
47 | .svn
48 | .cvs
49 |
50 |
51 | # wordpress specific
52 | wp-config.php
53 | wp-content/uploads/
54 | wp-content/blogs.dir/
55 | wp-content/upgrade/*
56 | wp-content/backup-db/*
57 | wp-content/advanced-cache.php
58 | wp-content/wp-cache-config.php
59 | wp-content/cache/*
60 | wp-content/cache/supercache/*
61 |
62 | # wpengine specific
63 | .smushit-status
64 | .gitattributes
65 | _wpeprivate
66 | wp-content/object-cache.php
67 | wp-content/mu-plugins/mu-plugin.php
68 | wp-content/mu-plugins/slt-force-strong-passwords.php
69 | wp-content/mu-plugins/limit-login-attempts
70 | wp-content/mu-plugins/wpengine-common
71 | wp-content/mysql.sql
72 |
73 | # wp core (as of 3.4.1)
74 | /db-config.php
75 | /index.php
76 | /license.txt
77 | /readme.html
78 | /wp-activate.php
79 | /wp-app.php
80 | /wp-atom.php
81 | /wp-blog-header.php
82 | /wp-comments-post.php
83 | /wp-commentsrss2.php
84 | /wp-config-sample.php
85 | /wp-cron.php
86 | /wp-feed.php
87 | /wp-links-opml.php
88 | /wp-load.php
89 | /wp-login.php
90 | /wp-mail.php
91 | /wp-rdf.php
92 | /wp-rss.php
93 | /wp-rss2.php
94 | /wp-pass.php
95 | /wp-register.php
96 | /wp-settings.php
97 | /wp-signup.php
98 | /wp-trackback.php
99 | /xmlrpc.php
100 | /wp-admin
101 | /wp-includes
102 | /wp-content/index.php
103 | /wp-content/themes/twentyten
104 | /wp-content/themes/index.php
105 | /wp-content/plugins/index.php
106 |
107 | # large/disallowed file types
108 | # a CDN should be used for these
109 | *.hqx
110 | *.deb
111 | *.img
112 | *.msi
113 | *.msp
114 | *.msm
115 | *.mid
116 | *.midi
117 | *.kar
118 | *.mp3
119 | *.ogg
120 | *.m4a
121 | *.ra
122 | *.3gpp
123 | *.3gp
124 | *.mp4
125 | *.mpeg
126 | *.mpg
127 | *.mov
128 | *.webm
129 | *.flv
130 | *.m4v
131 | *.mng
132 | *.asx
133 | *.asf
134 | *.wmv
135 | *.avi
136 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ACF GoogleMaps Autocomplete
2 |
3 | Adds a new field type to ACF so you can use Google Maps Autocomplete anywhere inside your admin area without displaying the full ACF map component.
4 |
5 | Useful for long lists of locations etc.
6 |
7 | ## Installation
8 |
9 | - Copy the folder into your wp-content/plugins folder
10 | - Make sure you have included the standard ACF call to your Google Map API key in your functions.php file
11 | - Activate ACF and this plugin
12 | - Create the new ACF field, selecting the new GoogleMaps Autocomplete field type, under jQuery
13 | - Enter, and pull the data out to the Front-End
14 |
15 | This plugin will add 3 fields to be saved within your ACF data - address, lat, lng
16 |
17 | It is up to you to decide how to display them on the Front-End and send the information to the map; I recommend using data attributes.
18 |
19 | ### Include this in your functions.php file
20 |
21 | ```php
22 | function my_acf_init() {
23 | acf_update_setting('google_api_key', '**your_map_key_here**' );
24 | }
25 |
26 | add_action('acf/init', 'my_acf_init');
27 | ```
28 |
29 | ## Screenshot
30 |
31 | 
32 |
33 | ## Helped you out? Buy me a coffee!
34 |
35 |
36 |
--------------------------------------------------------------------------------
/acf-Autocomplete.php:
--------------------------------------------------------------------------------
1 | settings = array(
20 | 'version' => '1.0.0',
21 | 'url' => plugin_dir_url( __FILE__ ),
22 | 'path' => plugin_dir_path( __FILE__ ),
23 | 'enqueue_google_maps' => true,
24 | );
25 |
26 | add_action('acf/include_field_types', array($this, 'include_field')); // v5
27 | }
28 |
29 | function include_field( $version = false ) {
30 | include_once(plugin_dir_path( __FILE__ ) . 'fields/class-LQ-acf-field-Autocomplete.php');
31 | }
32 |
33 | }
34 |
35 | new LQ_acf_plugin_Autocomplete();
36 |
37 | endif;
38 |
39 | ?>
40 |
--------------------------------------------------------------------------------
/assets/js/input.js:
--------------------------------------------------------------------------------
1 | document.autocompleteField = function() {
2 | // Has user pressed the down key to navigate autocomplete options?
3 | let hasDownBeenPressed = false;
4 |
5 | const inputHandling = function(searchInput) {
6 | // options
7 | const options = {
8 | componentRestrictions: { country: 'gb' }
9 | };
10 | // Google Maps Autocomplete Method
11 | const autocomplete = new google.maps.places.Autocomplete(searchInput, options);
12 | google.maps.event.trigger(autocomplete, 'place_changed');
13 | // Default listener outside to stop nested loop returning odd results
14 | searchInput.addEventListener('keydown', e => {
15 | if (e.keyCode === 40) {
16 | hasDownBeenPressed = true;
17 | }
18 | });
19 |
20 | // GoogleMaps API custom eventlistener method
21 | google.maps.event.addDomListener(searchInput, 'keydown', e => {
22 | // Maps API e.stopPropagation();
23 | e.cancelBubble = true;
24 |
25 | // If enter key, or tab key
26 | if (e.keyCode === 13 || e.keyCode === 9) {
27 | // If user isn't navigating using arrows and this hasn't ran yet
28 | if (!hasDownBeenPressed && !e.hasRanOnce) {
29 | e.preventDefault();
30 | google.maps.event.trigger(e.target, 'keydown', {
31 | keyCode: 40,
32 | hasRanOnce: true
33 | });
34 | }
35 | }
36 | });
37 |
38 | // Clear the input on focus, reset hasDownBeenPressed
39 | searchInput.addEventListener('focus', () => {
40 | hasDownBeenPressed = false;
41 | searchInput.value = '';
42 | });
43 |
44 | // place_changed GoogleMaps listener when we do submit
45 | google.maps.event.addListener(autocomplete, 'place_changed', function() {
46 | // Get the place info from the autocomplete Api
47 | const place = autocomplete.getPlace();
48 |
49 | //If we can find the place lets go to it
50 | if (typeof place.address_components !== 'undefined') {
51 | // reset hasDownBeenPressed in case they don't unfocus
52 | hasDownBeenPressed = false;
53 | // 🤢 😷
54 | const hiddenInputs = Array.from(searchInput.parentNode.parentNode.children.item(0).children);
55 | hiddenInputs.forEach(function(input) {
56 | switch (input.dataset.name) {
57 | case 'address':
58 | input.value = place.formatted_address;
59 | break;
60 | case 'lat':
61 | input.value = place.geometry.location.lat();
62 | break;
63 | case 'lng':
64 | input.value = place.geometry.location.lng();
65 | break;
66 | }
67 | });
68 | }
69 | });
70 | };
71 |
72 | // search input
73 |
74 | const readyExistingFields = function() {
75 | const searchInput = Array.from(document.querySelectorAll('input[data-maps-autocomplete]'));
76 | searchInput.forEach(input => {
77 | inputHandling(input);
78 | });
79 | };
80 |
81 | const readyNewFields = function(input) {
82 | inputHandling(input);
83 | };
84 |
85 | if (typeof acf.add_action !== 'undefined') {
86 | acf.add_action('ready', readyExistingFields);
87 | acf.add_action('append', function(parent) {
88 | var input = parent[0].querySelector('.search');
89 | if (!input) return;
90 | readyNewFields(input);
91 | });
92 | }
93 | };
94 |
--------------------------------------------------------------------------------
/fields/class-LQ-acf-field-Autocomplete.php:
--------------------------------------------------------------------------------
1 | name = 'autocomplete';
12 | $this->label = __("Google Autocomplete",'acf');
13 | $this->category = 'jquery';
14 | $this->defaults = array(
15 | 'center_lat' => '',
16 | 'center_lng' => ''
17 | );
18 |
19 | $this->settings = $settings;
20 | // do not delete!
21 | parent::__construct();
22 | }
23 |
24 | function input_admin_enqueue_scripts() {
25 |
26 | // localize
27 | acf_localize_text(array(
28 | 'Sorry, this browser does not support geolocation' => __('Sorry, this browser does not support geolocation', 'acf'),
29 | ));
30 |
31 | if( !acf_get_setting('enqueue_google_maps') ) {
32 | return;
33 | }
34 |
35 | $url = $this->settings['url'];
36 | $version = $this->settings['version'];
37 |
38 | wp_register_script('autocomplete', "{$url}assets/js/input.js", $version);
39 | wp_enqueue_script('autocomplete');
40 |
41 | $api = array(
42 | 'key' => acf_get_setting('google_api_key'),
43 | 'client' => acf_get_setting('google_api_client'),
44 | 'libraries' => 'places',
45 | 'ver' => 3,
46 | 'callback' => 'document.autocompleteField'
47 | );
48 |
49 | $api = apply_filters('acf/fields/google_map/api', $api);
50 |
51 | if( empty($api['key']) ) unset($api['key']);
52 | if( empty($api['client']) ) unset($api['client']);
53 |
54 | $api_path = add_query_arg($api, 'https://maps.googleapis.com/maps/api/js');
55 |
56 | wp_register_script( 'google_maps', $api_path, false, '3' );
57 | wp_enqueue_script( 'google_maps' );
58 |
59 | }
60 |
61 | function render_field( $field ) {
62 | // validate value
63 | if( empty($field['value']) ) {
64 | $field['value'] = array();
65 | }
66 |
67 | //var_dump($field);
68 |
69 | $field['value'] = wp_parse_args($field['value'], array(
70 | 'address' => '',
71 | 'lat' => '',
72 | 'lng' => ''
73 | ));
74 |
75 | $atts = array(
76 | 'id' => $field['id'],
77 | 'class' => "acf-google-map {$field['class']}",
78 | 'data-lat' => $field['center_lat'],
79 | 'data-lng' => $field['center_lng'],
80 | );
81 |
82 | if( $field['value']['address'] ) {
83 | $atts['class'] .= ' -value';
84 | }
85 |
86 | ?>
87 |
88 |