Mapa interactivo con tabla

by Jorgelig

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/less.js/1.7.4/less.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
                    <div id="TableWithZoneStats" class="detailBox" data-bind="with: locationDataTableWithZoneStats" style="display: none;">
                        <div class="map-actions">
                            <i id="map_fullscreen" class="icon icon-fullscreen pull-right" title="@GetText("ViewFullscreen")" data-bind="fullScreen:{targetId: 'map'}"></i>
                        </div>
                        <div id="map" class="gmap" data-bind="mapWithDataTable: { arg: [] }"></div>
                        <div class="data-table" data-bind="visible: similarRealties().length > 0" style="display: none">
                            <div class="data-table-head row-fluid">
                                <div class="span5">@GetText("Key")</div>
                                <div class="span5">@GetText("Price")</div>
                                <div class="span1">m²C</div>
                                <div class="span1">m²T</div>
                            </div>
                            <div id="Realties" class="data-table-body"  data-bind="mCustomScrollbar: { observableArrayName: 'similarRealties' }">
                                <!-- , scrollTo: {containerId: 'Realties', itemId: 'realty-' + id()} -->
                                <div class="data-table-row row-fluid" data-bind="event: { click: selectPoint }, attr: { 'id': 'row-id-' + name }, css: { 'row-highlight': isSelected() }, attr: { 'id': 'realty-' + id() }">
                                    <div class="span5">
                                        <a target="_blank" data-bind="attr: { 'href': url, id: 'realty-code-' + $data.id() }, text: code, realtyPopover: $data.id()" class="popover-realty">-</a>
                                   ...

CSS

.detailBox {
    background-color: @white;
    padding: 15px;
    .border-radius();
    .box-shadow(0 0 1px #aaa);
    margin-bottom: 15px;

    h3 {
        border-bottom: 1px solid @grayLight_ce;
        margin-top: 20px!important;

        &:first-child { margin: 0!important; }
    }

    .map-actions {
        overflow: hidden;
        
        i { margin-bottom: 10px; }
    }

    .gmap {
        height: 300px;

        .marker-price {
            &:before {
                background-color: #5EAB1F;
                border-color: #3A6A13;
                border-style: solid;
                border-width: 0 1px 1px 0;
                content: " ";
                display: inline-block;
                height: 4px;
                left: 22px;
                margin: auto 0;
                position: absolute;
                top: 18px;
                .transform (45deg, 1, 1deg, 0px);
                width: 4px;
            }

            background-color: #5EAB1F;
            border-color: #3A6A13;
            .border-radius(@baseBorderRadius);
            border-style: solid;
            border-width: 1px;
            color: #FFFFFF;
            cursor: pointer;
            font-weight: 600;
            left: -25px;
            line-height: 20px;
            margin-top: -4px;
            padding: 0 3px;
            position: absolute;
            text-align: center;
            top: -24px;
            width: 43px;

            &.sold {
                &:before {
                    background-color: #999999;
                    border-color: @grayDarker_22;
                }
                border-color: @grayDarker_22;
                background-color: #999999;
            }
            &.same{
                &:before{
                    background-color: #F34949;
                    border-color: #B94A48;
                }
                background-color: #F34949;
                border-color: #B94A48;
            }
        }

        .marker-highlight...

JavaScript

ko.bindingHandlers.mapWithDataTable = {
        init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
            var opts = valueAccessor();
            
            viewModel.mapElement(element);
            viewModel.initMap();
        }
    };

var LocationDataTableWithZoneStats = function(realty) {
    var self = this;

    self.map = {};
    self.selectedPoint = null;
    self.realtyMarker = null;
    self.mapElement = ko.observable();
    self.boundMap = ko.observable(new google.maps.LatLngBounds());
    
    
    self.id = ko.observable(realty.id);
    self.latitude = ko.observable(realty.latitude);
    self.longitude = ko.observable(realty.longitude);
    self.location = ko.observable(realty.location);
    self.closedLast12Months = ko.observable('');
    self.interests = ko.observable('');
    self.interestsAverage = ko.observable('');
    self.suggestions = ko.observable('');
    self.demand = ko.observable('');
    self.promotionDays = ko.observable('-');
    self.supply = ko.observable('-');
    self.visits = ko.observable('-');

    //Stats
    
    self.hasLatLong = ko.observable(realty.hasLatLong);
    self.similarRealties = ko.observableArray([]);
    
    self.sortRealties = function () {
        var s = self.similarRealties().sort(function (a, b) {
            return Number(a['price']()) > Number(b['price']()) ? -1 : 1;
        });
        self.similarRealties(s);
    };
    
    self.similarRealtiesIsReady = ko.observable(false);
    self.similarClosedRealtiesIsReady = ko.observable(false);
    self.mapIsReady = ko.computed(function () {
        return self.similarRealtiesIsReady() && self.similarClosedRealtiesIsReady();
    });
    
    self.mapIsReady.subscribe(function (newValue) {
        if (newValue) {
            
        }
    });

    //#region Methods
    self.initRealtyMarker = function () {
        var hasLatLong = (self.latitude() && self.longitude());
        var hasMarkers =...