In this tutorial, we will show you how to integrate the IP2Location geolocation data with the famous autocomplete plugin from Awesomplete. We will demonstrate how to automatically get the country information based on the visitor’s IP address, then allowing user to select the region and city name by using the autocomplete textbox from Awesomplete.
First and foremost, you need to create a new database. In this tutorial, we will be using the IP2Location™ LITE IP-COUNTRY-REGION-CITY Database. This database can be obtained from https://lite.ip2location.com/database/ip-country-region-city for free. After you have successfully downloaded the database, we will then create the table for the database.
Step 1 Create the ‘ip2location_db3lite’ table
CREATE TABLE `ip2location_db3lite` (
`ip_from` INT(10) NOT NULL, `ip_to` INT(10) NOT NULL, `country_code` CHAR(2) NOT NULL, `country_name` VARCHAR(64) NOT NULL, `region_name` VARCHAR(128) NOT NULL, `city_name` VARCHAR(128) NOT NULL, INDEX `idx_ip_from` (`ip_from`), INDEX `idx_ip_from_to` (`ip_from`, `ip_to`), INDEX `idx_ip_to` (`ip_to`), INDEX `idx_cc_rn` (`country_code`, `region_name`), INDEX `idx_cc_rn_cn` (`country_code`, `region_name`, `city_name`) ) COLLATE='utf8_general_ci' ENGINE=InnoDB ;
Step 2 Import the data file into the table
LOAD DATA LOCAL INFILE 'IP2LOCATION-LITE-DB3.CSV' INTO TABLE `ip2location_db3lite` FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\r\n' IGNORE 0 LINES;
Step 3 The PHP code
In this step we will show how to implement the autocomplete plugin from Awesomplete with the IP2Location LITE database. First, you need to download the sample code from their website and find the awesomplete.css and awesomplete.js inside the downloaded files. Then, copy these two files into your web directory. After that, include these two js files and jquery.min.js with the following code in the header:
<link rel="stylesheet" href="awesomplete.css" /> <script src="awesomplete.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Next, the HTML code is shown as in below:
<label> Country Name:<br /> <?php print $country_name; ?> </label> <br/><br/> <label> Region Name:<br /> <input class="awesomplete" list="mylist" id="rname" data-minchars="1" data-maxitems="12" /> <datalist id="mylist"> <?php //Get the region name based on country_code into array $sql = "select DISTINCT region_name from ip2location_db3lite where country_code = '".$country_code."' GROUP BY region_name"; $rn_result = mysqli_query($connect,$sql); while($row=mysqli_fetch_assoc($rn_result)){ echo "<option>".$row['region_name']."</option>"; } ?> </datalist> </label> <br/><br/> <label> City Name:<br /> <input id="cname" oninput="myFunction()" data-minchars="1" data-maxitems="12" /> </label>
In the above code, the input text field tags have been added with class="awesomplete" list="mylist"
. On the initial page load, retrieve the country name based on the visitor’s IP address for display. And for the second input text field, the oninput
will trigger a self-defined function in order to take user input, process it and send back the result in the same page without reloading using AJAX. For the region name, the data is fetched and shown under the <datalist>
tag based on the visitor’s IP address. To do all this, you need to add the following code before your <!DOCTYPE html>
or <html>
tag:
<?php //connect to database $connect = mysqli_connect("localhost", "root", "", "ip2location"); //retrieve countryName based on ipaddress //Get the visitor IP address //$ip = $_SERVER['REMOTE_ADDR']; //In case you are testing locally with 127.0.0.1, //you can uncomment the below line to assign the IP address //to 8.8.8.8 (or whatever) for your testing. $ip= "8.8.8.8"; // Function to convert IP address (xxx.xxx.xxx.xxx) to IP number (0 to 256^4-1) function Dot2LongIP ($ip) { if ($ip == ""){ return 0; }else { $ips = explode(".", $ip); return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 * 256); } } // Convert IP address to IP number for querying database $ipno = Dot2LongIP($ip); //start to query from database $query = 'select DISTINCT country_name,country_code from ip2location_db3lite where "'.$ipno.'"<= ip_to AND ip_from<="'.$ipno.'"'; $result = mysqli_query($connect, $query); //check if query is successful if(!empty($result)){ while($row = mysqli_fetch_assoc($result)){ //save the result into local variable for future usage<br> $country_name = $row["country_name"]; $country_code = $row["country_code"]; } } // Handle AJAX request (start) //This piece of code is added in the beginning of this page to avoid any override or null issue. if( isset($_POST['ajax']) && isset($_POST['name']) ){ //retrieve the city name based on country_name and region_name into array $region_name = $_POST['name']; $sql = "select DISTINCT city_name from ip2location_db3lite where country_code = '".$country_code."' AND region_name = '".$region_name."' GROUP BY city_name"; $result = mysqli_query($connect,$sql); $data = array(); while($row=mysqli_fetch_assoc($result)){ $data[] = $row['city_name']; } echo json_encode($data); exit; } // Handle AJAX request (end) ?>
After that, add the following code in your page right after the [html]</body>[/html] tag:
<script> var input = document.getElementById("cname"); var awesomplete = new Awesomplete(input); function myFunction() { var name = $('#rname').val(); $.ajax({ type: 'post', data: {ajax: 1,name: name}, dataType:"json", success: function(response){ awesomplete.list = response; } }); } </script>
Below is the example of the screenshot for the above tutorial:
Below is the complete code:
<?php //connect to database $connect = mysqli_connect("localhost", "root", "", "ip2location"); //retrieve countryName based on ipaddress //Get the visitor IP address //$ip = $_SERVER['REMOTE_ADDR']; //In case you are testing locally with 127.0.0.1, //you can uncomment the below line to assign the IP address //to 8.8.8.8 (or whatever) for your testing. $ip= "8.8.8.8"; // Function to convert IP address (xxx.xxx.xxx.xxx) to IP number (0 to 256^4-1) function Dot2LongIP ($ip) { if ($ip == ""){ return 0; }else { $ips = explode(".", $ip); return ($ips[3] + $ips[2] * 256 + $ips[1] * 256 * 256 + $ips[0] * 256 * 256 * 256); } } // Convert IP address to IP number for querying database $ipno = Dot2LongIP($ip); //start to query from database $query = 'select DISTINCT country_name,country_code from ip2location_db3lite where "'.$ipno.'"<= ip_to AND ip_from<="'.$ipno.'"'; $result = mysqli_query($connect, $query); //check if query is successful if(!empty($result)){ while($row = mysqli_fetch_assoc($result)){ //save the result into local variable for future usage $country_name = $row["country_name"]; $country_code = $row["country_code"]; } } // Handle AJAX request (start) //This piece of code is added in the beginning of this page to avoid any override or null issue. if( isset($_POST['ajax']) && isset($_POST['name']) ){ //retrieve the city name based on country_name and region_name into array $region_name = $_POST['name']; $sql = "select DISTINCT city_name from ip2location_db3lite where country_code = '".$country_code."' AND region_name = '".$region_name."' GROUP BY city_name"; $result = mysqli_query($connect,$sql); $data = array(); while($row=mysqli_fetch_assoc($result)){ $data[] = $row['city_name']; } echo json_encode($data); exit; } // Handle AJAX request (end) ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Awesomplete: Ultra lightweight, highly customizable, simple autocomplete, by Lea Verou</title> <link rel="stylesheet" href="prism/prism.css" /> <link rel="stylesheet" href="awesomplete.css" /> <link rel="stylesheet" href="style.css" /> <script src="awesomplete.js"></script> <script src="index.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> </head> <body class="language-markup"> <header> <h1>Awesomplete</h1> <p>Ultra lightweight, customizable, simple autocomplete widget with zero dependencies, built with modern standards for <abbr title="Verified to work in: IE9 (sorta), IE10+, Chrome, Firefox, Safari 5+, Mobile Safari">modern browsers</abbr>. <a href="http://lea.verou.me/2015/02/awesomplete-2kb-autocomplete-with-zero-dependencies">Because <code><datalist></code> still doesn’t cut it.</a></p> </header> <section> <h1>Demo</h1> <label> Country Name:<br /> <?php print $country_name; ?> </label> <br/><br/> <label> Region Name:<br /> <input class="awesomplete" list="mylist" id="rname" data-minchars="1" data-maxitems="12" /> <datalist id="mylist"> <?php //Get the region name based on country_code into array $sql = "select DISTINCT region_name from ip2location_db3lite where country_code = '".$country_code."' GROUP BY region_name"; $rn_result = mysqli_query($connect,$sql); while($row=mysqli_fetch_assoc($rn_result)){ echo "<option>".$row['region_name']."</option>"; } ?> </datalist> </label> <br/><br/> <label> City Name:<br /> <input id="cname" oninput="myFunction()" data-minchars="1" data-maxitems="12" /> </label> <p>Note that by default you need to type <strong>at least 2 characters</strong> for the popup to show up, though that’s <a href="#customization">super easy to customize</a>. With Awesomplete, making something like this can be as simple as:</p> <pre class="language-markup"><code><input class="awesomplete" data-list="Ada, Java, JavaScript, Brainfuck, LOLCODE, Node.js, Ruby on Rails" /></code></pre> <pre class="language-javascript"><code>// No extra JS needed for basic usage!</code></pre> </section> </body> <script> var input = document.getElementById("cname"); var awesomplete = new Awesomplete(input); function myFunction() { var name = $('#rname').val(); $.ajax({ type: 'post', data: {ajax: 1,name: name}, dataType:"json", success: function(response){ awesomplete.list = response; } }); } </script> </html>
Have a questions? Feel free to ask here!