FormValidation v0.8.1 is released, supports Bootstrap 4 alpha 3

Playing with geocomplete

Examples

geocomplete is a popular jQuery plugin wrapping Google Maps API's Geocoding and Places Autocomplete services. It allows us to choose an address from autocomplete dropdown list while searching for a location.

The following example demonstrates how to use FormValidation with the geocomplete plugin. It requires user to fill in an address which can be chosen from the autocomplete list. If user enter a straight text that isn't found after looking by the Google Map API's, the address will be treated as invalid one.

You should look at the basic principles when integrating FormValidation with other plugins

A particular address is defined by a latitude and longitude coordinates:

  • Both value must be the number
  • The latitude must be between -90 and 90
  • The longitude must be between -180 and 180

geocomplete provides the ability of populating these coordinates after selecting the address from the list. Then we can use these values to validate the address via the callback validator:

$('#addressForm').formValidation({
    fields: {
        address: {
            trigger: 'blur',
            validators: {
                callback: {
                    callback: function(value, validator, $field) {
                        var lat = $('#addressForm').find('[name="lat"]').val(),
                            lng = $('#addressForm').find('[name="lng"]').val();
                        return $.isNumeric(lat) && $.isNumeric(lng)
                                && (-90 <= lat) && (lat <= 90)
                                && (-180 <= lng) && (lng <= 180);
                    }
                }
            }
        }
    }
});

When user enter a a straight text, we need to reset the latitude, longitude values and mark the field as not validated yet via the updateStatus() method:

$('#addressForm')
    .find('[name="address"]')
        .on('input keyup', function(e) {
            // Reset lat, lng
            $('#addressForm')
                .formValidation('updateStatus', 'address', 'NOT_VALIDATED')
                .find('[name="lat"], [name="lng"]').val('').end();
        });

Below is live demonstration which you can play with:

<!-- Google Place library -->
<script src="//maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>

<!-- Geocomplete plugin -->
<script src="//cdn.jsdelivr.net/jquery.geocomplete/1.6.4/jquery.geocomplete.min.js"></script>

<style type="text/css">
.mapCanvas {
    width: 600px;
    height: 400px;
}
</style>

<form id="addressForm" class="form-horizontal">
    <div class="form-group">
        <label class="col-xs-3 control-label">Address</label>
        <div class="col-xs-5">
            <input type="text" class="form-control" name="address" />
        </div>
    </div>

    <div class="form-group">
        <label class="col-xs-3 control-label">Map</label>
        <div class="col-xs-9">
            <div id="map" class="mapCanvas"></div>
        </div>
    </div>

    <div id="addressDetails" class="hide">
        <input name="lat" type="hidden" class="form-control" />
        <input name="lng" type="hidden" class="form-control" />
    </div>

    <div class="form-group">
        <div class="col-xs-9 col-xs-offset-3">
            <button type="submit" class="btn btn-default">Submit</button>
        </div>
    </div>
</form>

<script>
$(document).ready(function() {
    $('#addressForm')
        .formValidation({
            framework: 'bootstrap',
            icon: {
                valid: 'glyphicon glyphicon-ok',
                invalid: 'glyphicon glyphicon-remove',
                validating: 'glyphicon glyphicon-refresh'
            },
            fields: {
                address: {
                    trigger: 'blur',
                    validators: {
                        notEmpty: {
                            message: 'The address is required'
                        },
                        callback: {
                            message: 'The address is not found',
                            callback: function(value, validator, $field) {
                                var lat = $('#addressForm').find('[name="lat"]').val(),
                                    lng = $('#addressForm').find('[name="lng"]').val();
                                return $.isNumeric(lat) && $.isNumeric(lng)
                                        && (-90 <= lat) && (lat <= 90)
                                        && (-180 <= lng) && (lng <= 180);
                            }
                        }
                    }
                }
            }
        })
        .find('[name="address"]')
            .on('input keyup', function(e) {
                /* Reset lat, lng */
                $('#addressForm')
                    .formValidation('updateStatus', 'address', 'NOT_VALIDATED')
                    .find('[name="lat"], [name="lng"]').val('').end();
            })
            .geocomplete({
                details: '#addressDetails',
                map: '#map',
                blur: false,
                restoreValueAfterBlur: true
            })
            .on('geocode:result', function(e, result) {
                $('#addressForm').formValidation('revalidateField', 'address');
            })
            .on('geocode:error', function(e, result) {
                $('#addressForm').formValidation('revalidateField', 'address');
            })
            .end();
});
</script>