Solved

GPS save in database

Posted on 2016-10-17
19
37 Views
Last Modified: 2016-10-17
This problem has been going on for a little while and I'm pretty sure I'm really close to achieving what I need.

I have a GPS script using javascript that uses the function geoFindMe() to output into the id of the div "show".

However, this displayed both longitude and latitude as one.

Therefore I decided to separate them by using .values in the javascript so that in the form both values would be separated.

This worked however it takes two clicks to actually get the GPS information in the two inputs.

This will be a part of a form where on SUBMIT of that form the longitude and latitude are stored in the database without the user seeing anything so their location can be verified at a later date.

I need help creating this so that on the input submit the location longitude and latitude is stored in a MySQL database.
stack.html
0
Comment
Question by:RiccardoQuest
  • 8
  • 6
  • 5
19 Comments
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41846781
First up
The mysql library is deprecated - you should consider using mysqli instead.
Secondly,
The Components object is deprecated. It will soon be removed. - from console.
Third, after running your code Lattitude and Longitude show in the <div id="show"></div>

So need to understand what the question is?
0
 

Author Comment

by:RiccardoQuest
ID: 41846786
It's shown as one variable in Show. I need it separated so it can be stored in the database as longitude and latitude separate fields. I just want the show id split into two and stored into database upon one click
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41846788
Here is the code, in the code snippet so we can all see it without having to download a file.
<script>
    var latitude    = 0;
    var longitude   = 0;

    function geoFindMe() {
      var output = document.getElementById("show");

      if (!navigator.geolocation){
        output.innerHTML = "<p>Geolocation is not supported by your browser</p>";
        return;
      }

      function success(position) {
        latitude  = position.coords.latitude;
        longitude = position.coords.longitude;

        output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
        var img = new Image();
        img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=20&size=300x300&sensor=false";

        output.appendChild(img);
      };

      function error() {
        output.innerHTML = "Unable to retrieve your location";
      };

      output.innerHTML = "<p>Locating...</p>";
      fillLatitudeLongitudeElements();
      navigator.geolocation.getCurrentPosition(success, error);
    

    function fillLatitudeLongitudeElements(){
        document.getElementById("latitude").value = latitude;
        document.getElementById("longitude").value = longitude;
        
        var sql = "INSERT INTO gps(lat, long) VALUES (latitude,longitude)";
    }
}
    function prompt(window, pref, message, callback) {
        let branch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);

        if (branch.getPrefType(pref) === branch.PREF_STRING) {
            switch (branch.getCharPref(pref)) {
                case "always":
                return callback(true);
                case "never":
                return callback(false);
            }
        }

        let done = false;

        function remember(value, result) {
            return function() {
                done = true;
                branch.setCharPref(pref, value);
                callback(result);
            }
        }

        let self = window.PopupNotifications.show(
        window.gBrowser.selectedBrowser,
        "geolocation",
        message,
        "geo-notification-icon",
        {
            label: "Share Location",
            accessKey: "S",
            callback: function(notification) {
                done = true;
                callback(true);
            }
        }, [
        {
            label: "Always Share",
            accessKey: "A",
            callback: remember("always", true)
        },
        {
            label: "Never Share",
            accessKey: "N",
            callback: remember("never", false)
        }
        ], {
            eventCallback: function(event) {
                if (event === "dismissed") {
                    if (!done) callback(false);
                    done = true;
                    window.PopupNotifications.remove(self);
                }
            },
            persistWhileVisible: true
        });
    }

    prompt(window,
    "extensions.foo-addon.allowGeolocation",
    "Foo Add-on wants to know your location.",
    function callback(allowed) { alert(allowed); });
</script>

<p><button onclick="geoFindMe()">Locate</button></p>
<div id="show"></div>

 <?php include "../dbconnect.php";
 
 if(isset($_POST['sub'])){
     
     $l = $_POST['long'];
     
     $la = $_POST['lat'];
     
     $n = $_POST['name'];
 
 mysql_query("INSERT INTO `gps`(`lat`, `long`, `name`) VALUES ('".$la."','".$l."','".$n."')");
 
 echo "Done though";
 
 }
 ?>

<form action="#" method="post">
  <fieldset>
    Latitude3:<br>
    <input id="latitude" type="text" name="firstname" value="latitude" readonly><br>
    Longitude:<br>
    <input id="longitude" type="text" name="lastname" value="longitude" readonly><br><br>
    <input type="submit" value="Submit" name="sub">
  </fieldset>
</form>

I would like to separate the show output so i can later store the longitude and lattitude into my table in sql

Open in new window

0
 

Author Comment

by:RiccardoQuest
ID: 41846793
i have changed the name="firstname" and name="lastname" to "lat" and "long"
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41846795
Please have a look at the PHP script starting on line 107, and the HTML document starting on line 124.  The $_POST associative array keys are usually expected to match the name= attributes in the HTML form, but they do not in this part of the code.  Unless your JS is adding more form elements somewhere else, you might want to use var_dump($_POST) and see what is getting transmitted to the PHP script by the HTTP request.

Here is how to handle the MySQL remediation.  This is no longer "optional" or a future issue.  There is no current version of PHP that still has the MySQL extension, except in deprecated status.
https://www.experts-exchange.com/articles/11177/PHP-MySQL-Deprecated-as-of-PHP-5-5-0.html
0
 
LVL 108

Assisted Solution

by:Ray Paseur
Ray Paseur earned 250 total points
ID: 41846797
changed the name="firstname" and name="lastname" to "lat" and "long"
Good idea! :-)

It also looks like you may have a UTF-8 character collision in this code:
output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';

Open in new window

You may also want to add an input control with the name="name" attribute.
0
 

Author Comment

by:RiccardoQuest
ID: 41846809
Updated! If you press Locate twice it happens however i need it to work with one press as i want this to work in the background of another form and the output will be input type="hidden" then inserted in to the database
stack.html
0
 

Author Comment

by:RiccardoQuest
ID: 41846812
<script>
    var latitude    = 0;
    var longitude   = 0;

    function geoFindMe() {
      var output = document.getElementById("show");

      if (!navigator.geolocation){
        output.innerHTML = "<p>Geolocation is not supported by your browser</p>";
        return;
      }

      function success(position) {
        latitude  = position.coords.latitude;
        longitude = position.coords.longitude;

        output.innerHTML = '<p>Latitude is ' + latitude + '° <br>Longitude is ' + longitude + '°</p>';
        var img = new Image();
        img.src = "https://maps.googleapis.com/maps/api/staticmap?center=" + latitude + "," + longitude + "&zoom=20&size=300x300&sensor=false";

        output.appendChild(img);
      };

      function error() {
        output.innerHTML = "Unable to retrieve your location";
      };

      output.innerHTML = "<p>Locating...</p>";
      fillLatitudeLongitudeElements();
      navigator.geolocation.getCurrentPosition(success, error);
    

    function fillLatitudeLongitudeElements(){
        document.getElementById("latitude").value = latitude;
        document.getElementById("longitude").value = longitude;
    }
}
    function prompt(window, pref, message, callback) {
        let branch = Components.classes["@mozilla.org/preferences-service;1"]
        .getService(Components.interfaces.nsIPrefBranch);

        if (branch.getPrefType(pref) === branch.PREF_STRING) {
            switch (branch.getCharPref(pref)) {
                case "always":
                return callback(true);
                case "never":
                return callback(false);
            }
        }

        let done = false;

        function remember(value, result) {
            return function() {
                done = true;
                branch.setCharPref(pref, value);
                callback(result);
            }
        }

        let self = window.PopupNotifications.show(
        window.gBrowser.selectedBrowser,
        "geolocation",
        message,
        "geo-notification-icon",
        {
            label: "Share Location",
            accessKey: "S",
            callback: function(notification) {
                done = true;
                callback(true);
            }
        }, [
        {
            label: "Always Share",
            accessKey: "A",
            callback: remember("always", true)
        },
        {
            label: "Never Share",
            accessKey: "N",
            callback: remember("never", false)
        }
        ], {
            eventCallback: function(event) {
                if (event === "dismissed") {
                    if (!done) callback(false);
                    done = true;
                    window.PopupNotifications.remove(self);
                }
            },
            persistWhileVisible: true
        });
    }

    prompt(window,
    "extensions.foo-addon.allowGeolocation",
    "Foo Add-on wants to know your location.",
    function callback(allowed) { alert(allowed); });
</script>

<p><button onclick="geoFindMe()">Locate</button></p>
<div id="show"></div>

 <?php include "../dbconnect.php";
 
 if(isset($_POST['sub'])){
	 
	 $l = $_POST['long'];
	 
	 $la = $_POST['lat'];
	 
	 $n = $_POST['name'];
 
 mysql_query("INSERT INTO `gps`(`lat`, `long`, `name`) VALUES ('".$la."','".$l."','".$n."')");
 
 echo "Done though";
 
 }
 ?>

<form action="#" method="post">
  <fieldset>
    Latitude0:<br>
    <input id="latitude" type="text" name="lat" value="latitude" readonly><br>
    Longitude:<br>
    <input id="longitude" type="text" name="long" value="longitude" readonly><br><br>
    <input type="submit" value="Submit" name="sub">
  </fieldset>
</form>

Open in new window

0
 
LVL 51

Accepted Solution

by:
Julian Hansen earned 250 total points
ID: 41846822
Ok I think I see the problem. You need to get on top of asynchronous programing.

Lets break your code down

Line 5 you enter geoFindMe()
Line 13 - 22 you define a success handler
Line 24 - 26 you define an error handler
Line 29 You call fillLatitudeLongitudeElements

So far you have done no lookup yet and the global lat / lang values are 0 - so this function call is going to do nothing.
Line 30 you call getCurrentPosition with the success callback. This triggers an asynchronous operation that takes an indeterminate time to complete - meanwhile the main script continues executing - in this case exits.

When the success function is called (a long time later) latitude and longitude are updated to the values returned from the getCurrentPosition. The next time you click - these values are available.

There are essentially two things wrong with your code
1. You are calling fillLatitudeLongitudeElements(); before getting the values
2. Even if you called fillLatitudeLongitudeElements(); after getCurrentPosition it would still probably fail because the asynch call for getCurrentPosition will not complete before fillLatitudeLongitudeElements(); executes.

The solution is therefore to move the fillLatitudeLongitudeElements() inside your success handler i.e. move line 29 to after line 21 in the success handler.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:RiccardoQuest
ID: 41846841
Cant believe that was it. Its so annoying that i had it similair to that but i moved the bracket so it was outside the handler. Im unable to save it in the database though through "sub"
0
 

Author Comment

by:RiccardoQuest
ID: 41846878
Silly me I forgot to rename the file .php Thank you again, Julian Hansen and Ray Paseur for both your help yet again :)
0
 

Author Comment

by:RiccardoQuest
ID: 41846887
Is there anyway to get the "Submit" button to post the gps when submitting the form? So another words just one button to do all ?
0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41846889
Ok let's look at your server side
Firstly there is no name field being sent through - only lat and long.

A useful exercise is to add this line to the beginning of your <?php section
echo "<pre>" . print_r($_POST, true) . "</pre>";

Open in new window

Look at the output from that to understand what is being sent

What I would do is this
(NB: I am using your mysql_query code - but as mentioned above you should move to mysqli);
<?php
// Extract lat / long / name fields and sanitize the values
$latitude = isset($_POST['lat']) ? (float)$_POST['lat'] : false;
$longitude = isset($_POST['long']) ? (float)$_POST['long'] : false;
$name = isset($_POST['name']) ? mysql_real_escape_string($_POST['name']) : false;
// Only proceed if we have valid data
if ($latitude && $longitude && name) {
   // Construct query using HEREDOC
   // Cleaner. Also using embedded variables rather than messy string concat
   $query = <<< QUERY
INSERT INTO `gps` (`lat`,`long`,`name`)
VALUES ('{$latitude}','{$longitude}','{$name}')
QUERY;
   // NB: You don't include a connection resource in your mysql_query call
   // Assuming it is $conn.
   $result = mysql_query($query, $conn);
   if (!$result) {
      echo "Error: " . mysql_error($conn) . "<br/>";
   }
}

Open in new window

Don't forget to add the name field to the form or else the above code won't insert anything.
Also fix your mysql_query (seriously suggest you move to mysqli) but in the meantime you need to include a connection handle in the mysql_query() call
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41846891
Here's a simplified solution.  It might be easiest to start with something like this and build up the application a step at a time. This uses a GET-method request to display the location data, but by the time the web page is loaded, the location data has already been identified and stored in the HTML form input control values.  So you could, in theory, skip the submit button and just display the location, or just pass the location through an AJAX request to a background PHP script that can write to your database.
https://iconoun.com/demo/temp_riccardo.php
<?php // demo/temp_riccardo.php
/**
 * https://www.experts-exchange.com/questions/28976860/GPS-save-in-database.html
 *
 * https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/getCurrentPosition
 *
 * https://www.experts-exchange.com/articles/4276/What-is-near-me-Proximity-calculations-using-PHP-and-MySQL.html
 * https://www.experts-exchange.com/articles/3350/Using-the-Google-Maps-API-in-PHP-and-JavaScript.html
 * https://www.experts-exchange.com/articles/9854/Using-GeoCodes-to-Find-an-Average-Location.html
 */
error_reporting(E_ALL);


// SHOW THE REQUEST VARIABLES, IF ANY
$get = NULL;
if (!empty($_GET)) $get = print_r($_GET, TRUE);


// CREATE OUR WEB PAGE IN HTML5 FORMAT
$htm = <<<HTML5
<!DOCTYPE html>
<html dir="ltr" lang="en-US">
<head>
<meta charset="utf-8" />
<meta name="robots" content="noindex, nofollow" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

<style type="text/css">
/* STYLE SHEET HERE */
</style>

<script>
function success(pos) {
    var location = pos.coords;
    document.getElementById("my_lat").value = location.latitude;
    document.getElementById("my_lon").value = location.longitude;
};

function error(err) {
    console.warn('ERROR(' + err.code + '): ' + err.message);
};

var options = {
    enableHighAccuracy: true,
    timeout: 5000,
    maximumAge: 0
};

navigator.geolocation.getCurrentPosition(success, error, options);
</script>

<title>HTML5 Page With Simple Geo-Location</title>
</head>
<body>

<noscript>Your browsing experience will be much better with JavaScript enabled!</noscript>

<div>$get</div>

<form>
<input type="hidden" id="my_lat" name="lat" value="" />
<input type="hidden" id="my_lon" name="lon" value="" />
<input type="submit" value="Where am I?" />
</form>

</body>
</html>
HTML5;


// RENDER THE WEB PAGE
echo $htm;

Open in new window

0
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41846896
So another words just one button to do all ?
Yes you can do this.
Simply add this
document.forms[0].submit();

Open in new window

After
fillLatitudeLongitudeElements();

Open in new window

In your success handler.
1
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41846920
So another words just one button to do all ?
Or not even a button at all.  Just get the geocode (latitude+longitude) and start the AJAX request to your background database script as soon as you have the geo data.
1
 

Author Comment

by:RiccardoQuest
ID: 41846944
How would i go about that? On page load ?
0
 
LVL 108

Expert Comment

by:Ray Paseur
ID: 41846949
Probably.  This might be worth posting another question :-)
1
 
LVL 51

Expert Comment

by:Julian Hansen
ID: 41847036
How would i go about that? On page load ?
My advice - get on top of the basics first - there is a lot here that you still need to master and if you start adding more unknown territory to the application you could end up confusing yourself.

Get this working solidly as a form post - and make sure you understand how all the moving parts work. Once you have done that you can look at moving to using AJAX.
0

Featured Post

How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

Join & Write a Comment

Introduction This article is designed to assist GIS (Geographic Information System) and GPS (Global Positioning System) developers using ESRI ArcGIS and other spatial information management systems.   For the uninitiated the concept of projectio…
Password hashing is better than message digests or encryption, and you should be using it instead of message digests or encryption.  Find out why and how in this article, which supplements the original article on PHP Client Registration, Login, Logo…
The viewer will get a basic understanding of what section 508 compliance can entail, learn about skip navigation links, alt text, transcripts, and font size controls.
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

23 Experts available now in Live!

Get 1:1 Help Now