Google Maps API : Chương 6 – Interface


Css : A Touch Style.
Trong phần này , chúng ta sẽ sử dụng CSS nhúng vào file HTML của chúng ta .

<link href="style.css" rel="stylesheet" type="text/css" />
...
//code
<div id="map"></div>

Và trong file CSS chỉ đơn giản là gọi :

#map {
width: 500px;
height: 400px;
}

Chỉnh kích thước cho map
Chỉ đơn giản là viết trong file CSS

html, body {
margin: 0;
padding: 0;
height: 100%;
}
#map {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}

Adding Hovering Toolbars
Đầu tiên add toolbar :

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"➥
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://maps.google.com/maps?file=api&v=2&key=API_KEY"➥
type="text/javascript"></script>
<script src="map_data.php" type="text/javascript"></script>
<script src="map_functions.js" type="text/javascript"></script>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="map"></div>
<div id="toolbar">
<h1>Cell-Tower Locations</h1>
<ul id="options">
<li><a href="#">Towers</a></li>
<li><a href="#">Poles</a></li>
<li><a href="#">Masts</a></li>
<li><a href="#">Other</a></li>
</ul>
</div>
</body>
</html>

Sau đó add css vào

#toolbar {
position: absolute;
top: 20px;
left: 60px;
width: 400px;
padding: 5px;
background: white;
border: 1px solid black;
}

Exam : http://nippontako.com/chapter6/hoveringToolbar/

Creating Collapsible Side Panels
Tạo side bar bên phải :

<body>
<div id="map-wrapper">
<div id="map"></div>
</div>
<div id="toolbar">
...
</div>
<div id="sidebar">
<p>Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin
accumsan condimentum dolor. Vestibulum ante fabicum...</p>
</div>
</body>

CSS khai báo :

#map-wrapper {
position: relative;
height: 100%;
}
#sidebar {
position: absolute;
top: 0;
width: 300px;
height: 100%;
overflow: auto;
}
body.sidebar-right #map-wrapper { margin-right: 300px; }
body.sidebar-right #sidebar { right: 0; }
body.sidebar-off #map-wrapper { margin: 0; }
body.sidebar-off #sidebar { display: none; }

Exam : http://nippontako.com/chapter6/sidePanel/

Switching Up the Body Classes
Là ta tạo hiệu ứng khi click vào nút hide thì ẩn panel, show thì hiện panel :
Trang body:

<body>

function change :

function changeBodyClass(from, to) {
document.body.className = document.body.className.replace(from, to);
return false;
}

Tạo tool bar :

<div id="toolbar">
...
<ul id="sidebar-controls">
<li><a href="#" id="button-sidebar-hide">Hide</a></li>
<li><a href="#" id="button-sidebar-show">Show</a></li>
</ul>
</div>

gọi function :

document.getElementById('button-sidebar-hide').onclick = function() {➥
return changeBodyClass('sidebar-right', 'sidebar-off'); };
document.getElementById('button-sidebar-show').onclick = function() {➥
return changeBodyClass('sidebar-off', 'sidebar-right'); };

CSS :

body.sidebar-right a#button-sidebar-show { display: none; }
body.sidebar-off a#button-sidebar-hide { display: none; }

Exam : http://nippontako.com/chapter6/sidePanelToggle/

Resizing with the Power of JavaScript
Ta toggle side bar mạnh hơn với javascript và position:behavious :
Function windowHeight:

function windowHeight() {
// Standard browsers (Mozilla, Safari, etc.)
if (self.innerHeight)
return self.innerHeight;
// IE 6
if (document.documentElement && document.documentElement.clientHeight)
return y = document.documentElement.clientHeight;
// IE 5
if (document.body)
return document.body.clientHeight;
// Just in case.
return 0;
}

function handleResize() gọi function trên :

function handleResize() {
var height = windowHeight();
height -= document.getElementById('toolbar').offsetHeight - 30;
document.getElementById('map').style.height = height + 'px';
document.getElementById('sidebar').style.height = height + 'px';
}

Hàm khởi tạo :

function init() {
...
handleResize();
}

Và toolbar bên trang index phải có dạng như vậy :

<body>
<div id="toolbar">
...
</div>
<div id="content">
<div id="map-wrapper">
<div id="map"></div>
</div>
<div id="sidebar">
...
</div>
</div>
</body>

Note : id=sidebar phải nằm trong id=content và sau id=map-wrapper để có thể chạy được .

Exam : http://nippontako.com/chapter6/onResize/

Populating the Side Panel
Side panel hiện tại không đẹp , vì nó show ra tất cả thông tin , khi người dùng click vào marker nào , thì nó cũng không phản ánh, cho nên ta sẽ dùng list để hiện thị tô đen khung, khi người dùng click vào 1 marker nào đó .
Đầu tiên ta khai báo list :

<div id="content">
...
<div id="sidebar">
<ul id="sidebar-list">
</ul>
</div>
</div>

Sau đó trong file data ta khai báo data làm list:

var markers = [
<?php while($row = mysql_fetch_assoc($result)): ?>
<?= $joiner ?>
{
'latitude': <?= $row['latitude'] ?>,
'longitude': <?= $row['longitude'] ?>,
'address': '<?= addslashes($row['struc_address']) ?>',
'city': '<?= addslashes($row['struc_city']) ?>',
'state': '<?= addslashes($row['struc_state']) ?>',
'height': '<?= addslashes($row['struc_height']) ?>',
'elevation': '<?= addslashes($row['struc_elevation']) ?>',
'type': '<?= addslashes($row['struc_type']) ?>',
'owner': '<?= addslashes($row['owner_name']) ?>'
}
<?
$joiner = ',';
$count++;
?>
<?php endwhile; ?>
];

Và bây giờ, ta sẽ dùng PHPDOM để lấy dữ liệu ra , đưa vào trong list , đồng thời dùng hàm focusPoint để trỏ tới khi list được click :

function initializePoint(pointData) {
var point = new GPoint(pointData.longitude, pointData.latitude);
var marker = new GMarker(point);
var listItem = document.createElement('li');
var listItemLink = listItem.appendChild(document.createElement('a'));
listItemLink.href = "#";
listItemLink.innerHTML = '<strong>' + pointData.address + ' </strong><span>' +➥
pointData.city + ', ' + pointData.state + ' (' + pointData.height + 'm)</span>';
var focusPoint = function() {
marker.openInfoWindowHtml(pointData.address);
map.panTo(point);
return false;
}
GEvent.addListener(marker, 'click', focusPoint);
listItemLink.onclick = focusPoint;
document.getElementById('sidebar-list').appendChild(listItem);
map.addOverlay(marker);
}
...
function init() {
...
for(id in markers) {
initializePoint(markers[id]);
}
handleResize();
}

Exam : http://nippontako.com/chapter6/sidePanelData/

Getting Side Panel Feedback
Trong code trên , thì user có thể tương tác với list Item và marker . Nhưng chỉ có khi click vào panel thì marker hiện , còn khi click vào marker thì item không hiện gì .

Để hiện ra highlight trên site panel thì dễ quá , nhưng vấn đề là , khi click lần đầu , it’s mean : “highlight me” , còn click lần khác thì “highlight me and unhighlight the previous selection! ” . Cho nên code sau , chúng ta cần chú ý tới điểm này :

var deselectCurrent = function() {}; // Empty function
function initializePoint(pointData) {
var point = new GPoint(pointData.longitude, pointData.latitude);
var marker = new GMarker(point);
var listItem = document.createElement('li');
var listItemLink = listItem.appendChild(document.createElement('a'));
listItemLink.href = "#";
listItemLink.innerHTML = '<strong>' + pointData.address + ' </strong><span>' +➥
pointData.city + ', ' + pointData.state + ' (' + pointData.height + 'm)</span>';
var focusPoint = function() {
deselectCurrent();
listItem.className = 'current';
deselectCurrent = function() { listItem.className = ''; }
marker.openInfoWindowHtml(pointData.address);
map.panTo(point);
return false;
}
GEvent.addListener(marker, 'click', focusPoint);
listItemLink.onclick = focusPoint;
document.getElementById('sidebar-list').appendChild(listItem);
map.addOverlay(marker);
}

Trong code trên , chú ý dòng

deselectCurrent();
listItem.className = 'current';
deselectCurrent = function() { listItem.className = ''; }

var deselectCurrent = function() {}; // Empty function

Lần đầu tiên chạy, ta gọi hàm deselectCurrent và nó sẽ không làm gì cả , và gán

listItem.className = 'current';

trong lần gọi tiếp theo , thì nó sẽ gọi hàm deselectCurrent lần nữa, nhưng lần này nó có giá trị là :

deselectCurrent = function() { listItem.className = ''; }

Có nghĩa là xóa đi previoust selection, và tiếp theo , nó gán listItem.className = ‘current’;
Tiếp tục, khi gọi deselectCurrent nó sẽ xóa previous selection và gán listItem.className = ‘current’; …

Exam : http://nippontako.com/chapter6/sidePanelDataBetter/

Làm loading cho site
Dĩ nhiên để tránh cho người dùng chờ đợi ta phải tạo thanh loading cho site :
Đầu tiên khai báo trong file index.php

<body>
<div id="toolbar">
...</div>
<div id="content">
<div id="map-wrapper">
<div id="map"></div>
</div>
<div id="sidebar">
...
</div>
<div id="alert">
<p>Loading data ...</p>
</div>
</div>
</body>

Sau đó khai báo trong css :

#alert {
position: absolute;
top: 50%;
left: 0;
width: 100%;
text-align: center;
display: none;
}
#alert p {
width: 150px;
margin: 0 auto 0 auto;
padding: 10px;
background: white;
border: 1px solid #aaa;
}
body.loading #alert { display: block; }

Mới đầu vào , loading sẽ hiện ra , và khi load xong thì chữ “loading” sẽ mất đi, để làm mất thanh loading ta dùng hàm sau :

function init() {
...
changeBodyClass('loading', 'standby');
}

Hàm này sẽ gọi hàm changeBodyClass mà ta đã khai báo trước đó .

Exam : http://nippontako.com/chapter6/nowLoading/

Thao tác với hộp lọc category(Data Point Filtering)
Hiện lên index.

<div id="toolbar">
<h1>Cell-Tower Locations</h1>
<ul id="filters">
</ul>
<ul id="sidebar-controls">
<li><a href="#" id="button-sidebar-hide">hide</a></li>
<li><a href="#" id="button-sidebar-show">show</a></li>
</ul>
</div>

Ở đây , ta có 3 nhiệm vụ chính :
-Sử dụng kĩ thuật để show và hide điểm đích .
-Tìm ra nhóm(category) cần sử dụng trong database.
-Tạo hàm để ẩn tất cả các list thừa .
NV1 :

function initializePoint(pointData) {
var visible = false;
...
GEvent.addListener(marker, 'click', focusPoint);
listItemLink.onclick = focusPoint;
pointData.show = function() {
if (!visible) {
document.getElementById('sidebar-list').appendChild(listItem);
map.addOverlay(marker);
visible = true;
}
}
pointData.hide = function() {
if (visible) {
document.getElementById('sidebar-list').removeChild(listItem);
map.removeOverlay(marker);
visible = false;
}
}
pointData.show();
}

Tức là lần đầu tiên chạy nó sẽ gọi hàm show , và show ra tất cả các điểm .
NV2 :

function init() {
var type;
var allTypes = { 'All':[] };
...
for(id in markers) {
initializePoint(markers[id]);
allTypes[markers[id].type] = true;
}
for(type in allTypes)
{
initializeSortTab(type);
}
handleResize();
changeBodyClass('loading', 'standby');
}

Khởi tạo này có nhiệm vụ điều hướng .
Cuối cùng , ta xem hàm xử lý sortTab:

function initializeSortTab(type) {
var listItem = document.createElement('li');
var listItemLink = listItem.appendChild(document.createElement('a'));
listItemLink.href = "#";
listItemLink.innerHTML = type;
listItemLink.onclick = function() {
changeBodyClass('standby', 'loading');
for(id in markers) {
if (markers[id].type == type || 'All' == type) {
markers[id].show();
} else {
markers[id].hide();
}
}
changeBodyClass('loading', 'standby');
return false;
}
document.getElementById('filters').appendChild(listItem);
}

Exam : http://nippontako.com/chapter6/dataFiltering/

Advertisements
%d bloggers like this: