PageSourceSearch

https://www.filmnc.com/js/widgetGeoPicker.js

js filmnc.com collected 2026-10-02 06:19:33 UTC 9,207 bytes, 268 lines download raw bytes

1/**
2 *  Mapbox Geocoder Widget
3 * 
4 *      new WidgetGeoPicker("lnglat", {
5 *          "button": "buttonId",
6 *          "map": "mapContainerId",
7 *          "apikey": "xxxxxxxxx"
8 *      });
9 * 
10 *      new WidgetGeoPicker(["lng", "lng"], {
11 *          "map": "mapContainerId",
12 *          "apikey": "xxxxxxxxx"
13 *      });
14 * 
15 */
16class WidgetGeoPicker {
17    constructor (fields, opts) {
18        const defaults = {
19            "button": "",
20            "map": "",
21            "preview": true,
22            "mapboxToken": "pk.eyJ1IjoiYjE1cHJvamVjdHMiLCJhIjoiY2t4ZXFqbHcwMWh3YzJya3lxa2dnMWg2YSJ9.3AzGYYZuT4iN50awlSSLAg"
23        };
24        this.config = Object.assign({}, defaults, opts);
25        this.eles = this.fieldelement(fields); // [eleLng, eleLat | eleLngLat]
26        this.modal = undefined;
27        this.preview = undefined;
28        this.showpicker = this.showpicker.bind(this);
29        this.removemodal = this.removemodal.bind(this);
30        this.clearselected = this.clearselected.bind(this);
31        this.initmapbox = this.initmapbox.bind(this);
32        this.saveselection = this.saveselection.bind(this);
33        this.location = false;
34        this.init();
35    }
36
37    /**
38     * Binds events to dom elements
39     * 
40     */
41    init () {
42        if (this.config.button) {
43            this.config.button = document.getElementById(this.config.button);
44            if (this.config.button) {
45                this.config.button.addEventListener("click", this.showpicker);
46            }
47        } else {
48            this.eles.forEach((fld, i) => {
49                fld.addEventListener("focus", this.showpicker);
50            });
51        }
52    }
53
54    /**
55     * Renders and attaches the GeoPicker modal to the DOM
56     * 
57     */
58    showpicker () {
59        this.removemodal();
60        this.modal = document.createElement("div");
61        this.modal.classList.add(this.constructor.name);
62        this.modal.innerHTML = `
63        <div class="ui container">
64            <div class="ui grid">
65                <div class="twelve wide column"></div>
66                <div class="four wide right aligned column">
67                    <div class="ui buttons" style="padding-top:0.6rem;">
68                        <button id="${this.constructor.name}_cancel" class="ui button">Cancel</button>
69                        <button id="${this.constructor.name}_save" class="ui primary button">Save</button>
70                    </div>
71                </div>
72                <div id="map" class="sixteen wide column"></div>
73            </div>
74        </div>
75        `;
76        document.body.append(this.modal);
77        this.initmapbox();
78    }
79
80    /**
81     * Invokes the MapBox map and event handlers
82     * 
83     */
84    initmapbox () {
85        const that = this;
86        mapboxgl.accessToken = this.config.mapboxToken;
87        const map = new mapboxgl.Map({
88            container: 'map',
89            bounds: [[-84.39, 33.757], [-75.38, 36.624]],
90            style: 'mapbox://styles/mapbox/streets-v11',
91            zoom: 6
92        })
93        .on('click', function (e) {
94            that.location = [e.lngLat.lng, e.lngLat.lat];
95            updateMarker(that.location);
96        });
97        const updateMarker = (loc) => {
98            if (map._markers.length > 0) {
99                map._markers[0].setLngLat(loc);
100                return map._markers[0]; 
101            }
102            const marker = new mapboxgl.Marker({draggable: true})
103                    .setLngLat(loc).addTo(map);
104            marker.on("dragend", function (e) {
105                const lngLat = this.getLngLat();
106                that.location = [lngLat.lng, lngLat.lat];
107            });
108            return marker;
109        };
110        const coordinatesGeocoder = function (query) {
111            const matches = query.match(/^[ ]*(?:Lat: )?(-?\d+\.?\d*)[, ]+(?:Lng: )?(-?\d+\.?\d*)[ ]*$/i);
112            if (!matches) {
113                return null;
114            }
115            function coordinateFeature(lng, lat) {
116                return {
117                    center: [lng, lat],
118                    geometry: {
119                        type: 'Point',
120                        coordinates: [lng, lat]
121                    },
122                    place_name: 'Lat: ' + lat + ' Lng: ' + lng,
123                    place_type: ['coordinate'],
124                    properties: {},
125                    type: 'Feature'
126                };
127            }
128            const coord1 = Number(matches[1]);
129            const coord2 = Number(matches[2]);
130            const geocodes = [];
131            if (coord1 < -90 || coord1 > 90) {
132                geocodes.push(coordinateFeature(coord1, coord2));
133            }
134            if (coord2 < -90 || coord2 > 90) {
135                geocodes.push(coordinateFeature(coord2, coord1));
136            }
137            if (geocodes.length === 0) {
138                geocodes.push(coordinateFeature(coord1, coord2));
139                geocodes.push(coordinateFeature(coord2, coord1));
140            }
141            return geocodes;
142        };
143        const GeoCoder = new MapboxGeocoder({
144            accessToken: mapboxgl.accessToken,
145            localGeocoder: coordinatesGeocoder,
146            zoom: 4,
147            placeholder: 'address or lat,lng',
148            mapboxgl: mapboxgl,
149            reverseGeocode: true,
150            marker: false
151        });
152        GeoCoder.on("result", (rslt) => {
153            this.location = rslt.result.center;
154            updateMarker(this.location);
155        });
156        // Add the control to the map.
157        map.addControl(GeoCoder, "top-left");
158        // Widget Buttons
159        const xbut = document.getElementById(`${this.constructor.name}_cancel`);
160        if (xbut) {
161            xbut.addEventListener("click", this.removemodal);
162        }
163        const sbut = document.getElementById(`${this.constructor.name}_save`);
164        if (sbut) {
165            sbut.addEventListener("click", this.saveselection);
166        }
167    }
168
169    /**
170     * Update the form LngLat with the selected values
171     */
172    saveselection (e) {
173        if (this.location && this.eles) {
174            if (this.eles.length == 1) {
175                this.eles[0].value = this.location.join(",");
176            } else {
177                this.eles[0].value = this.location[0];
178                this.eles[1].value = this.location[1];
179            }
180            this.staticmap();
181            this.location = false;
182        } else {
183            alert("Please set a location to save.");
184            return;
185        }
186        this.removemodal();
187    }
188
189    /**
190     * Display the selected loction with a static map 
191     */
192    staticmap () {
193        const css = `${this.constructor.name}_preview`;
194        if (this.location && this.config.preview) {
195            const lng = this.location[0];
196            const lat = this.location[1];
197            let url = `https://api.mapbox.com/styles/v1/mapbox/streets-v11/static/pin-l+1c71d8(${lng},${lat})/${lng},${lat},13.89,0/600x384@2x?access_token=${this.config.mapboxToken}`;
198            let lnglat = "Lng:" + this.location.join(", Lat:");
199            if (!this.preview) {
200                this.preview = document.createElement("div");
201                this.preview.classList.add(css);
202                if (this.config.button) {
203                    this.config.button.after(this.preview);
204                }
205            }
206            this.preview.innerHTML = `<div><img src="${url}"></div><div>${lnglat} <button class="ui mini button" type="button">Clear</button></div>`;
207            const button = this.preview.querySelector("button");
208            if (button) {
209                button.addEventListener("click", this.clearselected);
210            }
211        }
212    }
213
214    /**
215     * Clear the selected value and preview
216     */
217    clearselected () {
218        if (this.preview) {
219            this.preview.remove();
220            this.preview = undefined;
221        }
222        this.eles.forEach((ele) => {
223            ele.value = "";
224        });
225    }
226
227    /**
228     * Remove the GeoPicker modal from the DOM
229     */
230    removemodal () {
231        if (this.modal) {
232            this.modal.remove();
233            this.modal = undefined;
234        }
235    }
236    
237    /**
238     * Get the form location field(s) based on the passed input params
239     * 
240     */
241    fieldelement (eles) {
242        if (eles.constructor.name == "Object" && (eles.lng && eles.lat || eles.lnglat)) {
243            if (eles.lnglat) {
244                eles = [eles.lnglat];
245            } else {
246                eles = [eles.lng, eles.lat];
247            }
248        } else if (eles.constructor.name == "HTMLInputElement") {
249            eles = [eles];
250        } else if (eles.constructor.name == "String") {
251            eles = [eles];
252        }
253        if (eles.constructor.name == "Array") {
254            eles.forEach((item, i) => {
255                if (item.constructor.name == "String") {
256                    eles[i] = document.getElementById(item);
257                } 
258            });
259            eles.forEach((item) => {
260                if (item.constructor.name != "HTMLInputElement") {
261                    throw new Error("Can't find form fields.");
262                }
263            });
264            return eles;
265        }
266        throw new Error("Can't find form fields.");
267    }
268}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.