mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
719 lines
32 KiB
HTML
719 lines
32 KiB
HTML
<!DOCTYPE html>
|
|
<html manifest="appcache-features.appcache">
|
|
<!--<html>-->
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
|
|
on iOS devices-->
|
|
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
|
|
|
|
<!--
|
|
|
|
This sample demonstrates using an application manifest to store features and tiles locally with a custom-built
|
|
editor widget. If you are planning on using one of Esri's pre-built widgets such as the AttributeInspector
|
|
then you'll need to use a different pattern for reconstituting the feature layer. See the How-To for more details:
|
|
https://github.com/Esri/offline-editor-js/blob/master/doc/howtouseeditlibrary.md
|
|
|
|
The use cases for using this sample are to ensure you can reload and restart you application
|
|
while it is offline and then continue working.
|
|
|
|
It is strongly recommended that you use your own optimized build of the ArcGIS API for JavaScript
|
|
using the Web Optimizer: http://jso.arcgis.com/. You can reference the CDN or host it on your
|
|
own web server.
|
|
|
|
Here is the list of contents for the optimized ArcGIS JS API file used in this sample app:
|
|
https://github.com/Esri/offline-editor-js/issues/284
|
|
|
|
Use the Grunt task in the /samples directory to help generate the manifest file. There is manual
|
|
work involved in determining which files need to go into the manifest. The included manifest
|
|
file should work with this sample to give you an idea of what goes into the manifest.
|
|
|
|
A few things to know about manifest files:
|
|
- You cannot load an online url that has a redirect.
|
|
- If there is an error encountered, the manifest file will stop loading
|
|
- The /utils/appCacheManager.js library will auto detect if the manifest changed and
|
|
ask if you want to reload the application.
|
|
|
|
HINT: When testing be sure you allow for browser caching. If you are using Chrome make sure you have NOT
|
|
checked Network Tab > Disable cache.
|
|
|
|
-->
|
|
|
|
<title>AppCache Tiles and Features</title>
|
|
|
|
<!-- Bootstrap core CSS -->
|
|
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
|
|
<link rel="stylesheet" href="../samples/widgets/modal/css/modal-popup.css">
|
|
<link rel="stylesheet" href="//js.arcgis.com/3.14/dijit/themes/claro/claro.css">
|
|
<link rel="stylesheet" href="//js.arcgis.com/3.14/esri/css/esri.css">
|
|
<link rel="stylesheet" href="//esri.github.io/bootstrap-map-js/src/css/bootstrapmap.css">
|
|
|
|
<script>
|
|
// DO NOT DELETE!
|
|
// Listen for application cache update events
|
|
// We want to place this as early in the application life-cycle as possible!
|
|
window.addEventListener('load', function(evt) {
|
|
|
|
window.applicationCache.addEventListener('updateready', function(evt) {
|
|
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
|
|
// Browser downloaded a new app cache.
|
|
if (confirm('A new version of this cache is available.')) {
|
|
window.location.reload();
|
|
console.log("App cache reloaded");
|
|
}
|
|
} else {
|
|
// Manifest didn't changed. Nothing new to server.
|
|
console.log("App cache no change");
|
|
}
|
|
}, false);
|
|
|
|
}, false);
|
|
|
|
// Reserved for debugging on Safari desktop and mobile
|
|
// Uncomment when doing any debugging on Safari 8 (or previous versions that support App Cache).
|
|
// To delete the application cache file on Safari refer to the following url then close/restart browser:
|
|
// http://stackoverflow.com/questions/5615266/how-do-you-clear-the-offline-cache-for-web-apps-in-safari
|
|
// function logEvent(event) {
|
|
// console.log("Checking for Application Cache Event: " + event.type);
|
|
// }
|
|
//
|
|
// window.applicationCache.addEventListener('checking',logEvent,false);
|
|
// window.applicationCache.addEventListener('noupdate',logEvent,false);
|
|
// window.applicationCache.addEventListener('downloading',logEvent,false);
|
|
// window.applicationCache.addEventListener('cached',logEvent,false);
|
|
// window.applicationCache.addEventListener('updateready',logEvent,false);
|
|
// window.applicationCache.addEventListener('obsolete',logEvent,false);
|
|
//
|
|
// // If you need to catch AppCache errors as early as possible to troubleshoot errors.
|
|
// // You should delete this for production use.
|
|
// window.applicationCache.addEventListener("error",function(err){
|
|
// console.log("ApplicationCache listener: " + err.toString() + ", " + JSON.stringify(err));
|
|
// if (confirm('There was a problem setting this app up for offline. Reload?')) {
|
|
// window.location.reload();
|
|
// console.log("App cache reloaded");
|
|
// }
|
|
// },false);
|
|
</script>
|
|
|
|
<style>
|
|
#mapDiv {
|
|
min-height: 400px;
|
|
max-height: 1000px;
|
|
}
|
|
|
|
body {
|
|
background-color: #ffffff;
|
|
overflow: hidden;
|
|
font-family: "Trebuchet MS";
|
|
}
|
|
|
|
.floatRight { float: right;}
|
|
.container { padding: 20px; width: 100%;}
|
|
</style>
|
|
|
|
<script src="//github.hubspot.com/offline/offline.min.js"></script>
|
|
<script>
|
|
// This options sets up an image that the offline status detection library
|
|
// will use to ping to see if app is online or offline.
|
|
Offline.options = {
|
|
checks: {
|
|
image: {
|
|
url: function() {
|
|
return 'http://esri.github.io/offline-editor-js/tiny-image.png?_=' + (Math.floor(Math.random() * 1000000000));
|
|
}
|
|
},
|
|
active: 'image'
|
|
}
|
|
}
|
|
|
|
var locationPath = location.pathname.replace(/\/[^/]+$/, "");
|
|
var dojoConfig = {
|
|
paths: {
|
|
vendor: locationPath + "/../vendor",
|
|
utils: locationPath + "/../utils",
|
|
widgets: locationPath + "/widgets"
|
|
}
|
|
}
|
|
</script>
|
|
<!--
|
|
Include a reference to IndexedDBShim for library to work on Safari 7.x.
|
|
May not be required for all Safari browsers.
|
|
-->
|
|
<!--<script src="//nparashuram.com/IndexedDBShim/dist/indexeddbshim.min.js"></script>-->
|
|
|
|
<!--
|
|
This is a locally hosted optimized build of the ArcGIS JS API.
|
|
The optimizer creates a single JavaScript file that you can host yourself.
|
|
To create your own optimized build go to: http://http://jso.arcgis.com/
|
|
-->
|
|
<script src="../samples/jsolib/dojo.js" data-dojo-config="async: true"></script>
|
|
</head>
|
|
<body>
|
|
|
|
<!-- Our buttons and online/offline indicator -->
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-xs-10">
|
|
<div class="form form-group btn-group" data-toggle="buttons">
|
|
<button class="btn btn-primary" id="btn-get-tiles">1. Download Tiles</button>
|
|
<button class="btn btn-primary" id="btn-online-offline">2. Go Offline</button>
|
|
</div>
|
|
</div>
|
|
<div class="col-xs-2">
|
|
<!-- this indicates whether app is offline (down) or online (up) -->
|
|
<button id="btn-state" class="btn btn-success btn-large floatRight">
|
|
<span id="state-span" class="glyphicon glyphicon-link"> Up</span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-xs-12">
|
|
<div id="mapDiv"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
require(["esri/map",
|
|
"esri/layers/FeatureLayer",
|
|
"esri/renderers/SimpleRenderer","esri/symbols/SimpleMarkerSymbol",
|
|
"esri/Color",
|
|
"esri/tasks/query",
|
|
"dojo/on","dojo/promise/all", "dojo/_base/Deferred",
|
|
"esri/graphic","esri/geometry/Extent", "esri/SpatialReference",
|
|
"//esri.github.io/bootstrap-map-js/src/js/bootstrapmap.js",
|
|
"../dist/offline-tiles-advanced-src.js",
|
|
"../dist/offline-edit-advanced-src.js",
|
|
"dojo/domReady!"],
|
|
function(Map,FeatureLayer,
|
|
SimpleRenderer,SimpleMarkerSymbol,Color,Query,
|
|
on,all,Deferred,Graphic,Extent,SpatialReference,BootstrapMap) {
|
|
|
|
var map = null;
|
|
var _isOnline = true;
|
|
var defaultSymbol, bStationSymbol;
|
|
|
|
// Variables for editing handling
|
|
var busStopFeatureLayer = null, offlineEdit = {};
|
|
var bicycleStationFeatureLayer = null;
|
|
var imgOfflineIndicator = document.getElementById("state-span");
|
|
var btnState = document.getElementById("btn-state");
|
|
|
|
// Variables for handling tiles
|
|
var tileLayer;
|
|
var _currentExtent = null;
|
|
var _wantToCancel;
|
|
var globalState = {};
|
|
var btnGetTiles = document.getElementById("btn-get-tiles");
|
|
var btnOnlineOffline = document.getElementById("btn-online-offline");
|
|
|
|
// Important settings for determining which tile layers gets stored for offline use.
|
|
var minZoomAdjust = -1, maxZoomAdjust = 1;
|
|
var EXTENT_BUFFER = 0; //buffers the map extent in meters
|
|
|
|
defaultSymbol= new SimpleMarkerSymbol().setStyle(
|
|
SimpleMarkerSymbol.STYLE_DIAMOND).setColor(
|
|
new Color([255,0,0,0.5])).setSize(20);
|
|
bStationSymbol= new SimpleMarkerSymbol().setStyle(
|
|
SimpleMarkerSymbol.STYLE_CIRCLE).setColor(
|
|
new Color([13,83,202,0.5])).setSize(20);
|
|
|
|
/**
|
|
* NOTE: This is the entry point into the application. The very first thing
|
|
* we need to do is check if the application is online or offline.
|
|
*
|
|
* There have been a few bugs in the offline detection library (offline.min.js)
|
|
* This is a utility check to 100% validate if the application is online or
|
|
* offline prior to launching any map functionality.
|
|
*/
|
|
validateOnline(function(result) {
|
|
if(result) {
|
|
_isOnline = true;
|
|
setUIOnline();
|
|
}
|
|
else {
|
|
_isOnline = false;
|
|
setUIOffline();
|
|
}
|
|
startMap();
|
|
});
|
|
|
|
/**
|
|
* We run this code both online and offline.
|
|
*/
|
|
function startMap() {
|
|
|
|
//
|
|
// Extend the feature layer with offline capabilities.
|
|
//
|
|
|
|
tileLayer = new O.esri.Tiles.OfflineTilesAdvanced("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer",function(evt){
|
|
console.log("Tile Layer initialized for offline. App state is: " + Offline.state);
|
|
},_isOnline);
|
|
|
|
// We don't need a proxy. All ArcGIS Online Service are CORS enabled.
|
|
tileLayer.offline.proxyPath = null;
|
|
|
|
// We are using Esri bootstrap-map-js to create a responsive mapping app
|
|
map = BootstrapMap.create("mapDiv",{
|
|
center: [-104.99,39.75], // long, lat
|
|
zoom: 17,
|
|
sliderStyle: "small"
|
|
});
|
|
|
|
map.on("load",function(evt) {
|
|
_currentExtent = evt.map.extent;
|
|
});
|
|
|
|
// Add our offline enabled tile layer to the map
|
|
map.addLayer(tileLayer);
|
|
|
|
if(!_isOnline){
|
|
loadFeatureLayerOffline(function(success) {
|
|
if(success) {
|
|
console.log("DONE!");
|
|
}
|
|
else {
|
|
alert("There was a problem initializing the map for offline.");
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
initializeFeaturesLayersOnline(function(){
|
|
console.log("online layers init!");
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
function initializeFeaturesLayersOnline(callback){
|
|
var promises = [];
|
|
var deferred1 = new Deferred();
|
|
var deferred2 = new Deferred();
|
|
|
|
var listener1, listener2;
|
|
|
|
/////////////////////////
|
|
// Our first layer
|
|
/////////////////////////
|
|
|
|
// Initialize our feature layer like we normally would
|
|
busStopFeatureLayer = new FeatureLayer("http://services1.arcgis.com/M8KJPUwAXP8jhtnM/arcgis/rest/services/Denver_Bus_Stops/FeatureServer/0", {
|
|
mode: FeatureLayer.MODE_SNAPSHOT,
|
|
outFields: ["GlobalID","BSID","ROUTES","STOPNAME"]
|
|
});
|
|
|
|
busStopFeatureLayer.setRenderer(new SimpleRenderer(defaultSymbol));
|
|
|
|
listener1 = busStopFeatureLayer.on("update-end",function(event){
|
|
listener1.remove();
|
|
if(!offlineEdit.hasOwnProperty("ONLINE")){
|
|
initOfflineEdits();
|
|
}
|
|
|
|
offlineEdit.extend(busStopFeatureLayer,function(result, error) {
|
|
if(result){
|
|
deferred1.resolve(true);
|
|
map.addLayer(bicycleStationFeatureLayer);
|
|
callback(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
/////////////////////////
|
|
// Our second layer
|
|
/////////////////////////
|
|
|
|
bicycleStationFeatureLayer = new FeatureLayer("http://services1.arcgis.com/M8KJPUwAXP8jhtnM/ArcGIS/rest/services/b_cycle_stations/FeatureServer/0", {
|
|
mode: FeatureLayer.MODE_SNAPSHOT,
|
|
outFields: ["GlobalID","STATION_NAME","STATION_ADDRESS","NUM_DOCKS"]
|
|
});
|
|
|
|
bicycleStationFeatureLayer.setRenderer(new SimpleRenderer(bStationSymbol));
|
|
|
|
listener2 = bicycleStationFeatureLayer.on("update-end",function(event){
|
|
listener2.remove();
|
|
if(!offlineEdit.hasOwnProperty("ONLINE")){
|
|
initOfflineEdits();
|
|
}
|
|
|
|
offlineEdit.extend(bicycleStationFeatureLayer,function(result, error) {
|
|
if(result){
|
|
deferred2.resolve(true);
|
|
}
|
|
});
|
|
});
|
|
|
|
promises.push(deferred1);
|
|
promises.push(deferred2);
|
|
map.addLayer(busStopFeatureLayer);
|
|
|
|
all(promises).then(function(result){
|
|
console.log("All results back!");
|
|
|
|
// This sets listeners to detect if the app goes online or offline.
|
|
Offline.on('up', goOnline);
|
|
Offline.on('down', goOffline);
|
|
|
|
if(_isOnline){
|
|
|
|
on(btnGetTiles,"click",downloadTiles);
|
|
on(btnOnlineOffline, 'click', goOnlineOffline);
|
|
|
|
// We don't have any stored edits
|
|
// This is just an example of what you would do if you had stored edits!
|
|
console.log("Application is online...attempting to send any stored edits.");
|
|
|
|
offlineEdit.goOnline(function(result){
|
|
if(!result.success){
|
|
alert("There was a problem when attempting to go back online.");
|
|
}
|
|
else {
|
|
console.log("OfflineEditAdvanced is online");
|
|
}
|
|
});
|
|
}
|
|
else {
|
|
offlineEdit.goOffline();
|
|
}
|
|
|
|
callback();
|
|
})
|
|
}
|
|
|
|
/**
|
|
* If we are offline then the attempt to add the feature layer will fail. The error
|
|
* will show up in the 'update-end' event.
|
|
* Having that error is okay because we want to explicitly control the order in which events happen.
|
|
* In production usage it would be a best practices to check any other errors and handle them appropriately.
|
|
*/
|
|
function initFeatureUpdateEndListener() {
|
|
|
|
//**************************************************
|
|
//
|
|
// This is where we detect an offline condition
|
|
// within the lifecycle of the "mapping" application.
|
|
// If we are offline then run our offline
|
|
// specific code for reconstituting our map.
|
|
//
|
|
//**************************************************
|
|
|
|
// If app is online then we ONLY need to extend the feature layer.
|
|
if(_isOnline){
|
|
initializeFeaturesLayersOnline();
|
|
}
|
|
// If the app is offline then we need to retrieve the dataStore from OfflineEditAdvanced
|
|
// and then extend the feature layer using that information.
|
|
else {
|
|
loadFeatureLayerOffline(function(success) {
|
|
if(success) {
|
|
initializeFeaturesLayersOnline();
|
|
}
|
|
else {
|
|
alert("There was a problem initializing the map for offline.");
|
|
}
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Load the feature while offline using information stored in database
|
|
*/
|
|
function loadFeatureLayerOffline(callback) {
|
|
|
|
initOfflineEdits();
|
|
|
|
var promises = [];
|
|
|
|
offlineEdit.getFeatureCollections(function(success,dataStore) {
|
|
if(success){
|
|
|
|
var deferred1 = new Deferred();
|
|
var deferred2 = new Deferred();
|
|
promises.push(deferred1);
|
|
promises.push(deferred2);
|
|
|
|
var _listener1, _listener2;
|
|
|
|
//////////////////////////////////////
|
|
// bus stops
|
|
//////////////////////////////////////
|
|
|
|
busStopFeatureLayer = new FeatureLayer(dataStore.featureCollections[0].featureLayerCollection);
|
|
|
|
if(busStopFeatureLayer.url == null){
|
|
busStopFeatureLayer.url = dataStore.featureCollections[0].featureLayerUrl;
|
|
}
|
|
|
|
// Set the graphic symbols to red diamond to make it easy to click on them
|
|
// on a mobile device.
|
|
busStopFeatureLayer.setRenderer(new SimpleRenderer(defaultSymbol));
|
|
|
|
busStopFeatureLayer.on("error",function(err){
|
|
console.log("ERROR " + err);
|
|
});
|
|
|
|
_listener1 = busStopFeatureLayer.on("update",function(evt){
|
|
_listener1.remove();
|
|
|
|
offlineEdit.extend(busStopFeatureLayer,function(success, error){
|
|
if(success){
|
|
console.log("busStopFeatureLayer successfully extended offline");
|
|
deferred1.resolve(true);
|
|
}
|
|
else {
|
|
console.log("busStopFeatureLayer Error attempting to extend it offline");
|
|
deferred1.reject(false);
|
|
}
|
|
});
|
|
});
|
|
|
|
map.addLayer(busStopFeatureLayer);
|
|
|
|
|
|
//////////////////////////////////////
|
|
// Bicycle stations
|
|
//////////////////////////////////////
|
|
|
|
bicycleStationFeatureLayer = new FeatureLayer(dataStore.featureCollections[1].featureLayerCollection);
|
|
|
|
if(bicycleStationFeatureLayer.url == null){
|
|
bicycleStationFeatureLayer.url = dataStore.featureCollections[1].featureLayerUrl;
|
|
}
|
|
|
|
// Set the graphic symbols to red diamond to make it easy to click on them
|
|
// on a mobile device.
|
|
bicycleStationFeatureLayer.setRenderer(new SimpleRenderer(bStationSymbol));
|
|
|
|
bicycleStationFeatureLayer.on("error",function(err){
|
|
console.log("ERROR " + err);
|
|
});
|
|
|
|
_listener2 = bicycleStationFeatureLayer.on("update",function(evt){
|
|
_listener2.remove();
|
|
|
|
offlineEdit.extend(bicycleStationFeatureLayer,function(success, error){
|
|
if(success){
|
|
console.log("bicycleStationFeatureLayer successfully extended offline");
|
|
deferred2.resolve(true);
|
|
}
|
|
else {
|
|
console.log("bicycleStationFeatureLayer Error attempting to extend it offline");
|
|
deferred2.reject(false);
|
|
}
|
|
});
|
|
});
|
|
|
|
map.addLayer(bicycleStationFeatureLayer);
|
|
|
|
all(promises).then(function(result){
|
|
|
|
console.log("Feature has been added back to the map while offline.");
|
|
on(btnGetTiles,"click",downloadTiles);
|
|
on(btnOnlineOffline, 'click', goOnlineOffline);
|
|
|
|
callback(true);
|
|
});
|
|
}
|
|
else{
|
|
alert("There was a problem retrieving feature layer options object. " + dataStore);
|
|
callback(false);
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* **********************************************
|
|
* FEATURE LAYER MANAGEMENT CODE
|
|
* **********************************************
|
|
*/
|
|
|
|
function initOfflineEdits() {
|
|
console.log("Initializing OfflineEditAdvanced");
|
|
offlineEdit = new O.esri.Edit.OfflineEditAdvanced();
|
|
|
|
// IMPORTANT!!!
|
|
// This tells the database which graphic.attribute property to use as a unique identifier
|
|
// You can look this information up in your feature service directory under the "Fields" category.
|
|
// Example: http://services1.arcgis.com/M8KJPUwAXP8jhtnM/arcgis/rest/services/Denver_Bus_Stops/FeatureServer/0
|
|
offlineEdit.DB_UID = "FID";
|
|
|
|
// We want the library to automatically create the offline featureCollection for each layer
|
|
offlineEdit.ENABLE_FEATURECOLLECTION = true;
|
|
|
|
// IMPORTANT!!!
|
|
// A proxy page may be required to upload attachments.
|
|
// If you are using a CORS enabled feature service you can ignore this.
|
|
// If your feature service is not CORS-enabled then you will need to configure this.
|
|
// Refer to "Using the Proxy Page" for more information: https://developers.arcgis.com/en/javascript/jshelp/ags_proxy.html
|
|
offlineEdit.proxyPath = null;
|
|
}
|
|
|
|
/**
|
|
* ************************************
|
|
* TILE MANAGEMENT CODE
|
|
* ************************************
|
|
*/
|
|
|
|
/**
|
|
* Manually starts the process to download and store tiles
|
|
* in the local database
|
|
*/
|
|
function downloadTiles() {
|
|
tileLayer.deleteAllTiles(function(success,err) {
|
|
if(!success) {
|
|
alert("There was a problem deleting the tile cache");
|
|
}
|
|
else {
|
|
console.log("success deleting tile cache");
|
|
|
|
if( globalState.downloadState == 'downloading')
|
|
{
|
|
console.log("cancel!");
|
|
_wantToCancel = true;
|
|
btnGetTiles.innerHTML = "cancelling..";
|
|
}
|
|
else
|
|
{
|
|
var zoom = tileLayer.getMinMaxLOD(minZoomAdjust,maxZoomAdjust);
|
|
|
|
var extent = tileLayer.getExtentBuffer(EXTENT_BUFFER,_currentExtent);
|
|
_wantToCancel = false;
|
|
tileLayer.prepareForOffline(zoom.min, zoom.max, extent, reportProgress.bind(this));
|
|
globalState.downloadState = 'downloading';
|
|
}
|
|
}
|
|
}.bind(this))
|
|
}
|
|
|
|
/**
|
|
* Reports the process while downloading tiles.
|
|
*/
|
|
function reportProgress(progress) {
|
|
console.log("downloading tiles...");
|
|
if(progress.hasOwnProperty("countNow")){
|
|
var percent = Math.floor(progress.countNow / progress.countMax * 100);
|
|
btnGetTiles.innerHTML = 'Saving to phone ' + percent + "% - Tap to Cancel";
|
|
}
|
|
|
|
if( progress.finishedDownloading ) {
|
|
btnGetTiles.innerHTML = "Saving to phone 100% - Tap to Cancel";
|
|
updateOfflineUsage();
|
|
// updateFeatureLayerJSON();
|
|
|
|
if( progress.cancelRequested ) {
|
|
globalState.downloadState = 'cancelled';
|
|
alert("Tile download was cancelled");
|
|
}
|
|
else {
|
|
globalState.downloadState = 'downloaded';
|
|
alert("Tile download complete");
|
|
}
|
|
|
|
btnGetTiles.innerHTML = '1. Download Tiles';
|
|
}
|
|
return _wantToCancel; //determines if a cancel request has been issued
|
|
}
|
|
|
|
/**
|
|
* ************************************
|
|
* HANDLE GOING ONLINE/OFFLINE
|
|
* ************************************
|
|
*/
|
|
|
|
/**
|
|
* Forces OfflineEditAdvanced to go online.
|
|
* When invoking featureLayer.goOnline() we force library to sync any edits that were
|
|
* stored while offline.
|
|
*/
|
|
function goOnline() {
|
|
console.log("Going online...");
|
|
updateOfflineUsage();
|
|
if(typeof tileLayer != "undefined") tileLayer.goOnline();
|
|
}
|
|
|
|
/**
|
|
* Forces OfflineEditAdvanced offline
|
|
*/
|
|
function goOffline() {
|
|
console.log("Going offline...");
|
|
setUIOffline();
|
|
if(typeof tileLayer != "undefined") tileLayer.goOffline();
|
|
}
|
|
|
|
/**
|
|
* Toggles OfflineEditAdvanced online/offline
|
|
*/
|
|
function goOnlineOffline() {
|
|
if(offlineEdit.getOnlineStatus() == offlineEdit.ONLINE){
|
|
goOffline();
|
|
}
|
|
else{
|
|
goOnline();
|
|
}
|
|
}
|
|
|
|
function setUIOnline() {
|
|
btnOnlineOffline.innerHTML = "2. Go Offline";
|
|
imgOfflineIndicator.className = "glyphicon glyphicon-link";
|
|
imgOfflineIndicator.innerHTML = " Up";
|
|
btnState.className = "btn btn-success btn-large floatRight";
|
|
}
|
|
|
|
function setUIOffline() {
|
|
btnOnlineOffline.innerHTML = "2. Go Online";
|
|
imgOfflineIndicator.className = "glyphicon glyphicon-thumbs-down";
|
|
imgOfflineIndicator.innerHTML = " Down";
|
|
btnState.className = "btn btn-danger btn-large floatRight";
|
|
}
|
|
|
|
/**
|
|
* For internal use - detecting amount of storage used and number of tiles stored.
|
|
*/
|
|
function updateOfflineUsage() {
|
|
tileLayer.offline.store.usedSpace(function(result,err){
|
|
if(result != null) {
|
|
console.log( "DB Tile count: " + result.tileCount + ", DB Bytes: " + result.sizeBytes);
|
|
}
|
|
else {
|
|
console.log("DB Tile count: " + count + ", DB Bytes: Error");
|
|
}
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Attempts a manual http request to verify if app is online or offline.
|
|
* Use this in conjunction with the offline checker library: offline.min.js
|
|
* @param callback
|
|
*/
|
|
function validateOnline(callback) {
|
|
var req = new XMLHttpRequest();
|
|
req.open("GET", "http://esri.github.io/offline-editor-js/samples/images/blue-pin.png?" + (Math.floor(Math.random() * 1000000000)), true);
|
|
req.onload = function() {
|
|
if( req.status === 200 && req.responseText !== "") {
|
|
req = null;
|
|
callback(true);
|
|
}
|
|
else {
|
|
console.log("verifyOffline failed");
|
|
req = null;
|
|
callback(false);
|
|
}
|
|
};
|
|
req.onerror = function(e) {
|
|
console.log("appcache-features.html verifyOnline failed: " + e);
|
|
callback(false);
|
|
};
|
|
req.send(null);
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<!-- Bootstrap core JavaScript
|
|
================================================== -->
|
|
<!-- Placed at the end of the document so the pages load faster -->
|
|
<script src="//code.jquery.com/jquery-2.1.3.min.js"></script>
|
|
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
|
|
</body>
|
|
</html> |