I'm new to GCM / Java, I'm experienced in php, but only mysql.
I found this tutorial:
http://www.androidhive.info/2012/10/android-push-notifications-using-google-cloud-messaging-gcm-php-and-mysql/
It was very useful, and I got it to work. My only problem is that this code is for sending to one device at a time.
I tryed to edit it so it sends to multiple devices using one form & one submit button, but without a success.
This code gets from Java (Client) Info and puts it in a mysql database using php (Server).
It also registers the GCM registration id of the device in the mysql DB,
and than you can send notifications by id to the device using the id's GCM reg id.
Here is the index.php where you fill in the form:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
});
function sendPushNotification(id){
var data = $('form#'+id).serialize();
$('form#'+id).unbind('submit');
$.ajax({
url: "send_message.php",
type: 'GET',
data: data,
beforeSend: function() {
},
success: function(data, textStatus, xhr) {
$('.txt_message').val("");
},
error: function(xhr, textStatus, errorThrown) {
}
});
return false;
}
</script>
<style type="text/css">
.container{
width: 950px;
margin: 0 auto;
padding: 0;
}
h1{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 24px;
color: #777;
}
div.clear{
clear: both;
}
ul.devices{
margin: 0;
padding: 0;
}
ul.devices li{
float: left;
list-style: none;
border: 1px solid #dedede;
padding: 10px;
margin: 0 15px 25px 0;
border-radius: 3px;
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.35);
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: #555;
}
ul.devices li label, ul.devices li span{
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 12px;
font-style: normal;
font-variant: normal;
font-weight: bold;
color: #393939;
display: block;
float: left;
}
ul.devices li label{
height: 25px;
width: 50px;
}
ul.devices li textarea{
float: left;
resize: none;
}
ul.devices li .send_btn{
background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
background: -webkit-linear-gradient(0% 0%, 0% 100%, from(#0096FF), to(#005DFF));
background: -moz-linear-gradient(center top, #0096FF, #005DFF);
background: linear-gradient(#0096FF, #005DFF);
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
border-radius: 3px;
color: #fff;
}
</style>
</head>
<body>
<?php
include_once 'db_functions.php';
$db = new DB_Functions();
$users = $db->getAllUsers();
if ($users != false)
$no_of_users = mysql_num_rows($users);
else
$no_of_users = 0;
?>
<div class="container">
<h1>No of Devices Registered: <?php echo $no_of_users; ?></h1>
<hr/>
<ul class="devices">
<?php
if ($no_of_users > 0) {
?>
<?php
while ($row = mysql_fetch_array($users)) {
?>
<li>
<form id="<?php echo $row["id"] ?>" name="" method="post" onsubmit="return sendPushNotification('<?php echo $row["id"] ?>')">
<label>Name: </label> <span><?php echo $row["name"] ?></span>
<div class="clear"></div>
<label>Email:</label> <span><?php echo $row["klas"] ?></span>
<div class="clear"></div>
<div class="send_container">
<textarea rows="3" name="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
<input type="hidden" name="regId" value="<?php echo $row["gcm_regid"] ?>"/>
<input type="submit" class="send_btn" value="Send" onclick=""/>
</div>
</form>
</li>
<?php }
} else { ?>
<li>
No Users Registered Yet!
</li>
<?php } ?>
</ul>
</div>
</body>
</html>
It's using ajax to send it to GCM:
Send_message.php:
<?php
if (isset($_GET['regId']) && (isset($_GET["message"]))) {
$regId = $_GET['regId'];
$message = $_GET["message"];
include_once './GCM.php';
$gcm = new GCM();
$registatoin_ids = array($regId);
$message = array("price" => $message);
$result = $gcm->send_notification($registatoin_ids, $message);
echo $result;
}
?>
As you see, it gets everthing by id,
but I want to use one form, one submit button & one text field to send to multiple devices.
Would really appreciate it if someone could instruct me how to do it or give me some examples.
I don't know php, but GCM.php from the link you provided seems to already support sending push notifications to multiple devices :
public function send_notification($registatoin_ids, $message) {
// include config
include_once './config.php';
// Set POST variables
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
'registration_ids' => $registatoin_ids,
'data' => $message,
);
You should simply pass to the send_notification function an array that contains multiple Registration IDs, and it would send notifications to all of them.
Related
The program I have made contains only one search bar, so I can't filter more accurate or related tables.
I need one more search bar in order to enter the value in two search field by clicking post it will search from database and get most related once.
<?php
if(isset($_POST['search']))
{
$valueToSearch = $_POST['valueToSearch'];
// search in all table columns
// using concat mysql function
$query = "SELECT * FROM `included` WHERE CONCAT(`id`, `a`, `b`,
`c`,`c`,`d`,`e`,`f`,`g`,`h`,`i`) LIKE '%".$valueToSearch."%'";
$search_result = filterTable($query);
}
else {
$query = "SELECT * FROM `included`";
$search_result = filterTable($query);
}
// function to connect and execute the query
function filterTable($query)
{
$connect = mysqli_connect("localhost", "root", "", "hospitaldata");
$filter_Result = mysqli_query($connect, $query);
return $filter_Result;
}
?>
<!DOCTYPE html>
<html>
<head>
<img src="nop.jpg">
<title>PHP HTML TABLE DATA SEARCH</title>
<style>
table,tr,th,td{
border:.3px solid blue;
color:#000;
font-family:sans-serif;
}
div.relative {
position: relative;
top: -50px;
width: 1400px;
height: 100px;
color: #0C3;
font-family: "Arial Black", Gadget, sans-serif;
font-size: 24px;
}
div.absolute {
position: absolute;
top: 51px;
right: 20;
width: 1261px;
height: 40px;
color: #999;
font-family: Verdana, Geneva, sans-serif;
left: 65px;
}
input[type=text] {
alignment-baseline:central;
width: 130px;
box-sizing: border-box;
border: 2px solid #ccc;
border-radius: 4px;
font-size: 16px;
background-color: white;
background-image:url('ds.jpg');
padding: 12px 20px 12px 40px;
-webkit-transition: width 0.4s ease-in-out;
transition: width 0.4s ease-in-out;
}
input[type=text]:focus {
width: 50%;
}
table,tr,th,tr
{
border:1px solid blue;
}
</style>
</style>
</head>
<body>
<div class="relative"><h1 align="center">HOSPITAL</h1>
<div class="absolute" align="center">Check provided points here</div>
</div>
<form action="index.php" method="post">
<input type="text" name="valueToSearch" placeholder="Search..."><br>
<input type="submit" name="search" value=">>"><br><br>
<table>
<tr>
<th>Building</th>
<th>Floor</th>
<th>zone</th>
<th>Room no</th>
<th>Room Type</th>
<th>Room Name</th>
<th>Types of Connection</th>
<th>Suggested</th>
<th>Provided</th>
</tr>
<!-- populate table from mysql database -->
<?php while($row = mysqli_fetch_array($search_result)):?>
<tr>
<td><?php echo $row['a'];?></td>
<td><?php echo $row['b'];?></td>
<td><?php echo $row['c'];?></td>
<td><?php echo $row['d'];?></td>
<td><?php echo $row['e'];?></td>
<td><?php echo $row['f'];?></td>
<td><?php echo $row['g'];?></td>
<td><?php echo $row['h'];?></td>
<td><?php echo $row['i'];?></td>
</tr>
<?php endwhile;?>
</table>
</form>
</body>
</html>
From your comments I understand the following:
you have a webpage with a search input field
you want a second input so your users can search more presice
one serach button should send both input fields
A really plain (and untested) version could look like this:
<form action="search.php" method="post">
<label><input name="search1"/> First keyword</label>
<label><input name="search2"/> Second keyword</label>
<input type="submit" value="Serach"/>
</form>
<?php
// If the Search button was pressed
if(isset($_POST['search1'])) {
$stmt = $pdo->prepare($query = "SELECT * FROM `included` WHERE CONCAT(`id`, `a`, `b`, `c`) LIKE '%:search1%' OR CONCAT(`d`, `e`) LIKE '%:search2%'");
$stmt->execute(['search1' => $POST['search1'], 'search2' => $POST['search2'] :? 'default');
foreach ($stmt as $row) {
// do something with $row
}
}
Of course you have to fit the SQL statement to your needs.
For infos about how to setup the $pdo database connection, please refer to the link: http://stackoverflow.com/a/60496/1152471
EDIT:
I think I found the problem, I test the application in a window with java 7 and runs fine, no weird symbols and run the application on two different macs with java 8 and fail. I don't believe is the version because java it's supposed to run on any platform equally any theory.
RE:EDIT:
Is the OS!!!!! I just check, in a Windows with java 8 and worked, has to do with the encoding what can I do?? :'(. (I use macOS)
Maybe is only the JavaFX version and could save an old version of JavaFX in the app but don't know how to do that help, please.
END EDIT
I've made a desktop java application using WebView in JavaFX and make my own HTML page and everything worked fine, but suddenly the characters fails and I don't think is the HTML because I put an H1 and look fine but the google maps don't.
The HTML works fine in a browser but fails in java!.
Also, I erase the cookies.
Here is a screenshot
Here is the HTML most copy paste from google api:
<!DOCTYPE html>
<html>
<head>
<meta >
<title> "Vista de Clientes" </title>
<style>
#map {
height: 100%;
}
html, body {
font-family: sans-serif;
height: 100%;
margin: 0;
padding: 0;
}
.controls {
margin-top: 10px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
margin-left: 12px;
padding: 0 11px 0 13px;
text-overflow: ellipsis;
width: 300px;
}
#pac-input:focus {
border-color: #4d90fe;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
#target {
width: 345px;
}
</style>
</head>
<body>
<input id="pac-input" class="controls" type="text" placeholder="Search Box">
<h1> hola </h1>
<div id="map"></div>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=APIKEYISGOOD&libraries=places"></script>
<script>
// object for the stores
var GreenCircle = {
path: google.maps.SymbolPath.CIRCLE,
fillColor: 'Lime',
fillOpacity: 1,
scale: 10,
strokeColor: 'green',
strokeWeight: 1
};
// google map instance
var map;
var markers = [];
// function for the initialization
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
zoom: 12,
center: {lat: 21.8857199, lng: -102.3613399}
});
var input = document.getElementById('pac-input');
var searchBox = new google.maps.places.SearchBox(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
// Bias the SearchBox results towards current map's viewport.
map.addListener('bounds_changed', function() {
searchBox.setBounds(map.getBounds());
});
searchBox.addListener('places_changed', function() {
var places = searchBox.getPlaces();
if (places.length == 0) {
return;
}
// Clear out the old markers.
markers.forEach(function(marker) {
marker.setMap(null);
});
markers = [];
// For each place, get the icon, name and location.
var bounds = new google.maps.LatLngBounds();
places.forEach(function(place) {
if (!place.geometry) {
console.log("Returned place contains no geometry");
return;
}
var icon = {
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(25, 25)
};
// Create a marker for each place.
markers.push(new google.maps.Marker({
map: map,
icon: icon,
title: place.name,
position: place.geometry.location,
draggable: true
}));
if (place.geometry.viewport) {
// Only geocodes have viewport.
bounds.union(place.geometry.viewport);
} else {
bounds.extend(place.geometry.location);
}
});
map.fitBounds(bounds);
});
}
initMap();
function setMarker(latvar, lngvar, labels){
var marker = new google.maps.Marker({
position: { lat: latvar, lng: lngvar},
map: map,
label: labels || "",
tittle: labels,
icon: GreenCircle
});
}
function setSelfMarker(Geojson)
{
map.data.addGeoJson( JSON.parse(Geojson) );
}
function setPosition(lat, lng)
{
map.setCenter(new google.maps.LatLng( lat, lng ) );
}
</script>
</body>
</html>
I load the code using:
String webPage = this.getFileSrc("VistaClientes.html");
webEngine.loadContent( webPage);
Is a string containing the full html.
The problem here is that there is a bug in the JavaFX webview on Mac. It tries to load some fonts locally and is disallowed. You can workaround this for Google maps by adding the following CSS directive to your <style> tag.
.gm-style-mtc > div, .gm-style > div, .gm-style-cc > div, .gm-style {font-family:sans-serif !important;}
I sent Email by Apache Commons Email lib.
but "url in img" and "id in div" were removed in my email received.
Why remove Html tag information ?
How can i maintain html tag ?
Java code :
HtmlEmail htmlEmail = new HtmlEmail();
htmlEmail.setCharset(StandardCharsets.UTF_8.displayName());
htmlEmail.setHostName(smtpSetting.getHostname());
htmlEmail.setSmtpPort(smtpSetting.getPort());
htmlEmail.setSSLCheckServerIdentity(true);
htmlEmail.setSSLOnConnect(true);
String smtpUser = smtpSetting.getUserId();
String smtpPassword = encryption.decryptString(smtpSetting.getPassword());
htmlEmail.setAuthenticator(new DefaultAuthenticator(smtpUser, smtpPassword));
htmlEmail.setFrom(smtpSetting.getUserId(), smtpSetting.getUserId());
htmlEmail.addTo(to);
htmlEmail.setSubject(subject);
htmlEmail.setHtmlMsg(content);
htmlEmail.send();
Html:
<div style="min-width:614px; min-height:381px">
<div style="position:absolute; top:0; bottom:0; left:0; right:0; margin:auto; width : 614px; height: 381px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; background:#ffffff; -webkit-box-shadow: 0 1px 2px 0 #bababa; -moz-box-shadow: 0 1px 2px 0 #bababa; box-shadow: 0 1px 2px 0 #bababa; overflow:hidden;">
<div style="background:#2c3a3d; width:614px; height:62px;">
<img
url="localhost:9000/assets/images/logo_type1.png" style="display:inline-block; margin-top:15px; margin-left:23px; width:130px; height:32px; no-repeat center;"/>
</div>
Received Html:
<div style="min-width:614px; min-height:381px">
<div id="email-content-popup-box" style="position:absolute; top:0; bottom:0; left:0; right:0; margin:auto; width : 614px; height: 381px;>
<img/>
</div>
Before:
After
The first image is of the login page, but when I click login button the navigation bar becomes like the second picture, spaces appear between the blocks. This happens when a sevlet is called and has this code:
out.print("<p style='position:absolute;top:200px;left:300px;color:#CC0066;'>Sorry username or password error! </p>");
RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
rd.include(request, response);
The CSS code is:
#menuli{
display: inline;
float: left;
color: #CCCCCC;
}
#menuA,#menuAL {
display: block;
width: 180px;
padding: 10px;
color: #FFFFFF;
font-size: x-large;
font-variant: normal;
font-family: Segoe, "Segoe UI", "DejaVu Sans", "Trebuchet MS", Verdana, sans-serif;
margin: 10;
text-decoration: none;
opacity: 0.9;
border-spacing:0;
border-collapse:collapse;
text-align: center;
background-color: #000033;
/*font-weight: bold;
/*border-radius: 20px;*/
}
#menuA:hover, #menuAL:hover
{
/*color: #699;*/
background-color: #003;
/*text-shadow: 10px 0px 10px; */
font-weight: bold;
background-image: -webkit-gradient(linear, 50.00% 0.00%, 50.00% 100.00%, color-stop( 0% , rgba(65,62,110,1.00)),color-stop( 40.94% , rgba(7,5,53,1.00)),color-stop( 49.74% , rgba(9,8,56,1.00)),color-stop( 100% , rgba(12,11,60,1.00)),color-stop( 100% , rgba(54,56,116,1.00)));
background-image: -webkit-linear-gradient(270deg,rgba(65,62,110,1.00) 0%,rgba(7,5,53,1.00) 40.94%,rgba(9,8,56,1.00) 49.74%,rgba(12,11,60,1.00) 100%,rgba(54,56,116,1.00) 100%);
background-image: linear-gradient(180deg,rgba(65,62,110,1.00) 0%,rgba(7,5,53,1.00) 40.94%,rgba(9,8,56,1.00) 49.74%,rgba(12,11,60,1.00) 100%,rgba(54,56,116,1.00) 100%);
}
#menu
{
position: absolute;
top: 126px;
left: 139px;
}
The JSP code is:
<div name="header" id="header">
<img id="logo" style="position:absolute; left:145px; top:10px; "src="images/logo.jpg">
<div id="menu" >
<ul>
<li id="menuli"><a id="menuA" href="index.jsp#header">Home</a></li>
<li id="menuli"><a id="menuA" href="index.jsp#services">Services</a></li>
<li id="menuli"><a class="prod" id="menuA" href="Display?course=6">Products</a>
</li>
<li id="menuli"><a id="menuA" href="index.jsp#contact">Contact</a></li>
<li id="menuli"><a id="menuA" href="index.jsp#about">About</a></li>
</ul>
</div>
</div>
It's happening with all the pages after any servlet includes it.
Please see the links for images.
Printing the html content inside servlet is considered as bad practice . you can rather set the attribute in the request . so instead of this ,
out.print("<p style='position:absolute;top:200px;left:300px;color:#CC0066;'>Sorry username or password error! </p>");
RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
rd.include(request, response);
use,
request.setAttribute("message","Sorry username or password error!");
RequestDispatcher rd=request.getRequestDispatcher("login.jsp");
rd.include(request, response);
And try to print the message in the jsp page,
simply using the scriptlet as ,
<p style='position:absolute;top:200px;left:300px;color:#CC0066;'><%=message></p>
or using EL
<p style='position:absolute;top:200px;left:300px;color:#CC0066;'>${message}</p>
using scriptlets are also considered to be bad practices since a decade . see this How to avoid java codes inside jsp
Hope this helps !!
Got it fixed. I had margin:10px in the CSS part of the navigation bar. Removed it and the problems are all gone.
:)
I have to add country, state, city,and remaining address if it contains. But I'm not proficient in using Google API along with JavaScript. I'm using ready made JavaScript function which gives full address on textbox after using autocomplete.
I don't know how to take or extract the country, state, city from full address.
I am giving my code:
<!DOCTYPE html>
<html>
<head>
<title>Place Autocomplete</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
.controls {
margin-top: 16px;
border: 1px solid transparent;
border-radius: 2px 0 0 2px;
box-sizing: border-box;
-moz-box-sizing: border-box;
height: 32px;
outline: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
}
#pac-input {
background-color: #fff;
padding: 0 11px 0 13px;
width: 400px;
font-family: Roboto;
font-size: 15px;
font-weight: 300;
text-overflow: ellipsis;
}
#pac-input:focus {
border-color: #4d90fe;
margin-left: -1px;
padding-left: 14px; /* Regular padding-left + 1. */
width: 401px;
}
.pac-container {
font-family: Roboto;
}
#type-selector {
color: #fff;
background-color: #4d90fe;
padding: 5px 11px 0px 11px;
}
#type-selector label {
font-family: Roboto;
font-size: 13px;
font-weight: 300;
}
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=places"></script>
<script>
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-33.8688, 151.2195),
zoom: 13
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var input = /** #type {HTMLInputElement} */(
document.getElementById('pac-input'));
var types = document.getElementById('type-selector');
map.controls[google.maps.ControlPosition.TOP_LEFT].push(input);
map.controls[google.maps.ControlPosition.TOP_LEFT].push(types);
var autocomplete = new google.maps.places.Autocomplete(input);
autocomplete.bindTo('bounds', map);
var infowindow = new google.maps.InfoWindow();
var marker = new google.maps.Marker({
map: map,
anchorPoint: new google.maps.Point(0, -29)
});
google.maps.event.addListener(autocomplete, 'place_changed', function() {
infowindow.close();
marker.setVisible(false);
var place = autocomplete.getPlace();
if (!place.geometry) {
return;
}
// If the place has a geometry, then present it on a map.
if (place.geometry.viewport) {
map.fitBounds(place.geometry.viewport);
} else {
map.setCenter(place.geometry.location);
map.setZoom(17); // Why 17? Because it looks good.
}
marker.setIcon(/** #type {google.maps.Icon} */({
url: place.icon,
size: new google.maps.Size(71, 71),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(17, 34),
scaledSize: new google.maps.Size(35, 35)
}));
marker.setPosition(place.geometry.location);
marker.setVisible(true);
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
infowindow.setContent('<div><strong>' + place.name + '</strong><br>' + address);
// alert("here is your addresss :" address);
infowindow.open(map, marker);
});
// Sets a listener on a radio button to change the filter type on Places
// Autocomplete.
function setupClickListener(id, types) {
var radioButton = document.getElementById(id);
google.maps.event.addDomListener(radioButton, 'click', function() {
autocomplete.setTypes(types);
});
}
setupClickListener('changetype-all', []);
setupClickListener('changetype-establishment', ['establishment']);
setupClickListener('changetype-geocode', ['geocode']);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<input id="pac-input" class="controls" type="text"
placeholder="Enter a location">
<div id="type-selector" class="controls">
<input type="radio" name="type" id="changetype-all" checked="checked">
<label for="changetype-all">All</label>
<input type="radio" name="type" id="changetype-establishment">
<label for="changetype-establishment">Establishments</label>
<input type="radio" name="type" id="changetype-geocode">
<label for="changetype-geocode">Geocodes</label>
</div>
<div id="map-canvas"></div>
</body>
</html>
Thanks for giving reply. From this output on search locality I want to extract individual county ,state,city and locality and use in Spring MVC class pojo.
Below is the section of code (from what you gave) that you should be interested in.
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
}
Essentially, what this part does, is it initializes the address variable (empty initially). Then, if the place object (presumably returned from Google) is not empty and contains components, if fills the address with all the separate components from place.
The above code implies that the place object returned by Google provides you with three (3) components specifically: those at index positions 0, 1, and 2.
You will have to figure out if these components, on their own, give you the separated information you need. To check that, try updating with the following code (notice the FOR loop I added):
var address = '';
if (place.address_components) {
address = [
(place.address_components[0] && place.address_components[0].short_name || ''),
(place.address_components[1] && place.address_components[1].short_name || ''),
(place.address_components[2] && place.address_components[2].short_name || '')
].join(' ');
for (var i = 0; i < place.address_components.length; i++)
{
console.log('Component at index ' + i
+ ' is: ' + place.address_components[i].short_name;
}
}
Run the updated code and check your console (available with Chrome) -- it will let you know which components were returned by Google, with their index number. Use that knowledge to achieve your goal.