Integration: Google-Maps 2.6 - Fabrik and Geocoding

webtv4free.com

New Member
Hi everyone,

I have a dream but I experience a problem which I cannot solve on my own.

My Dream:
The users shall submit information including physical addresses (Street, City, Country) through a form I created with the FABRIK-Component.

This form writes the data to a table in a SQL-Database. The Table is the one that the Google-Maps-Component set up. (This works so far).

The problem is, that the physical addresses need to be automatically geocoded in oder to get the longtitude and latitude without manual interference.

The original Google-Maps 2.6 Component does this. Unfortunately does the form not provide all the fields I need and there is no easy way to customize the layout of the form in the Google-Maps-2.6-Component. Therefore I decided to get the data with the FABRIK-Component.

Fabrik allows to run PHP-Code after the "Submit"-Button was pressed. I guess here lies the key to the solution. Unfortunately I cannot code PHP.

Can anyone help me to fulfill my dream ? Does anyone know a pice of code to automatically geocode the address and insert in the proper field of the table?

Thanks in advance ... Marcus
 
Hi Marcus,
It just so happens that we will be adding a tutorial on how to do this in just a day or so.

Can you wait that long?

Cheers,
-Graylan King
 
ok - this is exactly what I'm needing too... I got my subscription today and hope that buys an installment in the forum - keep up the great work fellas, and very nice looking site too, btw. fwiw the site we're working on is buildinggoodness.org, currently being developed on treebay.org - once we've done this we're also going to plot something new out on cvilleforum.org - a beta state site, using fabrikar 1.02... we'll be upgrading that soon too, and I hope to use fabrikar later with some other projects.... Thanks Ya'll!
 
Does using postgres and triggers make sense for this project? I'm not too familiar with the technique, however would like to be helpful... $40 shouldn't buy too much time in any world... wouldn't mind a swapping some ideas though...
 
fabrik only supports mysql databases so postgre is a no go I'm afraid.

Graylan has been delayed with the Google tutorial due to the arrival of a baby! - Congrats Graylan :D

The google geocoding that i've done in the past is using javascript, so here in theory is what I would do:

create a form with your address info, lets say the fields are called address1, city, state, postcode.
create a hidden text element called "latlon" which will contain the results of the geocoding.
create a button on your form called "getLocation". Add a "click" javascript event with this code:

Code:
<script type="text/javascript" src="[url]http://maps.google.com/maps?file=api&amp;v=2&amp;key=putyourkeyhere"></script>[/url]
var geocoder = new GClientGeocoder();
var address = $('address1') + ' ' + $('city') + ' ' + $('state') + ' ' + $('postcode');
geocoder.getLatLng(
     address ,
     function(point) {
      if (!point) {
         alert('did not find location of ' + address);
      } else {
        $('latlon').value = point.toString();
      }
     }
    );

I've not tried this but it should work.

Alternatively I've seen people using fopen to directly call the google maps geocoder url, but I don't like the idea of allowing fopen on my server installations.

Cheers
Rob
 
I know this thread is old but I need some help figuring out how to get Fabrik to capture the geo data based on an address and then have the option to draw a map in Google. I would really like to have a link in the table to show the maps if possible.
 
The instructions Rob gave should collect the lat/long data.

Then it's a case of customizing a template to provide the actual link. I'll have a go at that right now and get back soon ...

-- hugh
 
The following is using a form with ID 40 as an example. Please replace all occurences of 40 with your formid.

OK, the Geocoding itself needs a little tweaking from Rob's original post. First issue is you can't use a script tag within a javascript, so instead of including the Google JS in the onclick event, create a file in ./components/com_fabrik/js called 40.js, which has this line:

Code:
document.write("<script type=\"text/javascript\" src=\"http://maps.google.com/maps?file=api&v=2&key=yourkeyhere\"></script>");

Replace 'yourkeyhere' with your Google maps key, which you can get for your domain here:

http://code.google.com/apis/maps/signup.html

Then in your button's onclick javascript, paste this:

Code:
var geocoder = new GClientGeocoder();
var address = $('jos_fabrik_formdata_40___address1').value + ' ' + $('jos_fabrik_formdata_40___city').value + ' ' + $('jos_fabrik_formdata_40___state').value + ' ' + $('jos_fabrik_formdata_40___postcode').value;
geocoder.getLatLng(
     address ,
     function(point) {
        if (!point) {
           alert('did not find location of ' + address);
        }
        else {
           $('jos_fabrik_formdata_40___latlon').value = point.toString();
        }
     }
);

Remember to substitute your form ID for 40 above.

Clicking the button should now populate the latlon field. Make sure you make the latlon field long enough, 30 chars should do it.

If you don't want to have a button, we could make the above happen when you submit the form, instead. Get rid of the button and hide the latlon field. Let me know if you want to do that, I'll give you code.

Now I need to work out how to show the map, which will require a template mod ... more news soon ...

-- hugh
 
I got the map display working. So far I haven't been able to do away with the Geocode button, i.e. doing the geocoding on form submit rather than needing a button push.

Here's what I have so far (which supercedes the instructions above).

1) In your ./js/40.js file, put the following:

Code:
function load_map(latlat,latlong) {
  if (GBrowserIsCompatible()) {
    var map = new GMap2(document.getElementById("map"));
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(latlat,latlong), 13);
    var marker = new GMarker(map.getCenter());
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml("<b>GPS Coords</b><br />Lat: " + latlat + "<br />Long: " + latlong);
    });
    map.addOverlay(marker);
    marker.openInfoWindowHtml("<b>GPS Coords</b><br />Lat: " + latlat + "<br />Long: " + latlong);    }
}

function do_geocode() {
    var geocoder = new GClientGeocoder();
    var address = $('jos_fabrik_formdata_40___address1').value + ', ' + $('jos_fabrik_formdata_40___city').value + ', ' + $('jos_fabrik_formdata_40___state').value + ' ' + $('jos_fabrik_formdata_40___postcode').value;
    geocoder.getLatLng(
        address ,
        function(point) {
            if (!point) {
                alert('Could not find location of ' + address);
            }
            else {
                $('jos_fabrik_formdata_40___latlon').value = point.toString();
            }
        }
    );
}
2) Clone the default template (as per this thread), and replace the content of template.php with the following:

Code:
<?php /**
 * @package  fabrik
 * @version 1.0.4
 * @Copyright (C) Rob Clayburn
 * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html
 */
/* MOS Intruder Alerts */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
?>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAq-gv5SfH67XHsplhIHIPjxRWgZKhnXaB5STlb57LvQlAVAJYnxRhIjPFR_NuuqSzqGmLP2Oyi_6JNA" type="text/javascript"></script>
<h1><?php echo $this->form->title;?></h1>
<?php echo $this->topJS;
echo $this->form->intro;?>
<?php if( $this->form->error != '' ){
    echo "<div class='fabrikerror'>" . $this->form->error . "</div>";
}?>
<form action="<?php echo $this->form->action;?>" class="fabrikForm" <?php echo $this->form->js;?> method="post" name="<?php echo $this->form->name;?>" id="<?php echo $this->form->name;?>" enctype="<?php echo $this->form->encType;?>">
    <?php if($this->showEmail){
        echo $this->emailLink;
    }?> <?php if($this->showPDF){
        echo $this->pdfLink;
    }?> <?php if($this->showPrint){
        echo $this->printLink;
    }?> <?php
    
    foreach( $this->groups as $group ){?>
    <h3><?php echo $group->title;?></h3>
    <?php if($group->canRepeat && $this->task != 'viewTableRowDetails' ){?>
        <div><a class="addGroup" href="#" id="<?php echo $group->addId;?>"><?php echo _ADD;?></a> | <a class="deleteGroup" href="#" id="<?php echo $group->delId;?>"><?php echo _DELETE;?></a></div>
    <?php }?>
    <div class="fb_group" id="group<?php echo $group->id;?>" style="<?php echo $group->css;?>">
        
        <?php if($group->canRepeat){
            $subgroupCounter = 0;
            foreach($group->subgroups as $subgroup){?>
                <div class="fb_sub_group" id="subgroup<?php echo $group->id . "_" . $subgroupCounter;?>">
                <?php foreach( $subgroup as $element ){?>
                    <div class="<?php echo $element->divclass ?>" id="fb_element_<?php echo $element->int;?>">
                        <?php if($element->error != ''){?>
                            <div class="fabrikerror"><?php echo $element->error;?></div>
                        <?php }?> 
                        <?php echo $element->label;?>
                        <?php echo $element->element;?>
                    </div>
                <?php }?></div>
                <?php $subgroupCounter ++;
            } ?>
        <?php }else{?>
            <?php foreach( $group->elements as $element ){?>
                <div class="<?php echo $element->divclass ?>"  id="fb_element_<?php echo $element->int;?>"><?php if($element->error != ''){?>
                <div class="fabrikerror"><?php echo $element->error;?></div>
                <?php }?> <?php echo $element->label;?> <?php echo $element->element;?>
                </div>
            <?php
                if ($element->id == 'jos_fabrik_formdata_40___latlon') {
                    $latlong = $element->value;
                }
            }
            if (empty($this->form->submitButton))
            {
                if ($latlong) {
                ?>
<script type="text/javascript">
window.addEvent('load', function(){
   load_map<?php echo $latlong; ?>;
});
</script>
    <div id="map" style="width: 500px; height: 300px"></div>
                <?php
                }
            }
            else {
            ?>
<script type="text/javascript">
$('fabrik40').addEvent('submit',function(e){ do_geocode(); });
</script>
            <?php
            }
         }?>
    </div>
<?php
    }
    ?><?php echo $this->hiddenFields;
    echo $this->ask_receipt?>
    <div class="fabrikActions"><?php echo $this->form->resetButton;?> <?php echo $this->form->submitButton;?>
    </div>
</form>
<?php echo $this->jsActions; ?>
<div id="fabrikScroller"></div>
3) On your Geocode button (the one that calculates the latlong), replace the previous javascript 'onclick' code with this:

Code:
do_geocode();
The way this hangs together is:

When you are editing or submitting a form, the map is not displayed, but the Geocode button is.

When you view a record in View mode, the Geocode button is not displayed, but the map is displayed.

Remember to replace all occurrences of 40 in the above with your form ID. Or if your table was created outside of Fabrik, replace all occurences of jos_fabrik_formdata_40 with your table name.

I set all the above up on my test server, and it works quite nicely. See attached screenshot.

-- hugh
 

Attachments

  • geocode.jpg
    geocode.jpg
    60.5 KB · Views: 350
I know this thread is old but I need some help figuring out how to get Fabrik to capture the geo data based on an address and then have the option to draw a map in Google. I would really like to have a link in the table to show the maps if possible.

Did you ever try the solution I gave you?

-- hugh
 
I already have latitude and longitude calculated. How does the code need to be altered since I have the coordinates? I've attached a sample of my table headers that includes latitude and longitude. To display map, I was hoping to have another element that is only visible when an item is clicked to view more details. The element "get directions" would link to the Google map.
 

Attachments

  • Picture 9.png
    Picture 9.png
    7.5 KB · Views: 297
Untested, but try this for your form JS file:

Code:
function load_map(latlat,latlong) {
  if (GBrowserIsCompatible()) {
    var map = new GMap2(document.getElementById("map"));
    map.addControl(new GSmallMapControl());
    map.addControl(new GMapTypeControl());
    map.setCenter(new GLatLng(latlat,latlong), 13);
    var marker = new GMarker(map.getCenter());
    GEvent.addListener(marker, "click", function() {
      marker.openInfoWindowHtml("<b>GPS Coords</b><br />Lat: " + latlat + "<br />Long: " + latlong);
    });
    map.addOverlay(marker);
    marker.openInfoWindowHtml("<b>GPS Coords</b><br />Lat: " + latlat + "<br />Long: " + latlong);    }
}

... and this for your custom template.php. You'll have to edit this and change the lat and lon element names (very near the top) to your own names.

PHP:
<?php /**
 * @package  fabrik
 * @version 1.0.4
 * @Copyright (C) Rob Clayburn
 * @license GNU/GPL http://www.gnu.org/copyleft/gpl.html
 */
/* MOS Intruder Alerts */
defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );

$lat_element_name = 'jos_fabrik_formdata_40___lat';
$lon_element_name = 'jos_fabrik_formdata_40___lon';

?>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAq-gv5SfH67XHsplhIHIPjxRWgZKhnXaB5STlb57LvQlAVAJYnxRhIjPFR_NuuqSzqGmLP2Oyi_6JNA" type="text/javascript"></script>
<h1><?php echo $this->form->title;?></h1>
<?php echo $this->topJS;
echo $this->form->intro;?>
<?php if( $this->form->error != '' ){
    echo "<div class='fabrikerror'>" . $this->form->error . "</div>";
}?>
<form action="<?php echo $this->form->action;?>" class="fabrikForm" <?php echo $this->form->js;?> method="post" name="<?php echo $this->form->name;?>" id="<?php echo $this->form->name;?>" enctype="<?php echo $this->form->encType;?>">
    <?php if($this->showEmail){
        echo $this->emailLink;
    }?> <?php if($this->showPDF){
        echo $this->pdfLink;
    }?> <?php if($this->showPrint){
        echo $this->printLink;
    }?> <?php
    
    foreach( $this->groups as $group ){?>
    <h3><?php echo $group->title;?></h3>
    <?php if($group->canRepeat && $this->task != 'viewTableRowDetails' ){?>
        <div><a class="addGroup" href="#" id="<?php echo $group->addId;?>"><?php echo _ADD;?></a> | <a class="deleteGroup" href="#" id="<?php echo $group->delId;?>"><?php echo _DELETE;?></a></div>
    <?php }?>
    <div class="fb_group" id="group<?php echo $group->id;?>" style="<?php echo $group->css;?>">
        
        <?php if($group->canRepeat){
            $subgroupCounter = 0;
            foreach($group->subgroups as $subgroup){?>
                <div class="fb_sub_group" id="subgroup<?php echo $group->id . "_" . $subgroupCounter;?>">
                <?php foreach( $subgroup as $element ){?>
                    <div class="<?php echo $element->divclass ?>" id="fb_element_<?php echo $element->int;?>">
                        <?php if($element->error != ''){?>
                            <div class="fabrikerror"><?php echo $element->error;?></div>
                        <?php }?> 
                        <?php echo $element->label;?>
                        <?php echo $element->element;?>
                    </div>
                <?php }?></div>
                <?php $subgroupCounter ++;
            } ?>
        <?php }else{?>
            <?php foreach( $group->elements as $element ){?>
                <div class="<?php echo $element->divclass ?>"  id="fb_element_<?php echo $element->int;?>"><?php if($element->error != ''){?>
                <div class="fabrikerror"><?php echo $element->error;?></div>
                <?php }?> <?php echo $element->label;?> <?php echo $element->element;?>
                </div>
            <?php
                $lattitude = $longitude = '';
                if ($element->id == $lat_element_name) {
                    $lattitude = $element->value;
                }
                else if ($element->id == $lon_element_name) {
                    $longitude = $element->value;
                }
            }
            if (empty($this->form->submitButton))
            {
                if ($lattitude and $longitude) {
                ?>
<script type="text/javascript">
window.addEvent('load', function(){
   load_map(<?php echo $lattitude; ?>, <?php echo $longitude ?>);
});
</script>
    <div id="map" style="width: 500px; height: 300px"></div>
                <?php
                }
            }
            else {
            ?>
<script type="text/javascript">
$('fabrik40').addEvent('submit',function(e){ do_geocode(); });
</script>
            <?php
            }
         }?>
    </div>
<?php
    }
    ?><?php echo $this->hiddenFields;
    echo $this->ask_receipt?>
    <div class="fabrikActions"><?php echo $this->form->resetButton;?> <?php echo $this->form->submitButton;?>
    </div>
</form>
<?php echo $this->jsActions; ?>
<div id="fabrikScroller"></div>

You don't need to do any of the stuff about the Geocode button, just the above two things should do it.

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

No members online now.
Back
Top