mirror of
https://github.com/Esri/offline-editor-js.git
synced 2025-12-15 15:20:05 +00:00
Added callback to applyEdits() and custom event to indicate success/failure of updates, adds, deletes
This commit is contained in:
parent
ab7c164c01
commit
e29b520ea8
41
index.html
41
index.html
@ -16,14 +16,14 @@
|
||||
padding: 0;
|
||||
overflow:hidden;
|
||||
}
|
||||
#header {
|
||||
#header, #info {
|
||||
border:solid 2px #462d44;
|
||||
background:#fff;
|
||||
color:#444;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
font-family: sans-serif;
|
||||
font-size: 1.1em
|
||||
font-size: 1.1em;
|
||||
padding-left:20px;
|
||||
}
|
||||
#map {
|
||||
@ -98,6 +98,8 @@
|
||||
|
||||
map.on("layers-add-result", initEditing);
|
||||
|
||||
var headerDiv = document.getElementById("info");
|
||||
|
||||
var landusePointLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/6", {
|
||||
mode: FeatureLayer.MODE_SNAPSHOT,
|
||||
outFields: ["*"]
|
||||
@ -127,17 +129,39 @@
|
||||
//////////
|
||||
offlineStore = new OfflineStore(map);
|
||||
console.log("Storage used : " + offlineStore.getlocalStorageUsed());
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
try{
|
||||
document.addEventListener("editEvent",function(evt){
|
||||
if(evt.type == "editEvent" && evt.detail.message == true){
|
||||
console.log("editEvent: All edits successfully pushed");
|
||||
}
|
||||
else if(evt.type == "editEvent" && evt.detail.message == false){
|
||||
alert("Not all edits were successfully pushed to the server");
|
||||
}
|
||||
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
},
|
||||
false);
|
||||
}
|
||||
catch(err){
|
||||
console.log("test that event object is valid: " + err);
|
||||
}
|
||||
|
||||
//////////
|
||||
|
||||
var editToolbar = new Edit(map);
|
||||
|
||||
editToolbar.on("deactivate", function(evt) {
|
||||
if(updateFlag == true){
|
||||
offlineStore.applyEdits(vertices.graphic,vertices.layer,offlineStore.enum().UPDATE);
|
||||
offlineStore.applyEdits(vertices.graphic,vertices.layer,offlineStore.enum().UPDATE,function(count,success,id){
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
});
|
||||
updateFlag = false;
|
||||
}
|
||||
else{
|
||||
offlineStore.applyEdits(evt.graphic,currentLayer,offlineStore.enum().UPDATE);
|
||||
offlineStore.applyEdits(evt.graphic,currentLayer,offlineStore.enum().UPDATE,function(count,success,id){
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -168,7 +192,9 @@
|
||||
event.stop(evt);
|
||||
if (evt.ctrlKey === true || evt.metaKey === true) { //delete feature if ctrl key is depressed
|
||||
try{
|
||||
offlineStore.applyEdits(evt.graphic,layer,offlineStore.enum().DELETE);
|
||||
offlineStore.applyEdits(evt.graphic,layer,offlineStore.enum().DELETE,function(count,success,id){
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
});
|
||||
}
|
||||
catch(err){
|
||||
console.log("error " + err.stack);
|
||||
@ -218,7 +244,9 @@
|
||||
var newAttributes = lang.mixin({}, selectedTemplate.template.prototype.attributes);
|
||||
var newGraphic = new Graphic(evt.geometry, null, newAttributes);
|
||||
//selectedTemplate.featureLayer.applyEdits([newGraphic], null, null);
|
||||
offlineStore.applyEdits(newGraphic,selectedTemplate.featureLayer,offlineStore.enum().ADD);
|
||||
offlineStore.applyEdits(newGraphic,selectedTemplate.featureLayer,offlineStore.enum().ADD,function(count,success,id){
|
||||
headerDiv.innerHTML = "Storage Used: " + offlineStore.getlocalStorageUsed() + " MBs";
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@ -253,6 +281,7 @@
|
||||
<body class="claro">
|
||||
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:true, design:'headline'" style="width:100%;height:100%;">
|
||||
<div data-dojo-type="dijit/layout/ContentPane" id="header" data-dojo-props="region:'top'">Use ctrl or cmd + click on graphic to delete. Double click on graphic to edit vertices. </div>
|
||||
<div id="info" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">Storage used: 0 MBs</div>
|
||||
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'"></div>
|
||||
<div id="rightPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
|
||||
<div id="templatePickerDiv"></div>
|
||||
|
||||
@ -55,14 +55,24 @@ var OfflineStore = function(/* Map */ map) {
|
||||
*/
|
||||
this._localEnum = (function(){
|
||||
var values = {
|
||||
VALIDATION_URL : "http://localhost/offline/test.html", /* Change this to a remote server for testing! */
|
||||
TIMER_URL : "./src/Timer.js", /* For use within a child process only */
|
||||
STORAGE_KEY : "___EsriOfflineStore___", /* Unique key for setting/retrieving values from localStorage */
|
||||
INDEX_KEY : "___EsriOfflineIndex___", /* Index for tracking each action (add, delete, update) in local store */
|
||||
VALIDATION_TIMEOUT : 10 * 1000, /* HTTP timeout when trying to validate internet on/off */
|
||||
LOCAL_STORAGE_MAX_LIMIT : 4.75 /* MB */, /* Most browsers offer default storage of ~5MB */
|
||||
TOKEN : "|||", /* A unique token for tokenizing stringified localStorage values */
|
||||
/* Change this to a remote server for testing! */
|
||||
VALIDATION_URL : "http://localhost/offline/test.html",
|
||||
/* For use within a child process only */
|
||||
TIMER_URL : "./src/Timer.js",
|
||||
/* Unique key for setting/retrieving values from localStorage */
|
||||
STORAGE_KEY : "___EsriOfflineStore___",
|
||||
/* Index for tracking each action (add, delete, update) in local store */
|
||||
INDEX_KEY : "___EsriOfflineIndex___",
|
||||
/* HTTP timeout when trying to validate internet on/off */
|
||||
VALIDATION_TIMEOUT : 10 * 1000,
|
||||
/* Most browsers offer default storage of ~5MB */
|
||||
LOCAL_STORAGE_MAX_LIMIT : 4.75 /* MB */,
|
||||
/* A unique token for tokenizing stringified localStorage values */
|
||||
TOKEN : "|||",
|
||||
TIMER_TICK_INTERVAL : 10 * 1000 /* ms */,
|
||||
EDIT_EVENT: "editEvent",
|
||||
EDIT_EVENT_SUCCESS: true,
|
||||
EDIT_EVENT_FAILED: false,
|
||||
REQUIRED_LIBS : [
|
||||
"./src/Hydrate.js",
|
||||
"./src/Poller.js"
|
||||
@ -102,10 +112,12 @@ var OfflineStore = function(/* Map */ map) {
|
||||
* @param graphic Required
|
||||
* @param layer Required
|
||||
* @param enumValue Required
|
||||
* @param callback Recommended. Returns true if offline condition detected otherwise returns false.
|
||||
*/
|
||||
this.applyEdits = function(/* Graphic */ graphic,/* FeatureLayer */ layer, /* String */ enumValue){
|
||||
this.applyEdits = function(/* Graphic */ graphic,/* FeatureLayer */ layer, /* String */ enumValue, callback){
|
||||
var internet = this._checkInternet();
|
||||
this._applyEdits(internet,graphic,layer,enumValue);
|
||||
this._applyEdits(internet,graphic,layer,enumValue, callback);
|
||||
//this._sendEvent("Halllooo","test");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,6 +157,8 @@ var OfflineStore = function(/* Map */ map) {
|
||||
|
||||
/**
|
||||
* Determines total storage used for this domain.
|
||||
* NOTE: The index does take up storage space. Even if the offlineStore
|
||||
* is deleted, you will still see some space taken up by the index.
|
||||
* @returns Number MB's
|
||||
*/
|
||||
this.getlocalStorageUsed = function(){
|
||||
@ -152,20 +166,32 @@ var OfflineStore = function(/* Map */ map) {
|
||||
//IE hack
|
||||
if(window.localStorage.hasOwnProperty("remainingspace")){
|
||||
//http://msdn.microsoft.com/en-us/library/ie/cc197016(v=vs.85).aspx
|
||||
return window.localStorage.remainingSpace/1024/1024;
|
||||
return (window.localStorage.remainingSpace/1024/1024).round(4);
|
||||
}
|
||||
else{
|
||||
var mb = 0;
|
||||
for(var x in localStorage){
|
||||
//Uncomment out console.log to see *all* items in local storage
|
||||
console.log(x+"="+((localStorage[x].length * 2)/1024/1024)+" MB");
|
||||
//console.log(x+"="+((localStorage[x].length * 2)/1024/1024).toFixed(4)+" MB");
|
||||
mb += localStorage[x].length
|
||||
}
|
||||
|
||||
return Math.round(((mb * 2)/1024/1024) * 100)/100;
|
||||
//return Math.round(((mb * 2)/1024/1024) * 100)/100;
|
||||
return ((mb *2)/1024/1024).round(4);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Global prototype that provides rounding capabilities.
|
||||
* TODO reevaluate if this should be local in scope or global.
|
||||
* @param places
|
||||
* @returns {number}
|
||||
*/
|
||||
Number.prototype.round = function(places){
|
||||
places = Math.pow(10, places);
|
||||
return Math.round(this * places)/places;
|
||||
}
|
||||
|
||||
//////////////////////////
|
||||
///
|
||||
/// PRIVATE methods
|
||||
@ -180,20 +206,23 @@ var OfflineStore = function(/* Map */ map) {
|
||||
* @param graphic
|
||||
* @param layer
|
||||
* @param enumValue
|
||||
* @param callback Returns true if offline condition detected otherwise returns false.
|
||||
* Format: {count, success, id}
|
||||
* @private
|
||||
*/
|
||||
this._applyEdits = function(/* Boolean */ internet, /* Graphic */ graphic,/* FeatureLayer */ layer, /* String */ enumValue){
|
||||
this._applyEdits = function(/* Boolean */ internet, /* Graphic */ graphic,/* FeatureLayer */ layer, /* String */ enumValue, callback){
|
||||
//TODO Need to add code to determine size of incoming graphic
|
||||
var mb = this.getlocalStorageUsed();
|
||||
console.log("getlocalStorageUsed = " + mb + " MBs");
|
||||
|
||||
if(mb > this._localEnum().LOCAL_STORAGE_MAX_LIMIT /* MB */){
|
||||
alert("You are almost over the local storage limit. No more data can be added.")
|
||||
callback(0,false,0);
|
||||
return;
|
||||
}
|
||||
|
||||
if(internet === false){
|
||||
this._addToLocalStore(graphic,layer,enumValue);
|
||||
this._addToLocalStore(graphic,layer,enumValue,callback);
|
||||
if(this.isTimer == null){
|
||||
this._startTimer(function(err){
|
||||
throw ("unable to start background timer. Offline edits won't work. " + err.stack);
|
||||
@ -202,11 +231,12 @@ var OfflineStore = function(/* Map */ map) {
|
||||
}
|
||||
else if(internet == null || typeof internet == "undefined"){
|
||||
console.log("applyEdits: possible error.");
|
||||
callback(0,false,0);
|
||||
}
|
||||
else{
|
||||
//No need for a callback because this is an online request and it's immediately
|
||||
//pushed to Feature Service. The only thing updated in the library is the Index.
|
||||
this._layerEditManager(graphic,layer,enumValue,this.enum(),null,null);
|
||||
this._layerEditManager(graphic,layer,enumValue,this.enum(),0,callback);
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,17 +335,20 @@ console.log(localStore.toString());
|
||||
}
|
||||
}
|
||||
|
||||
this._addToLocalStore = function(/* Graphic */ graphic, /* FeatureLayer */ layer, /* String */ enumValue){
|
||||
this._addToLocalStore = function(/* Graphic */ graphic, /* FeatureLayer */ layer, /* String */ enumValue,callback){
|
||||
var arr = this._getLocalStorage();
|
||||
var geom = this._serializeGraphic(graphic,layer,enumValue);
|
||||
|
||||
var setItem = null;
|
||||
|
||||
//If localStorage does NOT exist
|
||||
if(arr === null){
|
||||
|
||||
this._setItemInLocalStore(geom);
|
||||
setItem = this._setItemInLocalStore(geom);
|
||||
callback(0,setItem,0);
|
||||
}
|
||||
else{
|
||||
this._updateExistingLocalStore(geom);
|
||||
setItem = this._updateExistingLocalStore(geom);
|
||||
callback(0,setItem,0);
|
||||
}
|
||||
|
||||
layer.add(graphic);
|
||||
@ -365,6 +398,10 @@ console.log(localStore.toString());
|
||||
if(evt == true){
|
||||
this._stopTimer();
|
||||
this._deleteStore();
|
||||
this._sendEvent(true,this._localEnum().EDIT_EVENT);
|
||||
}
|
||||
else{
|
||||
this._sendEvent(false,this._localEnum().EDIT_EVENT);
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
@ -395,6 +432,23 @@ console.log(localStore.toString());
|
||||
}
|
||||
}
|
||||
|
||||
this._sendEvent = function(msg,event){
|
||||
//this.preventDefault();
|
||||
|
||||
if (msg && window.CustomEvent) {
|
||||
var event = new CustomEvent(event, {
|
||||
detail: {
|
||||
message: msg,
|
||||
time: new Date()
|
||||
},
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
|
||||
document.dispatchEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
this._handleRestablishedInternet = function(callback){
|
||||
var graphicsArr = this.getStore();
|
||||
|
||||
@ -418,6 +472,7 @@ console.log(localStore.toString());
|
||||
else{
|
||||
console.log("_handleRestablishedInternet: there were errors. LocalStore still available.");
|
||||
this._stopTimer();
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
else if(success == true && check.length < graphicsArr.length){
|
||||
@ -427,6 +482,7 @@ console.log(localStore.toString());
|
||||
this._setItemLocalStoreIndex(obj1.layer,objectId,obj1.enumValue,false);
|
||||
console.log("_handleRestablishedInternet: error sending edit on " + objectId);
|
||||
this._stopTimer();
|
||||
callback(false);
|
||||
}
|
||||
else if(success == false && check.length < graphicsArr.length){
|
||||
this._setItemLocalStoreIndex(obj1.layer,objectId,obj1.enumValue,false);
|
||||
@ -761,6 +817,10 @@ console.log(localStore.toString());
|
||||
if(evt == true){
|
||||
this._stopTimer();
|
||||
this._deleteStore();
|
||||
this._sendEvent(true,this._localEnum().EDIT_EVENT);
|
||||
}
|
||||
else{
|
||||
this._sendEvent(false,this._localEnum().EDIT_EVENT);
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user